blob: 3c706a14abee28d1a0b82d7e9e80501ea66533d7 [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"
Hungming Chenc6556622019-10-02 16:01:07 +080068#include "tests/dns_responder/dns_tls_certificate.h"
chenbruceb43ec752019-07-24 20:19:41 +080069#include "tests/dns_responder/dns_tls_frontend.h"
Luke Huangfde82482019-06-04 01:04:53 +080070#include "tests/resolv_test_utils.h"
Ken Chenb9fa2062018-11-13 21:51:13 +080071
Luke Huang0d592bc2019-05-25 18:24:03 +080072// Valid VPN netId range is 100 ~ 65535
73constexpr int TEST_VPN_NETID = 65502;
Luke Huang94b10b92018-11-21 20:13:38 +080074constexpr int MAXPACKET = (8 * 1024);
Ken Chenb9fa2062018-11-13 21:51:13 +080075
Sehee Park2c118782019-05-07 13:02:45 +090076// Use maximum reserved appId for applications to avoid conflict with existing uids.
77static const int TEST_UID = 99999;
78
Ken Chenb9fa2062018-11-13 21:51:13 +080079// Semi-public Bionic hook used by the NDK (frameworks/base/native/android/net.c)
80// Tested here for convenience.
81extern "C" int android_getaddrinfofornet(const char* hostname, const char* servname,
82 const addrinfo* hints, unsigned netid, unsigned mark,
83 struct addrinfo** result);
84
Luke Huang70070852019-11-25 18:25:50 +080085using aidl::android::net::IDnsResolver;
Luke Huangf8215372019-11-22 11:53:41 +080086using aidl::android::net::INetd;
Luke Huang9807e6b2019-05-20 16:17:12 +080087using android::base::ParseInt;
Ken Chenb9fa2062018-11-13 21:51:13 +080088using android::base::StringPrintf;
Luke Huang9807e6b2019-05-20 16:17:12 +080089using android::base::unique_fd;
Ken Chenb9fa2062018-11-13 21:51:13 +080090using android::net::ResolverStats;
Hungming Chene8f970c2019-04-10 17:34:06 +080091using android::net::metrics::DnsMetricsListener;
Ken Chenb9fa2062018-11-13 21:51:13 +080092using android::netdutils::enableSockopt;
Hungming Chen63779052019-10-30 15:06:13 +080093using android::netdutils::makeSlice;
Luke Huang9807e6b2019-05-20 16:17:12 +080094using android::netdutils::ResponseCode;
Luke Huang9d2d25b2019-06-14 00:34:05 +080095using android::netdutils::ScopedAddrinfo;
Mike Yu40e67072019-10-09 21:14:09 +080096using android::netdutils::Stopwatch;
Hungming Chen63779052019-10-30 15:06:13 +080097using android::netdutils::toHex;
Ken Chenb9fa2062018-11-13 21:51:13 +080098
99// TODO: move into libnetdutils?
100namespace {
Luke Huangfde82482019-06-04 01:04:53 +0800101
Ken Chenb9fa2062018-11-13 21:51:13 +0800102ScopedAddrinfo safe_getaddrinfo(const char* node, const char* service,
103 const struct addrinfo* hints) {
104 addrinfo* result = nullptr;
105 if (getaddrinfo(node, service, hints, &result) != 0) {
106 result = nullptr; // Should already be the case, but...
107 }
108 return ScopedAddrinfo(result);
109}
Luke Huangfde82482019-06-04 01:04:53 +0800110
Mike Yu40e67072019-10-09 21:14:09 +0800111std::pair<ScopedAddrinfo, int> safe_getaddrinfo_time_taken(const char* node, const char* service,
112 const addrinfo& hints) {
113 Stopwatch s;
114 ScopedAddrinfo result = safe_getaddrinfo(node, service, &hints);
115 return {std::move(result), s.timeTakenUs() / 1000};
116}
117
Ken Chenb9fa2062018-11-13 21:51:13 +0800118} // namespace
119
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900120class ResolverTest : public ::testing::Test {
Hungming Chene8f970c2019-04-10 17:34:06 +0800121 public:
Hungming Chen5bf09772019-04-25 11:16:13 +0800122 static void SetUpTestCase() {
123 // Get binder service.
124 // Note that |mDnsClient| is not used for getting binder service in this static function.
125 // The reason is that wants to keep |mDnsClient| as a non-static data member. |mDnsClient|
126 // which sets up device network configuration could be independent from every test.
Luke Huangf8215372019-11-22 11:53:41 +0800127 // TODO: Perhaps add a static function in resolv_test_binder_utils.{cpp,h} to get binder
128 // service.
129
130 AIBinder* binder = AServiceManager_getService("dnsresolver");
131 ndk::SpAIBinder resolvBinder = ndk::SpAIBinder(binder);
132 auto resolvService = aidl::android::net::IDnsResolver::fromBinder(resolvBinder);
Hungming Chen5bf09772019-04-25 11:16:13 +0800133 ASSERT_NE(nullptr, resolvService.get());
134
135 // Subscribe the death recipient to the service IDnsResolver for detecting Netd death.
Luke Huang70070852019-11-25 18:25:50 +0800136 // GTEST assertion macros are not invoked for generating a test failure in the death
137 // recipient because the macros can't indicate failed test if Netd died between tests.
138 // Moreover, continuing testing may have no meaningful after Netd death. Therefore, the
139 // death recipient aborts process by GTEST_LOG_(FATAL) once Netd died.
Luke Huangf8215372019-11-22 11:53:41 +0800140 sResolvDeathRecipient = AIBinder_DeathRecipient_new([](void*) {
141 constexpr char errorMessage[] = "Netd died";
142 LOG(ERROR) << errorMessage;
143 GTEST_LOG_(FATAL) << errorMessage;
144 });
145 ASSERT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, sResolvDeathRecipient, nullptr));
Hungming Chen5bf09772019-04-25 11:16:13 +0800146
147 // Subscribe the DNS listener for verifying DNS metrics event contents.
Luke Huangf8215372019-11-22 11:53:41 +0800148 sDnsMetricsListener = ndk::SharedRefBase::make<DnsMetricsListener>(
149 TEST_NETID /*monitor specific network*/);
Hungming Chen5bf09772019-04-25 11:16:13 +0800150 ASSERT_TRUE(resolvService->registerEventListener(sDnsMetricsListener).isOk());
151
152 // Start the binder thread pool for listening DNS metrics events and receiving death
153 // recipient.
Luke Huangf8215372019-11-22 11:53:41 +0800154 ABinderProcess_startThreadPool();
Hungming Chene8f970c2019-04-10 17:34:06 +0800155 }
Luke Huangf8215372019-11-22 11:53:41 +0800156 static void TearDownTestCase() { AIBinder_DeathRecipient_delete(sResolvDeathRecipient); }
Hungming Chene8f970c2019-04-10 17:34:06 +0800157
Ken Chenb9fa2062018-11-13 21:51:13 +0800158 protected:
Xiao Ma09b71022018-12-11 17:56:32 +0900159 struct DnsRecord {
160 std::string host_name; // host name
161 ns_type type; // record type
162 std::string addr; // ipv4/v6 address
163 };
164
Hungming Chen5bf09772019-04-25 11:16:13 +0800165 void SetUp() { mDnsClient.SetUp(); }
Hungming Chene8f970c2019-04-10 17:34:06 +0800166 void TearDown() { mDnsClient.TearDown(); }
nuccachena26cc2a2018-07-17 18:07:23 +0800167
Xiao Ma09b71022018-12-11 17:56:32 +0900168 void StartDns(test::DNSResponder& dns, const std::vector<DnsRecord>& records) {
169 for (const auto& r : records) {
170 dns.addMapping(r.host_name, r.type, r.addr);
171 }
172
173 ASSERT_TRUE(dns.startServer());
174 dns.clearQueries();
175 }
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900176
Hungming Chene8f970c2019-04-10 17:34:06 +0800177 bool WaitForNat64Prefix(ExpectNat64PrefixStatus status,
178 std::chrono::milliseconds timeout = std::chrono::milliseconds(1000)) {
Hungming Chen5bf09772019-04-25 11:16:13 +0800179 return sDnsMetricsListener->waitForNat64Prefix(status, timeout);
Hungming Chene8f970c2019-04-10 17:34:06 +0800180 }
181
Mike Yu724f77d2019-08-16 11:14:50 +0800182 bool WaitForPrivateDnsValidation(std::string serverAddr, bool validated) {
183 return sDnsMetricsListener->waitForPrivateDnsValidation(serverAddr, validated);
184 }
185
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900186 DnsResponderClient mDnsClient;
Xiao Ma09b71022018-12-11 17:56:32 +0900187
Hungming Chen5bf09772019-04-25 11:16:13 +0800188 // Use a shared static DNS listener for all tests to avoid registering lots of listeners
189 // which may be released late until process terminated. Currently, registered DNS listener
190 // is removed by binder death notification which is fired when the process hosting an
191 // IBinder has gone away. If every test in ResolverTest registers its DNS listener, Netd
192 // may temporarily hold lots of dead listeners until the unit test process terminates.
193 // TODO: Perhaps add an unregistering listener binder call or fork a listener process which
194 // could be terminated earlier.
Luke Huangf8215372019-11-22 11:53:41 +0800195 static std::shared_ptr<DnsMetricsListener>
196 sDnsMetricsListener; // Initialized in SetUpTestCase.
Hungming Chen5bf09772019-04-25 11:16:13 +0800197
198 // Use a shared static death recipient to monitor the service death. The static death
199 // recipient could monitor the death not only during the test but also between tests.
Luke Huangf8215372019-11-22 11:53:41 +0800200 static AIBinder_DeathRecipient* sResolvDeathRecipient; // Initialized in SetUpTestCase.
Ken Chenb9fa2062018-11-13 21:51:13 +0800201};
202
Hungming Chen5bf09772019-04-25 11:16:13 +0800203// Initialize static member of class.
Luke Huangf8215372019-11-22 11:53:41 +0800204std::shared_ptr<DnsMetricsListener> ResolverTest::sDnsMetricsListener;
205AIBinder_DeathRecipient* ResolverTest::sResolvDeathRecipient;
Hungming Chen5bf09772019-04-25 11:16:13 +0800206
Ken Chenb9fa2062018-11-13 21:51:13 +0800207TEST_F(ResolverTest, GetHostByName) {
Xiao Ma09b71022018-12-11 17:56:32 +0900208 constexpr char nonexistent_host_name[] = "nonexistent.example.com.";
209
210 test::DNSResponder dns;
211 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.3"}});
212 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800213
214 const hostent* result;
Ken Chenb9fa2062018-11-13 21:51:13 +0800215 result = gethostbyname("nonexistent");
216 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, nonexistent_host_name));
217 ASSERT_TRUE(result == nullptr);
218 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
219
220 dns.clearQueries();
221 result = gethostbyname("hello");
Xiao Ma09b71022018-12-11 17:56:32 +0900222 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
Ken Chenb9fa2062018-11-13 21:51:13 +0800223 ASSERT_FALSE(result == nullptr);
224 ASSERT_EQ(4, result->h_length);
225 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
226 EXPECT_EQ("1.2.3.3", ToString(result));
227 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800228}
229
lifr4e4a2e02019-01-29 16:53:51 +0800230TEST_F(ResolverTest, GetHostByName_cnames) {
231 constexpr char host_name[] = "host.example.com.";
232 size_t cnamecount = 0;
233 test::DNSResponder dns;
234
235 const std::vector<DnsRecord> records = {
236 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
237 {"a.example.com.", ns_type::ns_t_cname, "b.example.com."},
238 {"b.example.com.", ns_type::ns_t_cname, "c.example.com."},
239 {"c.example.com.", ns_type::ns_t_cname, "d.example.com."},
240 {"d.example.com.", ns_type::ns_t_cname, "e.example.com."},
241 {"e.example.com.", ns_type::ns_t_cname, host_name},
242 {host_name, ns_type::ns_t_a, "1.2.3.3"},
243 {host_name, ns_type::ns_t_aaaa, "2001:db8::42"},
244 };
245 StartDns(dns, records);
246 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
247
248 // using gethostbyname2() to resolve ipv4 hello.example.com. to 1.2.3.3
249 // Ensure the v4 address and cnames are correct
250 const hostent* result;
251 result = gethostbyname2("hello", AF_INET);
252 ASSERT_FALSE(result == nullptr);
253
254 for (int i = 0; result != nullptr && result->h_aliases[i] != nullptr; i++) {
255 std::string domain_name = records[i].host_name.substr(0, records[i].host_name.size() - 1);
256 EXPECT_EQ(result->h_aliases[i], domain_name);
257 cnamecount++;
258 }
259 // The size of "Non-cname type" record in DNS records is 2
260 ASSERT_EQ(cnamecount, records.size() - 2);
261 ASSERT_EQ(4, result->h_length);
262 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
263 EXPECT_EQ("1.2.3.3", ToString(result));
264 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
265 EXPECT_EQ(1U, dns.queries().size()) << dns.dumpQueries();
266
267 // using gethostbyname2() to resolve ipv6 hello.example.com. to 2001:db8::42
268 // Ensure the v6 address and cnames are correct
269 cnamecount = 0;
270 dns.clearQueries();
271 result = gethostbyname2("hello", AF_INET6);
272 for (unsigned i = 0; result != nullptr && result->h_aliases[i] != nullptr; i++) {
273 std::string domain_name = records[i].host_name.substr(0, records[i].host_name.size() - 1);
274 EXPECT_EQ(result->h_aliases[i], domain_name);
275 cnamecount++;
276 }
277 // The size of "Non-cname type" DNS record in records is 2
278 ASSERT_EQ(cnamecount, records.size() - 2);
279 ASSERT_FALSE(result == nullptr);
280 ASSERT_EQ(16, result->h_length);
281 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
282 EXPECT_EQ("2001:db8::42", ToString(result));
283 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
284}
285
286TEST_F(ResolverTest, GetHostByName_cnamesInfiniteLoop) {
287 test::DNSResponder dns;
288 const std::vector<DnsRecord> records = {
289 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
290 {"a.example.com.", ns_type::ns_t_cname, kHelloExampleCom},
291 };
292 StartDns(dns, records);
293 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
294
295 const hostent* result;
296 result = gethostbyname2("hello", AF_INET);
297 ASSERT_TRUE(result == nullptr);
298
299 dns.clearQueries();
300 result = gethostbyname2("hello", AF_INET6);
301 ASSERT_TRUE(result == nullptr);
302}
303
Ken Chenb9fa2062018-11-13 21:51:13 +0800304TEST_F(ResolverTest, GetHostByName_localhost) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800305 constexpr char name_camelcase[] = "LocalHost";
Ken Chenb9fa2062018-11-13 21:51:13 +0800306 constexpr char name_ip6_dot[] = "ip6-localhost.";
307 constexpr char name_ip6_fqdn[] = "ip6-localhost.example.com.";
308
309 // Add a dummy nameserver which shouldn't receive any queries
Xiao Ma09b71022018-12-11 17:56:32 +0900310 test::DNSResponder dns;
311 StartDns(dns, {});
312 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800313
314 // Expect no DNS queries; localhost is resolved via /etc/hosts
Xiao Ma09b71022018-12-11 17:56:32 +0900315 const hostent* result = gethostbyname(kLocalHost);
Ken Chenb9fa2062018-11-13 21:51:13 +0800316 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
317 ASSERT_FALSE(result == nullptr);
318 ASSERT_EQ(4, result->h_length);
319 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900320 EXPECT_EQ(kLocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800321 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
322
323 // Ensure the hosts file resolver ignores case of hostnames
324 result = gethostbyname(name_camelcase);
325 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
326 ASSERT_FALSE(result == nullptr);
327 ASSERT_EQ(4, result->h_length);
328 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900329 EXPECT_EQ(kLocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800330 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
331
332 // The hosts file also contains ip6-localhost, but gethostbyname() won't
chenbruce018fdb22019-06-12 18:08:04 +0800333 // return it. This would be easy to
Ken Chenb9fa2062018-11-13 21:51:13 +0800334 // change, but there's no point in changing the legacy behavior; new code
335 // should be calling getaddrinfo() anyway.
336 // So we check the legacy behavior, which results in amusing A-record
337 // lookups for ip6-localhost, with and without search domains appended.
338 dns.clearQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900339 result = gethostbyname(kIp6LocalHost);
Sehee Parkbbca0202018-11-16 10:53:16 +0900340 EXPECT_EQ(2U, dns.queries().size()) << dns.dumpQueries();
341 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, name_ip6_dot)) << dns.dumpQueries();
342 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, name_ip6_fqdn)) << dns.dumpQueries();
Ken Chenb9fa2062018-11-13 21:51:13 +0800343 ASSERT_TRUE(result == nullptr);
344
345 // Finally, use gethostbyname2() to resolve ip6-localhost to ::1 from
346 // the hosts file.
347 dns.clearQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900348 result = gethostbyname2(kIp6LocalHost, AF_INET6);
Ken Chenb9fa2062018-11-13 21:51:13 +0800349 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
350 ASSERT_FALSE(result == nullptr);
351 ASSERT_EQ(16, result->h_length);
352 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900353 EXPECT_EQ(kIp6LocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800354 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800355}
356
357TEST_F(ResolverTest, GetHostByName_numeric) {
358 // Add a dummy nameserver which shouldn't receive any queries
Xiao Ma09b71022018-12-11 17:56:32 +0900359 test::DNSResponder dns;
360 StartDns(dns, {});
361 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800362
363 // Numeric v4 address: expect no DNS queries
364 constexpr char numeric_v4[] = "192.168.0.1";
Ken Chenb9fa2062018-11-13 21:51:13 +0800365 const hostent* result = gethostbyname(numeric_v4);
Sehee Parkbbca0202018-11-16 10:53:16 +0900366 EXPECT_EQ(0U, dns.queries().size());
Ken Chenb9fa2062018-11-13 21:51:13 +0800367 ASSERT_FALSE(result == nullptr);
368 ASSERT_EQ(4, result->h_length); // v4
369 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
370 EXPECT_EQ(numeric_v4, ToString(result));
371 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
372
373 // gethostbyname() recognizes a v6 address, and fails with no DNS queries
374 constexpr char numeric_v6[] = "2001:db8::42";
375 dns.clearQueries();
376 result = gethostbyname(numeric_v6);
Sehee Parkbbca0202018-11-16 10:53:16 +0900377 EXPECT_EQ(0U, dns.queries().size());
Ken Chenb9fa2062018-11-13 21:51:13 +0800378 EXPECT_TRUE(result == nullptr);
379
380 // Numeric v6 address with gethostbyname2(): succeeds with no DNS queries
381 dns.clearQueries();
382 result = gethostbyname2(numeric_v6, AF_INET6);
Sehee Parkbbca0202018-11-16 10:53:16 +0900383 EXPECT_EQ(0U, dns.queries().size());
Ken Chenb9fa2062018-11-13 21:51:13 +0800384 ASSERT_FALSE(result == nullptr);
385 ASSERT_EQ(16, result->h_length); // v6
386 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
387 EXPECT_EQ(numeric_v6, ToString(result));
388 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
389
390 // Numeric v6 address with scope work with getaddrinfo(),
391 // but gethostbyname2() does not understand them; it issues two dns
392 // queries, then fails. This hardly ever happens, there's no point
393 // in fixing this. This test simply verifies the current (bogus)
394 // behavior to avoid further regressions (like crashes, or leaks).
395 constexpr char numeric_v6_scope[] = "fe80::1%lo";
396 dns.clearQueries();
397 result = gethostbyname2(numeric_v6_scope, AF_INET6);
Sehee Parkbbca0202018-11-16 10:53:16 +0900398 EXPECT_EQ(2U, dns.queries().size()); // OUCH!
Ken Chenb9fa2062018-11-13 21:51:13 +0800399 ASSERT_TRUE(result == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800400}
401
402TEST_F(ResolverTest, BinderSerialization) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800403 std::vector<int> params_offsets = {
Luke Huang5bd827c2019-03-14 16:10:04 +0800404 IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY,
405 IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD,
406 IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES,
407 IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES,
408 IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC,
409 IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT,
Ken Chenb9fa2062018-11-13 21:51:13 +0800410 };
Bernie Innocentib102dd22018-12-04 14:57:48 +0900411 const int size = static_cast<int>(params_offsets.size());
Luke Huang5bd827c2019-03-14 16:10:04 +0800412 EXPECT_EQ(size, IDnsResolver::RESOLVER_PARAMS_COUNT);
Ken Chenb9fa2062018-11-13 21:51:13 +0800413 std::sort(params_offsets.begin(), params_offsets.end());
Bernie Innocentib102dd22018-12-04 14:57:48 +0900414 for (int i = 0; i < size; ++i) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800415 EXPECT_EQ(params_offsets[i], i);
416 }
417}
418
419TEST_F(ResolverTest, GetHostByName_Binder) {
Luke Huangf8215372019-11-22 11:53:41 +0800420 std::vector<std::string> domains = {"example.com"};
Ken Chenb9fa2062018-11-13 21:51:13 +0800421 std::vector<std::unique_ptr<test::DNSResponder>> dns;
422 std::vector<std::string> servers;
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900423 std::vector<DnsResponderClient::Mapping> mappings;
424 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupMappings(1, domains, &mappings));
425 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupDNSServers(4, mappings, &dns, &servers));
Ken Chenb9fa2062018-11-13 21:51:13 +0800426 ASSERT_EQ(1U, mappings.size());
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900427 const DnsResponderClient::Mapping& mapping = mappings[0];
Ken Chenb9fa2062018-11-13 21:51:13 +0800428
Xiao Ma09b71022018-12-11 17:56:32 +0900429 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains, kDefaultParams));
Ken Chenb9fa2062018-11-13 21:51:13 +0800430
431 const hostent* result = gethostbyname(mapping.host.c_str());
Bernie Innocentib102dd22018-12-04 14:57:48 +0900432 const size_t total_queries =
Luke Huangfde82482019-06-04 01:04:53 +0800433 std::accumulate(dns.begin(), dns.end(), 0, [&mapping](size_t total, auto& d) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800434 return total + GetNumQueriesForType(*d, ns_type::ns_t_a, mapping.entry.c_str());
435 });
436
437 EXPECT_LE(1U, total_queries);
438 ASSERT_FALSE(result == nullptr);
439 ASSERT_EQ(4, result->h_length);
440 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
441 EXPECT_EQ(mapping.ip4, ToString(result));
442 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
443
444 std::vector<std::string> res_servers;
445 std::vector<std::string> res_domains;
Mike Yu0a1c53d2018-11-26 13:26:21 +0900446 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +0900447 res_params res_params;
Ken Chenb9fa2062018-11-13 21:51:13 +0800448 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +0800449 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800450 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
451 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
452 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chenb9fa2062018-11-13 21:51:13 +0800453 EXPECT_EQ(servers.size(), res_servers.size());
454 EXPECT_EQ(domains.size(), res_domains.size());
Mike Yu0a1c53d2018-11-26 13:26:21 +0900455 EXPECT_EQ(0U, res_tls_servers.size());
Luke Huang5bd827c2019-03-14 16:10:04 +0800456 ASSERT_EQ(static_cast<size_t>(IDnsResolver::RESOLVER_PARAMS_COUNT), kDefaultParams.size());
457 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY],
458 res_params.sample_validity);
459 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD],
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900460 res_params.success_threshold);
Luke Huang5bd827c2019-03-14 16:10:04 +0800461 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES], res_params.min_samples);
462 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES], res_params.max_samples);
463 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
Ken Chenb9fa2062018-11-13 21:51:13 +0800464 res_params.base_timeout_msec);
465 EXPECT_EQ(servers.size(), res_stats.size());
466
Bernie Innocenti0c067e42019-04-01 15:33:16 +0900467 EXPECT_THAT(res_servers, testing::UnorderedElementsAreArray(servers));
468 EXPECT_THAT(res_domains, testing::UnorderedElementsAreArray(domains));
Ken Chenb9fa2062018-11-13 21:51:13 +0800469}
470
471TEST_F(ResolverTest, GetAddrInfo) {
Xiao Ma09b71022018-12-11 17:56:32 +0900472 constexpr char listen_addr[] = "127.0.0.4";
473 constexpr char listen_addr2[] = "127.0.0.5";
474 constexpr char host_name[] = "howdy.example.com.";
Ken Chenb9fa2062018-11-13 21:51:13 +0800475
Xiao Ma09b71022018-12-11 17:56:32 +0900476 const std::vector<DnsRecord> records = {
477 {host_name, ns_type::ns_t_a, "1.2.3.4"},
478 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
479 };
480 test::DNSResponder dns(listen_addr);
481 test::DNSResponder dns2(listen_addr2);
482 StartDns(dns, records);
483 StartDns(dns2, records);
Ken Chenb9fa2062018-11-13 21:51:13 +0800484
Xiao Ma09b71022018-12-11 17:56:32 +0900485 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr}));
Ken Chenb9fa2062018-11-13 21:51:13 +0800486 dns.clearQueries();
487 dns2.clearQueries();
488
489 ScopedAddrinfo result = safe_getaddrinfo("howdy", nullptr, nullptr);
490 EXPECT_TRUE(result != nullptr);
491 size_t found = GetNumQueries(dns, host_name);
492 EXPECT_LE(1U, found);
493 // Could be A or AAAA
494 std::string result_str = ToString(result);
495 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
Luke Huangf8215372019-11-22 11:53:41 +0800496 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +0800497
498 // Verify that the name is cached.
499 size_t old_found = found;
500 result = safe_getaddrinfo("howdy", nullptr, nullptr);
501 EXPECT_TRUE(result != nullptr);
502 found = GetNumQueries(dns, host_name);
503 EXPECT_LE(1U, found);
504 EXPECT_EQ(old_found, found);
505 result_str = ToString(result);
Luke Huangf8215372019-11-22 11:53:41 +0800506 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4") << result_str;
Ken Chenb9fa2062018-11-13 21:51:13 +0800507
508 // Change the DNS resolver, ensure that queries are still cached.
Xiao Ma09b71022018-12-11 17:56:32 +0900509 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr2}));
Ken Chenb9fa2062018-11-13 21:51:13 +0800510 dns.clearQueries();
511 dns2.clearQueries();
512
513 result = safe_getaddrinfo("howdy", nullptr, nullptr);
514 EXPECT_TRUE(result != nullptr);
515 found = GetNumQueries(dns, host_name);
516 size_t found2 = GetNumQueries(dns2, host_name);
517 EXPECT_EQ(0U, found);
518 EXPECT_LE(0U, found2);
519
520 // Could be A or AAAA
521 result_str = ToString(result);
522 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
Luke Huangf8215372019-11-22 11:53:41 +0800523 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +0800524}
525
526TEST_F(ResolverTest, GetAddrInfoV4) {
Xiao Ma09b71022018-12-11 17:56:32 +0900527 test::DNSResponder dns;
528 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.5"}});
529 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800530
Xiao Ma09b71022018-12-11 17:56:32 +0900531 const addrinfo hints = {.ai_family = AF_INET};
532 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
Ken Chenb9fa2062018-11-13 21:51:13 +0800533 EXPECT_TRUE(result != nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900534 EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom));
Ken Chenb9fa2062018-11-13 21:51:13 +0800535 EXPECT_EQ("1.2.3.5", ToString(result));
536}
537
538TEST_F(ResolverTest, GetAddrInfo_localhost) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800539 // Add a dummy nameserver which shouldn't receive any queries
Xiao Ma09b71022018-12-11 17:56:32 +0900540 test::DNSResponder dns;
541 StartDns(dns, {});
542 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800543
Xiao Ma09b71022018-12-11 17:56:32 +0900544 ScopedAddrinfo result = safe_getaddrinfo(kLocalHost, nullptr, nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800545 EXPECT_TRUE(result != nullptr);
546 // Expect no DNS queries; localhost is resolved via /etc/hosts
547 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900548 EXPECT_EQ(kLocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800549
Xiao Ma09b71022018-12-11 17:56:32 +0900550 result = safe_getaddrinfo(kIp6LocalHost, nullptr, nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800551 EXPECT_TRUE(result != nullptr);
552 // Expect no DNS queries; ip6-localhost is resolved via /etc/hosts
553 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900554 EXPECT_EQ(kIp6LocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800555}
556
Luke Huangd8ac4752019-06-18 17:05:47 +0800557TEST_F(ResolverTest, GetAddrInfo_InvalidSocketType) {
558 test::DNSResponder dns;
559 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.5"}});
560 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
561
562 // TODO: Test other invalid socket types.
563 const addrinfo hints = {
564 .ai_family = AF_UNSPEC,
Luke Huangd8ac4752019-06-18 17:05:47 +0800565 .ai_socktype = SOCK_PACKET,
Nick Desaulnierscd6395a2019-10-11 09:15:24 -0700566 .ai_protocol = ANY,
Luke Huangd8ac4752019-06-18 17:05:47 +0800567 };
568 addrinfo* result = nullptr;
569 // This is a valid hint, but the query won't be sent because the socket type is
570 // not supported.
571 EXPECT_EQ(EAI_NODATA, getaddrinfo("hello", nullptr, &hints, &result));
572 ScopedAddrinfo result_cleanup(result);
573 EXPECT_EQ(nullptr, result);
574}
575
Ken Chen92bed612018-12-22 21:46:55 +0800576// Verify if the resolver correctly handle multiple queries simultaneously
577// step 1: set dns server#1 into deferred responding mode.
578// step 2: thread#1 query "hello.example.com." --> resolver send query to server#1.
579// step 3: thread#2 query "hello.example.com." --> resolver hold the request and wait for
580// response of previous pending query sent by thread#1.
581// step 4: thread#3 query "konbanha.example.com." --> resolver send query to server#3. Server
582// respond to resolver immediately.
583// step 5: check if server#1 get 1 query by thread#1, server#2 get 0 query, server#3 get 1 query.
584// step 6: resume dns server#1 to respond dns query in step#2.
585// step 7: thread#1 and #2 should get returned from DNS query after step#6. Also, check the
586// number of queries in server#2 is 0 to ensure thread#2 does not wake up unexpectedly
587// before signaled by thread#1.
588TEST_F(ResolverTest, GetAddrInfoV4_deferred_resp) {
589 const char* listen_addr1 = "127.0.0.9";
590 const char* listen_addr2 = "127.0.0.10";
591 const char* listen_addr3 = "127.0.0.11";
592 const char* listen_srv = "53";
593 const char* host_name_deferred = "hello.example.com.";
594 const char* host_name_normal = "konbanha.example.com.";
Mike Yufc125e42019-05-15 20:41:28 +0800595 test::DNSResponder dns1(listen_addr1, listen_srv, ns_rcode::ns_r_servfail);
596 test::DNSResponder dns2(listen_addr2, listen_srv, ns_rcode::ns_r_servfail);
597 test::DNSResponder dns3(listen_addr3, listen_srv, ns_rcode::ns_r_servfail);
Ken Chen92bed612018-12-22 21:46:55 +0800598 dns1.addMapping(host_name_deferred, ns_type::ns_t_a, "1.2.3.4");
599 dns2.addMapping(host_name_deferred, ns_type::ns_t_a, "1.2.3.4");
600 dns3.addMapping(host_name_normal, ns_type::ns_t_a, "1.2.3.5");
601 ASSERT_TRUE(dns1.startServer());
602 ASSERT_TRUE(dns2.startServer());
603 ASSERT_TRUE(dns3.startServer());
604 const std::vector<std::string> servers_for_t1 = {listen_addr1};
605 const std::vector<std::string> servers_for_t2 = {listen_addr2};
606 const std::vector<std::string> servers_for_t3 = {listen_addr3};
607 addrinfo hints = {.ai_family = AF_INET};
608 const std::vector<int> params = {300, 25, 8, 8, 5000};
609 bool t3_task_done = false;
610
611 dns1.setDeferredResp(true);
612 std::thread t1([&, this]() {
613 ASSERT_TRUE(
614 mDnsClient.SetResolversForNetwork(servers_for_t1, kDefaultSearchDomains, params));
615 ScopedAddrinfo result = safe_getaddrinfo(host_name_deferred, nullptr, &hints);
616 // t3's dns query should got returned first
617 EXPECT_TRUE(t3_task_done);
618 EXPECT_EQ(1U, GetNumQueries(dns1, host_name_deferred));
619 EXPECT_TRUE(result != nullptr);
620 EXPECT_EQ("1.2.3.4", ToString(result));
621 });
622
623 // ensuring t1 and t2 handler functions are processed in order
624 usleep(100 * 1000);
625 std::thread t2([&, this]() {
626 ASSERT_TRUE(
627 mDnsClient.SetResolversForNetwork(servers_for_t2, kDefaultSearchDomains, params));
628 ScopedAddrinfo result = safe_getaddrinfo(host_name_deferred, nullptr, &hints);
629 EXPECT_TRUE(t3_task_done);
630 EXPECT_EQ(0U, GetNumQueries(dns2, host_name_deferred));
631 EXPECT_TRUE(result != nullptr);
632 EXPECT_EQ("1.2.3.4", ToString(result));
633
634 std::vector<std::string> res_servers;
635 std::vector<std::string> res_domains;
636 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +0900637 res_params res_params;
Ken Chen92bed612018-12-22 21:46:55 +0800638 std::vector<ResolverStats> res_stats;
639 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800640 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
641 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains,
642 &res_tls_servers, &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chen92bed612018-12-22 21:46:55 +0800643 EXPECT_EQ(0, wait_for_pending_req_timeout_count);
644 });
645
646 // ensuring t2 and t3 handler functions are processed in order
647 usleep(100 * 1000);
648 std::thread t3([&, this]() {
649 ASSERT_TRUE(
650 mDnsClient.SetResolversForNetwork(servers_for_t3, kDefaultSearchDomains, params));
651 ScopedAddrinfo result = safe_getaddrinfo(host_name_normal, nullptr, &hints);
652 EXPECT_EQ(1U, GetNumQueries(dns1, host_name_deferred));
653 EXPECT_EQ(0U, GetNumQueries(dns2, host_name_deferred));
654 EXPECT_EQ(1U, GetNumQueries(dns3, host_name_normal));
655 EXPECT_TRUE(result != nullptr);
656 EXPECT_EQ("1.2.3.5", ToString(result));
657
658 t3_task_done = true;
659 dns1.setDeferredResp(false);
660 });
661 t3.join();
662 t1.join();
663 t2.join();
664}
665
lifr4e4a2e02019-01-29 16:53:51 +0800666TEST_F(ResolverTest, GetAddrInfo_cnames) {
667 constexpr char host_name[] = "host.example.com.";
668 test::DNSResponder dns;
669 const std::vector<DnsRecord> records = {
670 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
671 {"a.example.com.", ns_type::ns_t_cname, "b.example.com."},
672 {"b.example.com.", ns_type::ns_t_cname, "c.example.com."},
673 {"c.example.com.", ns_type::ns_t_cname, "d.example.com."},
674 {"d.example.com.", ns_type::ns_t_cname, "e.example.com."},
675 {"e.example.com.", ns_type::ns_t_cname, host_name},
676 {host_name, ns_type::ns_t_a, "1.2.3.3"},
677 {host_name, ns_type::ns_t_aaaa, "2001:db8::42"},
678 };
679 StartDns(dns, records);
680 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
681
682 addrinfo hints = {.ai_family = AF_INET};
683 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
684 EXPECT_TRUE(result != nullptr);
685 EXPECT_EQ("1.2.3.3", ToString(result));
686
687 dns.clearQueries();
688 hints = {.ai_family = AF_INET6};
689 result = safe_getaddrinfo("hello", nullptr, &hints);
690 EXPECT_TRUE(result != nullptr);
691 EXPECT_EQ("2001:db8::42", ToString(result));
692}
693
694TEST_F(ResolverTest, GetAddrInfo_cnamesNoIpAddress) {
695 test::DNSResponder dns;
696 const std::vector<DnsRecord> records = {
697 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
698 };
699 StartDns(dns, records);
700 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
701
702 addrinfo hints = {.ai_family = AF_INET};
703 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
704 EXPECT_TRUE(result == nullptr);
705
706 dns.clearQueries();
707 hints = {.ai_family = AF_INET6};
708 result = safe_getaddrinfo("hello", nullptr, &hints);
709 EXPECT_TRUE(result == nullptr);
710}
711
712TEST_F(ResolverTest, GetAddrInfo_cnamesIllegalRdata) {
713 test::DNSResponder dns;
714 const std::vector<DnsRecord> records = {
715 {kHelloExampleCom, ns_type::ns_t_cname, ".!#?"},
716 };
717 StartDns(dns, records);
718 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
719
720 addrinfo hints = {.ai_family = AF_INET};
721 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
722 EXPECT_TRUE(result == nullptr);
723
724 dns.clearQueries();
725 hints = {.ai_family = AF_INET6};
726 result = safe_getaddrinfo("hello", nullptr, &hints);
727 EXPECT_TRUE(result == nullptr);
728}
729
Ken Chenb9fa2062018-11-13 21:51:13 +0800730TEST_F(ResolverTest, MultidomainResolution) {
Xiao Ma09b71022018-12-11 17:56:32 +0900731 constexpr char host_name[] = "nihao.example2.com.";
Luke Huangf8215372019-11-22 11:53:41 +0800732 std::vector<std::string> searchDomains = {"example1.com", "example2.com", "example3.com"};
Ken Chenb9fa2062018-11-13 21:51:13 +0800733
Xiao Ma09b71022018-12-11 17:56:32 +0900734 test::DNSResponder dns("127.0.0.6");
735 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.3"}});
736 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({"127.0.0.6"}, searchDomains));
737
Ken Chenb9fa2062018-11-13 21:51:13 +0800738 const hostent* result = gethostbyname("nihao");
Xiao Ma09b71022018-12-11 17:56:32 +0900739
Ken Chenb9fa2062018-11-13 21:51:13 +0800740 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
741 ASSERT_FALSE(result == nullptr);
742 ASSERT_EQ(4, result->h_length);
743 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
744 EXPECT_EQ("1.2.3.3", ToString(result));
745 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800746}
747
748TEST_F(ResolverTest, GetAddrInfoV6_numeric) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800749 constexpr char host_name[] = "ohayou.example.com.";
750 constexpr char numeric_addr[] = "fe80::1%lo";
751
Xiao Ma09b71022018-12-11 17:56:32 +0900752 test::DNSResponder dns;
Ken Chenb9fa2062018-11-13 21:51:13 +0800753 dns.setResponseProbability(0.0);
Xiao Ma09b71022018-12-11 17:56:32 +0900754 StartDns(dns, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
755 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800756
757 addrinfo hints = {.ai_family = AF_INET6};
758 ScopedAddrinfo result = safe_getaddrinfo(numeric_addr, nullptr, &hints);
759 EXPECT_TRUE(result != nullptr);
760 EXPECT_EQ(numeric_addr, ToString(result));
761 EXPECT_TRUE(dns.queries().empty()); // Ensure no DNS queries were sent out
762
763 // Now try a non-numeric hostname query with the AI_NUMERICHOST flag set.
764 // We should fail without sending out a DNS query.
765 hints.ai_flags |= AI_NUMERICHOST;
766 result = safe_getaddrinfo(host_name, nullptr, &hints);
767 EXPECT_TRUE(result == nullptr);
768 EXPECT_TRUE(dns.queries().empty()); // Ensure no DNS queries were sent out
769}
770
771TEST_F(ResolverTest, GetAddrInfoV6_failing) {
Xiao Ma09b71022018-12-11 17:56:32 +0900772 constexpr char listen_addr0[] = "127.0.0.7";
773 constexpr char listen_addr1[] = "127.0.0.8";
Ken Chenb9fa2062018-11-13 21:51:13 +0800774 const char* host_name = "ohayou.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +0900775
776 test::DNSResponder dns0(listen_addr0);
777 test::DNSResponder dns1(listen_addr1);
Ken Chenb9fa2062018-11-13 21:51:13 +0800778 dns0.setResponseProbability(0.0);
Xiao Ma09b71022018-12-11 17:56:32 +0900779 StartDns(dns0, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
780 StartDns(dns1, {{host_name, ns_type::ns_t_aaaa, "2001:db8::6"}});
781
Luke Huangf8215372019-11-22 11:53:41 +0800782 std::vector<std::string> servers = {listen_addr0, listen_addr1};
Ken Chenb9fa2062018-11-13 21:51:13 +0800783 // <sample validity in s> <success threshold in percent> <min samples> <max samples>
784 int sample_count = 8;
Luke Huangf8215372019-11-22 11:53:41 +0800785 const std::vector<int> params = {300, 25, sample_count, sample_count};
Xiao Ma09b71022018-12-11 17:56:32 +0900786 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, kDefaultSearchDomains, params));
Ken Chenb9fa2062018-11-13 21:51:13 +0800787
788 // Repeatedly perform resolutions for non-existing domains until MAXNSSAMPLES resolutions have
789 // reached the dns0, which is set to fail. No more requests should then arrive at that server
790 // for the next sample_lifetime seconds.
791 // TODO: This approach is implementation-dependent, change once metrics reporting is available.
Xiao Ma09b71022018-12-11 17:56:32 +0900792 const addrinfo hints = {.ai_family = AF_INET6};
Bernie Innocentib102dd22018-12-04 14:57:48 +0900793 for (int i = 0; i < sample_count; ++i) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800794 std::string domain = StringPrintf("nonexistent%d", i);
795 ScopedAddrinfo result = safe_getaddrinfo(domain.c_str(), nullptr, &hints);
796 }
797 // Due to 100% errors for all possible samples, the server should be ignored from now on and
798 // only the second one used for all following queries, until NSSAMPLE_VALIDITY is reached.
799 dns0.clearQueries();
800 dns1.clearQueries();
801 ScopedAddrinfo result = safe_getaddrinfo("ohayou", nullptr, &hints);
802 EXPECT_TRUE(result != nullptr);
803 EXPECT_EQ(0U, GetNumQueries(dns0, host_name));
804 EXPECT_EQ(1U, GetNumQueries(dns1, host_name));
805}
806
807TEST_F(ResolverTest, GetAddrInfoV6_nonresponsive) {
Xiao Ma09b71022018-12-11 17:56:32 +0900808 constexpr char listen_addr0[] = "127.0.0.7";
809 constexpr char listen_addr1[] = "127.0.0.8";
810 constexpr char listen_srv[] = "53";
811 constexpr char host_name1[] = "ohayou.example.com.";
812 constexpr char host_name2[] = "ciao.example.com.";
Luke Huang483cf332019-06-03 17:24:51 +0800813 const std::vector<std::string> defaultSearchDomain = {"example.com"};
814 // The minimal timeout is 1000ms, so we can't decrease timeout
815 // So reduce retry count.
816 const std::vector<int> reduceRetryParams = {
817 300, // sample validity in seconds
818 25, // success threshod in percent
819 8, 8, // {MIN,MAX}_SAMPLES
820 1000, // BASE_TIMEOUT_MSEC
821 1, // retry count
822 };
Xiao Ma09b71022018-12-11 17:56:32 +0900823 const std::vector<DnsRecord> records0 = {
824 {host_name1, ns_type::ns_t_aaaa, "2001:db8::5"},
825 {host_name2, ns_type::ns_t_aaaa, "2001:db8::5"},
826 };
827 const std::vector<DnsRecord> records1 = {
828 {host_name1, ns_type::ns_t_aaaa, "2001:db8::6"},
829 {host_name2, ns_type::ns_t_aaaa, "2001:db8::6"},
830 };
Ken Chenb9fa2062018-11-13 21:51:13 +0800831
832 // dns0 does not respond with 100% probability, while
833 // dns1 responds normally, at least initially.
Mike Yufc125e42019-05-15 20:41:28 +0800834 test::DNSResponder dns0(listen_addr0, listen_srv, static_cast<ns_rcode>(-1));
835 test::DNSResponder dns1(listen_addr1, listen_srv, static_cast<ns_rcode>(-1));
Ken Chenb9fa2062018-11-13 21:51:13 +0800836 dns0.setResponseProbability(0.0);
Xiao Ma09b71022018-12-11 17:56:32 +0900837 StartDns(dns0, records0);
838 StartDns(dns1, records1);
Luke Huang483cf332019-06-03 17:24:51 +0800839 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr0, listen_addr1}, defaultSearchDomain,
840 reduceRetryParams));
Ken Chenb9fa2062018-11-13 21:51:13 +0800841
Luke Huang483cf332019-06-03 17:24:51 +0800842 // Specify ai_socktype to make getaddrinfo will only query 1 time
843 const addrinfo hints = {.ai_family = AF_INET6, .ai_socktype = SOCK_STREAM};
Ken Chenb9fa2062018-11-13 21:51:13 +0800844
845 // dns0 will ignore the request, and we'll fallback to dns1 after the first
846 // retry.
847 ScopedAddrinfo result = safe_getaddrinfo(host_name1, nullptr, &hints);
848 EXPECT_TRUE(result != nullptr);
849 EXPECT_EQ(1U, GetNumQueries(dns0, host_name1));
850 EXPECT_EQ(1U, GetNumQueries(dns1, host_name1));
851
852 // Now make dns1 also ignore 100% requests... The resolve should alternate
Luke Huang483cf332019-06-03 17:24:51 +0800853 // queries between the nameservers and fail
Ken Chenb9fa2062018-11-13 21:51:13 +0800854 dns1.setResponseProbability(0.0);
855 addrinfo* result2 = nullptr;
856 EXPECT_EQ(EAI_NODATA, getaddrinfo(host_name2, nullptr, &hints, &result2));
857 EXPECT_EQ(nullptr, result2);
Luke Huang483cf332019-06-03 17:24:51 +0800858 EXPECT_EQ(1U, GetNumQueries(dns0, host_name2));
859 EXPECT_EQ(1U, GetNumQueries(dns1, host_name2));
Ken Chenb9fa2062018-11-13 21:51:13 +0800860}
861
862TEST_F(ResolverTest, GetAddrInfoV6_concurrent) {
Xiao Ma09b71022018-12-11 17:56:32 +0900863 constexpr char listen_addr0[] = "127.0.0.9";
864 constexpr char listen_addr1[] = "127.0.0.10";
865 constexpr char listen_addr2[] = "127.0.0.11";
866 constexpr char host_name[] = "konbanha.example.com.";
867
868 test::DNSResponder dns0(listen_addr0);
869 test::DNSResponder dns1(listen_addr1);
870 test::DNSResponder dns2(listen_addr2);
871 StartDns(dns0, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
872 StartDns(dns1, {{host_name, ns_type::ns_t_aaaa, "2001:db8::6"}});
873 StartDns(dns2, {{host_name, ns_type::ns_t_aaaa, "2001:db8::7"}});
874
Luke Huangf8215372019-11-22 11:53:41 +0800875 const std::vector<std::string> servers = {listen_addr0, listen_addr1, listen_addr2};
Ken Chenb9fa2062018-11-13 21:51:13 +0800876 std::vector<std::thread> threads(10);
877 for (std::thread& thread : threads) {
Luke Huangf8215372019-11-22 11:53:41 +0800878 thread = std::thread([this, &servers]() {
879 unsigned delay = arc4random_uniform(1 * 1000 * 1000); // <= 1s
Ken Chenb9fa2062018-11-13 21:51:13 +0800880 usleep(delay);
881 std::vector<std::string> serverSubset;
882 for (const auto& server : servers) {
883 if (arc4random_uniform(2)) {
884 serverSubset.push_back(server);
885 }
886 }
887 if (serverSubset.empty()) serverSubset = servers;
Xiao Ma09b71022018-12-11 17:56:32 +0900888 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(serverSubset));
889 const addrinfo hints = {.ai_family = AF_INET6};
Ken Chenb9fa2062018-11-13 21:51:13 +0800890 addrinfo* result = nullptr;
891 int rv = getaddrinfo("konbanha", nullptr, &hints, &result);
892 EXPECT_EQ(0, rv) << "error [" << rv << "] " << gai_strerror(rv);
893 if (result) {
894 freeaddrinfo(result);
895 result = nullptr;
896 }
897 });
898 }
899 for (std::thread& thread : threads) {
900 thread.join();
901 }
Ken Chen92bed612018-12-22 21:46:55 +0800902
903 std::vector<std::string> res_servers;
904 std::vector<std::string> res_domains;
905 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +0900906 res_params res_params;
Ken Chen92bed612018-12-22 21:46:55 +0800907 std::vector<ResolverStats> res_stats;
908 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800909 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
910 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
911 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chen92bed612018-12-22 21:46:55 +0800912 EXPECT_EQ(0, wait_for_pending_req_timeout_count);
Ken Chenb9fa2062018-11-13 21:51:13 +0800913}
914
Ken Chenb9fa2062018-11-13 21:51:13 +0800915TEST_F(ResolverTest, EmptySetup) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800916 std::vector<std::string> servers;
917 std::vector<std::string> domains;
Xiao Ma09b71022018-12-11 17:56:32 +0900918 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
Ken Chenb9fa2062018-11-13 21:51:13 +0800919 std::vector<std::string> res_servers;
920 std::vector<std::string> res_domains;
Mike Yu0a1c53d2018-11-26 13:26:21 +0900921 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +0900922 res_params res_params;
Ken Chenb9fa2062018-11-13 21:51:13 +0800923 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +0800924 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800925 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
926 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
927 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chenb9fa2062018-11-13 21:51:13 +0800928 EXPECT_EQ(0U, res_servers.size());
929 EXPECT_EQ(0U, res_domains.size());
Mike Yu0a1c53d2018-11-26 13:26:21 +0900930 EXPECT_EQ(0U, res_tls_servers.size());
Luke Huang5bd827c2019-03-14 16:10:04 +0800931 ASSERT_EQ(static_cast<size_t>(IDnsResolver::RESOLVER_PARAMS_COUNT), kDefaultParams.size());
932 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY],
933 res_params.sample_validity);
934 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD],
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900935 res_params.success_threshold);
Luke Huang5bd827c2019-03-14 16:10:04 +0800936 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES], res_params.min_samples);
937 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES], res_params.max_samples);
938 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
Ken Chenb9fa2062018-11-13 21:51:13 +0800939 res_params.base_timeout_msec);
Luke Huang5bd827c2019-03-14 16:10:04 +0800940 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT], res_params.retry_count);
Ken Chenb9fa2062018-11-13 21:51:13 +0800941}
942
943TEST_F(ResolverTest, SearchPathChange) {
Xiao Ma09b71022018-12-11 17:56:32 +0900944 constexpr char listen_addr[] = "127.0.0.13";
945 constexpr char host_name1[] = "test13.domain1.org.";
946 constexpr char host_name2[] = "test13.domain2.org.";
Luke Huangf8215372019-11-22 11:53:41 +0800947 std::vector<std::string> servers = {listen_addr};
948 std::vector<std::string> domains = {"domain1.org"};
Xiao Ma09b71022018-12-11 17:56:32 +0900949
950 const std::vector<DnsRecord> records = {
951 {host_name1, ns_type::ns_t_aaaa, "2001:db8::13"},
952 {host_name2, ns_type::ns_t_aaaa, "2001:db8::1:13"},
953 };
954 test::DNSResponder dns(listen_addr);
955 StartDns(dns, records);
956 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
Ken Chenb9fa2062018-11-13 21:51:13 +0800957
958 const addrinfo hints = {.ai_family = AF_INET6};
959 ScopedAddrinfo result = safe_getaddrinfo("test13", nullptr, &hints);
960 EXPECT_TRUE(result != nullptr);
961 EXPECT_EQ(1U, dns.queries().size());
962 EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
963 EXPECT_EQ("2001:db8::13", ToString(result));
964
965 // Test that changing the domain search path on its own works.
Luke Huangf8215372019-11-22 11:53:41 +0800966 domains = {"domain2.org"};
Xiao Ma09b71022018-12-11 17:56:32 +0900967 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
Ken Chenb9fa2062018-11-13 21:51:13 +0800968 dns.clearQueries();
969
970 result = safe_getaddrinfo("test13", nullptr, &hints);
971 EXPECT_TRUE(result != nullptr);
972 EXPECT_EQ(1U, dns.queries().size());
973 EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
974 EXPECT_EQ("2001:db8::1:13", ToString(result));
975}
976
Luke Huang2dac4382019-06-24 13:28:44 +0800977namespace {
978
Luke Huangf8215372019-11-22 11:53:41 +0800979std::vector<std::string> getResolverDomains(aidl::android::net::IDnsResolver* dnsResolverService,
Luke Huang2dac4382019-06-24 13:28:44 +0800980 unsigned netId) {
981 std::vector<std::string> res_servers;
982 std::vector<std::string> res_domains;
983 std::vector<std::string> res_tls_servers;
984 res_params res_params;
985 std::vector<ResolverStats> res_stats;
986 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800987 DnsResponderClient::GetResolverInfo(dnsResolverService, netId, &res_servers, &res_domains,
988 &res_tls_servers, &res_params, &res_stats,
989 &wait_for_pending_req_timeout_count);
Luke Huang2dac4382019-06-24 13:28:44 +0800990 return res_domains;
991}
992
993} // namespace
994
995TEST_F(ResolverTest, SearchPathPrune) {
996 constexpr size_t DUPLICATED_DOMAIN_NUM = 3;
997 constexpr char listen_addr[] = "127.0.0.13";
998 constexpr char domian_name1[] = "domain13.org.";
999 constexpr char domian_name2[] = "domain14.org.";
1000 constexpr char host_name1[] = "test13.domain13.org.";
1001 constexpr char host_name2[] = "test14.domain14.org.";
1002 std::vector<std::string> servers = {listen_addr};
1003
1004 std::vector<std::string> testDomains1;
1005 std::vector<std::string> testDomains2;
1006 // Domain length should be <= 255
1007 // Max number of domains in search path is 6
1008 for (size_t i = 0; i < MAXDNSRCH + 1; i++) {
1009 // Fill up with invalid domain
1010 testDomains1.push_back(std::string(300, i + '0'));
1011 // Fill up with valid but duplicated domain
1012 testDomains2.push_back(StringPrintf("domain%zu.org", i % DUPLICATED_DOMAIN_NUM));
1013 }
1014
1015 // Add valid domain used for query.
1016 testDomains1.push_back(domian_name1);
1017
1018 // Add valid domain twice used for query.
1019 testDomains2.push_back(domian_name2);
1020 testDomains2.push_back(domian_name2);
1021
1022 const std::vector<DnsRecord> records = {
1023 {host_name1, ns_type::ns_t_aaaa, "2001:db8::13"},
1024 {host_name2, ns_type::ns_t_aaaa, "2001:db8::1:13"},
1025 };
1026 test::DNSResponder dns(listen_addr);
1027 StartDns(dns, records);
1028 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, testDomains1));
1029
1030 const addrinfo hints = {.ai_family = AF_INET6};
1031 ScopedAddrinfo result = safe_getaddrinfo("test13", nullptr, &hints);
1032
1033 EXPECT_TRUE(result != nullptr);
1034
1035 EXPECT_EQ(1U, dns.queries().size());
1036 EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
1037 EXPECT_EQ("2001:db8::13", ToString(result));
1038
1039 const auto& res_domains1 = getResolverDomains(mDnsClient.resolvService(), TEST_NETID);
1040 // Expect 1 valid domain, invalid domains are removed.
1041 ASSERT_EQ(1U, res_domains1.size());
1042 EXPECT_EQ(domian_name1, res_domains1[0]);
1043
1044 dns.clearQueries();
1045
1046 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, testDomains2));
1047
1048 result = safe_getaddrinfo("test14", nullptr, &hints);
1049 EXPECT_TRUE(result != nullptr);
1050
1051 // (3 domains * 2 retries) + 1 success query = 7
1052 EXPECT_EQ(7U, dns.queries().size());
1053 EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
1054 EXPECT_EQ("2001:db8::1:13", ToString(result));
1055
1056 const auto& res_domains2 = getResolverDomains(mDnsClient.resolvService(), TEST_NETID);
1057 // Expect 4 valid domain, duplicate domains are removed.
1058 EXPECT_EQ(DUPLICATED_DOMAIN_NUM + 1U, res_domains2.size());
1059 EXPECT_THAT(
1060 std::vector<std::string>({"domain0.org", "domain1.org", "domain2.org", domian_name2}),
1061 testing::ElementsAreArray(res_domains2));
1062}
1063
Mike Yu0a1c53d2018-11-26 13:26:21 +09001064// If we move this function to dns_responder_client, it will complicate the dependency need of
1065// dns_tls_frontend.h.
1066static void setupTlsServers(const std::vector<std::string>& servers,
waynema0e73c2e2019-07-31 15:04:08 +08001067 std::vector<std::unique_ptr<test::DnsTlsFrontend>>* tls) {
Xiao Ma09b71022018-12-11 17:56:32 +09001068 constexpr char listen_udp[] = "53";
1069 constexpr char listen_tls[] = "853";
Mike Yu0a1c53d2018-11-26 13:26:21 +09001070
1071 for (const auto& server : servers) {
1072 auto t = std::make_unique<test::DnsTlsFrontend>(server, listen_tls, server, listen_udp);
1073 t = std::make_unique<test::DnsTlsFrontend>(server, listen_tls, server, listen_udp);
1074 t->startServer();
Mike Yu0a1c53d2018-11-26 13:26:21 +09001075 tls->push_back(std::move(t));
1076 }
1077}
1078
Mike Yu0a1c53d2018-11-26 13:26:21 +09001079TEST_F(ResolverTest, MaxServerPrune_Binder) {
Mike Yu0a1c53d2018-11-26 13:26:21 +09001080 std::vector<std::string> domains;
1081 std::vector<std::unique_ptr<test::DNSResponder>> dns;
1082 std::vector<std::unique_ptr<test::DnsTlsFrontend>> tls;
1083 std::vector<std::string> servers;
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +09001084 std::vector<DnsResponderClient::Mapping> mappings;
Mike Yu0a1c53d2018-11-26 13:26:21 +09001085
1086 for (unsigned i = 0; i < MAXDNSRCH + 1; i++) {
1087 domains.push_back(StringPrintf("example%u.com", i));
1088 }
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +09001089 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupMappings(1, domains, &mappings));
1090 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupDNSServers(MAXNS + 1, mappings, &dns, &servers));
waynema0e73c2e2019-07-31 15:04:08 +08001091 ASSERT_NO_FATAL_FAILURE(setupTlsServers(servers, &tls));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001092
waynema0e73c2e2019-07-31 15:04:08 +08001093 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, domains, kDefaultParams,
1094 kDefaultPrivateDnsHostName));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001095
Mike Yu383855b2019-01-15 17:53:27 +08001096 // If the private DNS validation hasn't completed yet before backend DNS servers stop,
1097 // TLS servers will get stuck in handleOneRequest(), which causes this test stuck in
1098 // ~DnsTlsFrontend() because the TLS server loop threads can't be terminated.
1099 // So, wait for private DNS validation done before stopping backend DNS servers.
1100 for (int i = 0; i < MAXNS; i++) {
chenbruceaff85842019-05-31 15:46:42 +08001101 LOG(INFO) << "Waiting for private DNS validation on " << tls[i]->listen_address() << ".";
Mike Yu724f77d2019-08-16 11:14:50 +08001102 EXPECT_TRUE(WaitForPrivateDnsValidation(tls[i]->listen_address(), true));
chenbruceaff85842019-05-31 15:46:42 +08001103 LOG(INFO) << "private DNS validation on " << tls[i]->listen_address() << " done.";
Mike Yu383855b2019-01-15 17:53:27 +08001104 }
1105
Mike Yu0a1c53d2018-11-26 13:26:21 +09001106 std::vector<std::string> res_servers;
1107 std::vector<std::string> res_domains;
1108 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +09001109 res_params res_params;
Mike Yu0a1c53d2018-11-26 13:26:21 +09001110 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +08001111 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +08001112 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
1113 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
1114 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001115
1116 // Check the size of the stats and its contents.
1117 EXPECT_EQ(static_cast<size_t>(MAXNS), res_servers.size());
1118 EXPECT_EQ(static_cast<size_t>(MAXNS), res_tls_servers.size());
1119 EXPECT_EQ(static_cast<size_t>(MAXDNSRCH), res_domains.size());
1120 EXPECT_TRUE(std::equal(servers.begin(), servers.begin() + MAXNS, res_servers.begin()));
1121 EXPECT_TRUE(std::equal(servers.begin(), servers.begin() + MAXNS, res_tls_servers.begin()));
1122 EXPECT_TRUE(std::equal(domains.begin(), domains.begin() + MAXDNSRCH, res_domains.begin()));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001123}
1124
1125TEST_F(ResolverTest, ResolverStats) {
Xiao Ma09b71022018-12-11 17:56:32 +09001126 constexpr char listen_addr1[] = "127.0.0.4";
1127 constexpr char listen_addr2[] = "127.0.0.5";
1128 constexpr char listen_addr3[] = "127.0.0.6";
Mike Yu0a1c53d2018-11-26 13:26:21 +09001129
1130 // Set server 1 timeout.
Mike Yufc125e42019-05-15 20:41:28 +08001131 test::DNSResponder dns1(listen_addr1, "53", static_cast<ns_rcode>(-1));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001132 dns1.setResponseProbability(0.0);
1133 ASSERT_TRUE(dns1.startServer());
1134
1135 // Set server 2 responding server failure.
Xiao Ma09b71022018-12-11 17:56:32 +09001136 test::DNSResponder dns2(listen_addr2);
Mike Yu0a1c53d2018-11-26 13:26:21 +09001137 dns2.setResponseProbability(0.0);
1138 ASSERT_TRUE(dns2.startServer());
1139
1140 // Set server 3 workable.
Xiao Ma09b71022018-12-11 17:56:32 +09001141 test::DNSResponder dns3(listen_addr3);
1142 dns3.addMapping(kHelloExampleCom, ns_type::ns_t_a, "1.2.3.4");
Mike Yu0a1c53d2018-11-26 13:26:21 +09001143 ASSERT_TRUE(dns3.startServer());
1144
1145 std::vector<std::string> servers = {listen_addr1, listen_addr2, listen_addr3};
Xiao Ma09b71022018-12-11 17:56:32 +09001146 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001147
1148 dns3.clearQueries();
Xiao Ma09b71022018-12-11 17:56:32 +09001149 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
Mike Yu0a1c53d2018-11-26 13:26:21 +09001150 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
Xiao Ma09b71022018-12-11 17:56:32 +09001151 size_t found = GetNumQueries(dns3, kHelloExampleCom);
Mike Yu0a1c53d2018-11-26 13:26:21 +09001152 EXPECT_LE(1U, found);
1153 std::string result_str = ToString(result);
1154 EXPECT_TRUE(result_str == "1.2.3.4") << ", result_str='" << result_str << "'";
1155
1156 std::vector<std::string> res_servers;
1157 std::vector<std::string> res_domains;
1158 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +09001159 res_params res_params;
Mike Yu0a1c53d2018-11-26 13:26:21 +09001160 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +08001161 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +08001162 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
1163 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
1164 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001165
1166 EXPECT_EQ(1, res_stats[0].timeouts);
1167 EXPECT_EQ(1, res_stats[1].errors);
1168 EXPECT_EQ(1, res_stats[2].successes);
Mike Yu0a1c53d2018-11-26 13:26:21 +09001169}
1170
Ken Chenb9fa2062018-11-13 21:51:13 +08001171// Test what happens if the specified TLS server is nonexistent.
1172TEST_F(ResolverTest, GetHostByName_TlsMissing) {
Xiao Ma09b71022018-12-11 17:56:32 +09001173 constexpr char listen_addr[] = "127.0.0.3";
1174 constexpr char host_name[] = "tlsmissing.example.com.";
1175
1176 test::DNSResponder dns;
1177 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.3"}});
Luke Huangf8215372019-11-22 11:53:41 +08001178 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001179
1180 // There's nothing listening on this address, so validation will either fail or
1181 /// hang. Either way, queries will continue to flow to the DNSResponder.
waynema0e73c2e2019-07-31 15:04:08 +08001182 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Ken Chenb9fa2062018-11-13 21:51:13 +08001183
1184 const hostent* result;
1185
1186 result = gethostbyname("tlsmissing");
1187 ASSERT_FALSE(result == nullptr);
1188 EXPECT_EQ("1.2.3.3", ToString(result));
1189
1190 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001191 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001192}
1193
1194// Test what happens if the specified TLS server replies with garbage.
1195TEST_F(ResolverTest, GetHostByName_TlsBroken) {
Xiao Ma09b71022018-12-11 17:56:32 +09001196 constexpr char listen_addr[] = "127.0.0.3";
1197 constexpr char host_name1[] = "tlsbroken1.example.com.";
1198 constexpr char host_name2[] = "tlsbroken2.example.com.";
1199 const std::vector<DnsRecord> records = {
1200 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1201 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1202 };
1203
1204 test::DNSResponder dns;
1205 StartDns(dns, records);
Luke Huangf8215372019-11-22 11:53:41 +08001206 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001207
1208 // Bind the specified private DNS socket but don't respond to any client sockets yet.
1209 int s = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
1210 ASSERT_TRUE(s >= 0);
1211 struct sockaddr_in tlsServer = {
Luke Huangf8215372019-11-22 11:53:41 +08001212 .sin_family = AF_INET,
1213 .sin_port = htons(853),
Ken Chenb9fa2062018-11-13 21:51:13 +08001214 };
1215 ASSERT_TRUE(inet_pton(AF_INET, listen_addr, &tlsServer.sin_addr));
1216 ASSERT_TRUE(enableSockopt(s, SOL_SOCKET, SO_REUSEPORT).ok());
1217 ASSERT_TRUE(enableSockopt(s, SOL_SOCKET, SO_REUSEADDR).ok());
1218 ASSERT_FALSE(bind(s, reinterpret_cast<struct sockaddr*>(&tlsServer), sizeof(tlsServer)));
1219 ASSERT_FALSE(listen(s, 1));
1220
1221 // Trigger TLS validation.
waynema0e73c2e2019-07-31 15:04:08 +08001222 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Ken Chenb9fa2062018-11-13 21:51:13 +08001223
1224 struct sockaddr_storage cliaddr;
1225 socklen_t sin_size = sizeof(cliaddr);
Luke Huangf8215372019-11-22 11:53:41 +08001226 int new_fd = accept4(s, reinterpret_cast<struct sockaddr*>(&cliaddr), &sin_size, SOCK_CLOEXEC);
Ken Chenb9fa2062018-11-13 21:51:13 +08001227 ASSERT_TRUE(new_fd > 0);
1228
1229 // We've received the new file descriptor but not written to it or closed, so the
1230 // validation is still pending. Queries should still flow correctly because the
1231 // server is not used until validation succeeds.
1232 const hostent* result;
1233 result = gethostbyname("tlsbroken1");
1234 ASSERT_FALSE(result == nullptr);
1235 EXPECT_EQ("1.2.3.1", ToString(result));
1236
1237 // Now we cause the validation to fail.
1238 std::string garbage = "definitely not a valid TLS ServerHello";
1239 write(new_fd, garbage.data(), garbage.size());
1240 close(new_fd);
1241
1242 // Validation failure shouldn't interfere with lookups, because lookups won't be sent
1243 // to the TLS server unless validation succeeds.
1244 result = gethostbyname("tlsbroken2");
1245 ASSERT_FALSE(result == nullptr);
1246 EXPECT_EQ("1.2.3.2", ToString(result));
1247
1248 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001249 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001250 close(s);
1251}
1252
1253TEST_F(ResolverTest, GetHostByName_Tls) {
Xiao Ma09b71022018-12-11 17:56:32 +09001254 constexpr char listen_addr[] = "127.0.0.3";
1255 constexpr char listen_udp[] = "53";
1256 constexpr char listen_tls[] = "853";
1257 constexpr char host_name1[] = "tls1.example.com.";
1258 constexpr char host_name2[] = "tls2.example.com.";
1259 constexpr char host_name3[] = "tls3.example.com.";
1260 const std::vector<DnsRecord> records = {
1261 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1262 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1263 {host_name3, ns_type::ns_t_a, "1.2.3.3"},
1264 };
1265
1266 test::DNSResponder dns;
1267 StartDns(dns, records);
Luke Huangf8215372019-11-22 11:53:41 +08001268 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001269
1270 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1271 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08001272 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08001273 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Ken Chenb9fa2062018-11-13 21:51:13 +08001274
Mike Yu724f77d2019-08-16 11:14:50 +08001275 const hostent* result = gethostbyname("tls1");
Ken Chenb9fa2062018-11-13 21:51:13 +08001276 ASSERT_FALSE(result == nullptr);
1277 EXPECT_EQ("1.2.3.1", ToString(result));
1278
1279 // Wait for query to get counted.
1280 EXPECT_TRUE(tls.waitForQueries(2, 5000));
1281
1282 // Stop the TLS server. Since we're in opportunistic mode, queries will
1283 // fall back to the locally-assigned (clear text) nameservers.
1284 tls.stopServer();
1285
1286 dns.clearQueries();
1287 result = gethostbyname("tls2");
1288 EXPECT_FALSE(result == nullptr);
1289 EXPECT_EQ("1.2.3.2", ToString(result));
1290 const auto queries = dns.queries();
1291 EXPECT_EQ(1U, queries.size());
1292 EXPECT_EQ("tls2.example.com.", queries[0].first);
1293 EXPECT_EQ(ns_t_a, queries[0].second);
1294
1295 // Reset the resolvers without enabling TLS. Queries should still be routed
1296 // to the UDP endpoint.
Xiao Ma09b71022018-12-11 17:56:32 +09001297 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001298
1299 result = gethostbyname("tls3");
1300 ASSERT_FALSE(result == nullptr);
1301 EXPECT_EQ("1.2.3.3", ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +08001302}
1303
Ken Chenb9fa2062018-11-13 21:51:13 +08001304TEST_F(ResolverTest, GetHostByName_TlsFailover) {
Xiao Ma09b71022018-12-11 17:56:32 +09001305 constexpr char listen_addr1[] = "127.0.0.3";
1306 constexpr char listen_addr2[] = "127.0.0.4";
1307 constexpr char listen_udp[] = "53";
1308 constexpr char listen_tls[] = "853";
1309 constexpr char host_name1[] = "tlsfailover1.example.com.";
1310 constexpr char host_name2[] = "tlsfailover2.example.com.";
1311 const std::vector<DnsRecord> records1 = {
1312 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1313 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1314 };
1315 const std::vector<DnsRecord> records2 = {
1316 {host_name1, ns_type::ns_t_a, "1.2.3.3"},
1317 {host_name2, ns_type::ns_t_a, "1.2.3.4"},
1318 };
1319
1320 test::DNSResponder dns1(listen_addr1);
1321 test::DNSResponder dns2(listen_addr2);
1322 StartDns(dns1, records1);
1323 StartDns(dns2, records2);
1324
Luke Huangf8215372019-11-22 11:53:41 +08001325 std::vector<std::string> servers = {listen_addr1, listen_addr2};
Ken Chenb9fa2062018-11-13 21:51:13 +08001326
1327 test::DnsTlsFrontend tls1(listen_addr1, listen_tls, listen_addr1, listen_udp);
1328 test::DnsTlsFrontend tls2(listen_addr2, listen_tls, listen_addr2, listen_udp);
1329 ASSERT_TRUE(tls1.startServer());
1330 ASSERT_TRUE(tls2.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08001331 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
1332 kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08001333 EXPECT_TRUE(WaitForPrivateDnsValidation(tls1.listen_address(), true));
1334 EXPECT_TRUE(WaitForPrivateDnsValidation(tls2.listen_address(), true));
Ken Chenb9fa2062018-11-13 21:51:13 +08001335
Mike Yu724f77d2019-08-16 11:14:50 +08001336 const hostent* result = gethostbyname("tlsfailover1");
Ken Chenb9fa2062018-11-13 21:51:13 +08001337 ASSERT_FALSE(result == nullptr);
1338 EXPECT_EQ("1.2.3.1", ToString(result));
1339
1340 // Wait for query to get counted.
1341 EXPECT_TRUE(tls1.waitForQueries(2, 5000));
1342 // No new queries should have reached tls2.
1343 EXPECT_EQ(1, tls2.queries());
1344
1345 // Stop tls1. Subsequent queries should attempt to reach tls1, fail, and retry to tls2.
1346 tls1.stopServer();
1347
1348 result = gethostbyname("tlsfailover2");
1349 EXPECT_EQ("1.2.3.4", ToString(result));
1350
1351 // Wait for query to get counted.
1352 EXPECT_TRUE(tls2.waitForQueries(2, 5000));
1353
1354 // No additional queries should have reached the insecure servers.
1355 EXPECT_EQ(2U, dns1.queries().size());
1356 EXPECT_EQ(2U, dns2.queries().size());
1357
1358 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001359 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Ken Chenb9fa2062018-11-13 21:51:13 +08001360}
1361
1362TEST_F(ResolverTest, GetHostByName_BadTlsName) {
Xiao Ma09b71022018-12-11 17:56:32 +09001363 constexpr char listen_addr[] = "127.0.0.3";
1364 constexpr char listen_udp[] = "53";
1365 constexpr char listen_tls[] = "853";
1366 constexpr char host_name[] = "badtlsname.example.com.";
1367
1368 test::DNSResponder dns;
1369 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.1"}});
Luke Huangf8215372019-11-22 11:53:41 +08001370 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001371
1372 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1373 ASSERT_TRUE(tls.startServer());
Xiao Ma09b71022018-12-11 17:56:32 +09001374 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
waynema0e73c2e2019-07-31 15:04:08 +08001375 kDefaultIncorrectPrivateDnsHostName));
Ken Chenb9fa2062018-11-13 21:51:13 +08001376
waynema0e73c2e2019-07-31 15:04:08 +08001377 // The TLS handshake would fail because the name of TLS server doesn't
1378 // match with TLS server's certificate.
Mike Yu724f77d2019-08-16 11:14:50 +08001379 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), false));
Ken Chenb9fa2062018-11-13 21:51:13 +08001380
1381 // The query should fail hard, because a name was specified.
1382 EXPECT_EQ(nullptr, gethostbyname("badtlsname"));
1383
1384 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001385 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001386}
1387
1388TEST_F(ResolverTest, GetAddrInfo_Tls) {
Xiao Ma09b71022018-12-11 17:56:32 +09001389 constexpr char listen_addr[] = "127.0.0.3";
1390 constexpr char listen_udp[] = "53";
1391 constexpr char listen_tls[] = "853";
1392 constexpr char host_name[] = "addrinfotls.example.com.";
1393 const std::vector<DnsRecord> records = {
1394 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1395 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1396 };
1397
1398 test::DNSResponder dns;
1399 StartDns(dns, records);
Luke Huangf8215372019-11-22 11:53:41 +08001400 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001401
1402 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1403 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08001404 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
1405 kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08001406 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Ken Chenb9fa2062018-11-13 21:51:13 +08001407
1408 dns.clearQueries();
1409 ScopedAddrinfo result = safe_getaddrinfo("addrinfotls", nullptr, nullptr);
1410 EXPECT_TRUE(result != nullptr);
1411 size_t found = GetNumQueries(dns, host_name);
1412 EXPECT_LE(1U, found);
1413 // Could be A or AAAA
1414 std::string result_str = ToString(result);
1415 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
Luke Huangf8215372019-11-22 11:53:41 +08001416 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +08001417 // Wait for both A and AAAA queries to get counted.
1418 EXPECT_TRUE(tls.waitForQueries(3, 5000));
1419
1420 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001421 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001422}
1423
1424TEST_F(ResolverTest, TlsBypass) {
1425 const char OFF[] = "off";
1426 const char OPPORTUNISTIC[] = "opportunistic";
1427 const char STRICT[] = "strict";
1428
1429 const char GETHOSTBYNAME[] = "gethostbyname";
1430 const char GETADDRINFO[] = "getaddrinfo";
1431 const char GETADDRINFOFORNET[] = "getaddrinfofornet";
1432
1433 const unsigned BYPASS_NETID = NETID_USE_LOCAL_NAMESERVERS | TEST_NETID;
1434
Ken Chenb9fa2062018-11-13 21:51:13 +08001435 const char ADDR4[] = "192.0.2.1";
1436 const char ADDR6[] = "2001:db8::1";
1437
1438 const char cleartext_addr[] = "127.0.0.53";
1439 const char cleartext_port[] = "53";
1440 const char tls_port[] = "853";
Luke Huangf8215372019-11-22 11:53:41 +08001441 const std::vector<std::string> servers = {cleartext_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001442
Xiao Ma09b71022018-12-11 17:56:32 +09001443 test::DNSResponder dns(cleartext_addr);
Ken Chenb9fa2062018-11-13 21:51:13 +08001444 ASSERT_TRUE(dns.startServer());
1445
1446 test::DnsTlsFrontend tls(cleartext_addr, tls_port, cleartext_addr, cleartext_port);
Mike Yudd4ac2d2019-05-31 16:52:11 +08001447 ASSERT_TRUE(tls.startServer());
Ken Chenb9fa2062018-11-13 21:51:13 +08001448
Luke Huangf8215372019-11-22 11:53:41 +08001449 // clang-format off
Ken Chenb9fa2062018-11-13 21:51:13 +08001450 struct TestConfig {
1451 const std::string mode;
1452 const bool withWorkingTLS;
1453 const std::string method;
1454
1455 std::string asHostName() const {
Luke Huangf8215372019-11-22 11:53:41 +08001456 return StringPrintf("%s.%s.%s.", mode.c_str(), withWorkingTLS ? "tlsOn" : "tlsOff",
Ken Chenb9fa2062018-11-13 21:51:13 +08001457 method.c_str());
1458 }
1459 } testConfigs[]{
Ken Chenb9fa2062018-11-13 21:51:13 +08001460 {OFF, true, GETHOSTBYNAME},
1461 {OPPORTUNISTIC, true, GETHOSTBYNAME},
1462 {STRICT, true, GETHOSTBYNAME},
Ken Chenb9fa2062018-11-13 21:51:13 +08001463 {OFF, true, GETADDRINFO},
1464 {OPPORTUNISTIC, true, GETADDRINFO},
1465 {STRICT, true, GETADDRINFO},
Ken Chenb9fa2062018-11-13 21:51:13 +08001466 {OFF, true, GETADDRINFOFORNET},
1467 {OPPORTUNISTIC, true, GETADDRINFOFORNET},
1468 {STRICT, true, GETADDRINFOFORNET},
Mike Yudd4ac2d2019-05-31 16:52:11 +08001469 {OFF, false, GETHOSTBYNAME},
1470 {OPPORTUNISTIC, false, GETHOSTBYNAME},
1471 {STRICT, false, GETHOSTBYNAME},
1472 {OFF, false, GETADDRINFO},
1473 {OPPORTUNISTIC, false, GETADDRINFO},
1474 {STRICT, false, GETADDRINFO},
1475 {OFF, false, GETADDRINFOFORNET},
1476 {OPPORTUNISTIC, false, GETADDRINFOFORNET},
1477 {STRICT, false, GETADDRINFOFORNET},
Ken Chenb9fa2062018-11-13 21:51:13 +08001478 };
Luke Huangf8215372019-11-22 11:53:41 +08001479 // clang-format on
Ken Chenb9fa2062018-11-13 21:51:13 +08001480
1481 for (const auto& config : testConfigs) {
1482 const std::string testHostName = config.asHostName();
1483 SCOPED_TRACE(testHostName);
1484
1485 // Don't tempt test bugs due to caching.
1486 const char* host_name = testHostName.c_str();
1487 dns.addMapping(host_name, ns_type::ns_t_a, ADDR4);
1488 dns.addMapping(host_name, ns_type::ns_t_aaaa, ADDR6);
1489
Mike Yudd4ac2d2019-05-31 16:52:11 +08001490 if (config.withWorkingTLS) {
1491 if (!tls.running()) {
1492 ASSERT_TRUE(tls.startServer());
1493 }
1494 } else {
1495 if (tls.running()) {
1496 ASSERT_TRUE(tls.stopServer());
1497 }
1498 }
Ken Chenb9fa2062018-11-13 21:51:13 +08001499
1500 if (config.mode == OFF) {
Xiao Ma09b71022018-12-11 17:56:32 +09001501 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, kDefaultSearchDomains,
1502 kDefaultParams));
Ken Chenb9fa2062018-11-13 21:51:13 +08001503 } else if (config.mode == OPPORTUNISTIC) {
Xiao Ma09b71022018-12-11 17:56:32 +09001504 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08001505 kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08001506
1507 // Wait for the validation event. If the server is running, the validation should
1508 // be successful; otherwise, the validation should be failed.
1509 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), config.withWorkingTLS));
Ken Chenb9fa2062018-11-13 21:51:13 +08001510 } else if (config.mode == STRICT) {
Xiao Ma09b71022018-12-11 17:56:32 +09001511 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08001512 kDefaultParams, kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08001513
1514 // Wait for the validation event.
1515 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), config.withWorkingTLS));
Ken Chenb9fa2062018-11-13 21:51:13 +08001516 }
Mike Yudd4ac2d2019-05-31 16:52:11 +08001517 tls.clearQueries();
Ken Chenb9fa2062018-11-13 21:51:13 +08001518
1519 const hostent* h_result = nullptr;
1520 ScopedAddrinfo ai_result;
1521
1522 if (config.method == GETHOSTBYNAME) {
1523 ASSERT_EQ(0, setNetworkForResolv(BYPASS_NETID));
1524 h_result = gethostbyname(host_name);
1525
1526 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
1527 ASSERT_FALSE(h_result == nullptr);
1528 ASSERT_EQ(4, h_result->h_length);
1529 ASSERT_FALSE(h_result->h_addr_list[0] == nullptr);
1530 EXPECT_EQ(ADDR4, ToString(h_result));
1531 EXPECT_TRUE(h_result->h_addr_list[1] == nullptr);
1532 } else if (config.method == GETADDRINFO) {
1533 ASSERT_EQ(0, setNetworkForResolv(BYPASS_NETID));
1534 ai_result = safe_getaddrinfo(host_name, nullptr, nullptr);
1535 EXPECT_TRUE(ai_result != nullptr);
1536
1537 EXPECT_LE(1U, GetNumQueries(dns, host_name));
1538 // Could be A or AAAA
1539 const std::string result_str = ToString(ai_result);
1540 EXPECT_TRUE(result_str == ADDR4 || result_str == ADDR6)
Luke Huangf8215372019-11-22 11:53:41 +08001541 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +08001542 } else if (config.method == GETADDRINFOFORNET) {
1543 addrinfo* raw_ai_result = nullptr;
1544 EXPECT_EQ(0, android_getaddrinfofornet(host_name, /*servname=*/nullptr,
1545 /*hints=*/nullptr, BYPASS_NETID, MARK_UNSET,
1546 &raw_ai_result));
1547 ai_result.reset(raw_ai_result);
1548
1549 EXPECT_LE(1U, GetNumQueries(dns, host_name));
1550 // Could be A or AAAA
1551 const std::string result_str = ToString(ai_result);
1552 EXPECT_TRUE(result_str == ADDR4 || result_str == ADDR6)
Luke Huangf8215372019-11-22 11:53:41 +08001553 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +08001554 }
1555
Mike Yudd4ac2d2019-05-31 16:52:11 +08001556 EXPECT_EQ(0, tls.queries());
Ken Chenb9fa2062018-11-13 21:51:13 +08001557
1558 // Clear per-process resolv netid.
1559 ASSERT_EQ(0, setNetworkForResolv(NETID_UNSET));
Ken Chenb9fa2062018-11-13 21:51:13 +08001560 dns.clearQueries();
1561 }
Ken Chenb9fa2062018-11-13 21:51:13 +08001562}
1563
1564TEST_F(ResolverTest, StrictMode_NoTlsServers) {
Xiao Ma09b71022018-12-11 17:56:32 +09001565 constexpr char cleartext_addr[] = "127.0.0.53";
Luke Huangf8215372019-11-22 11:53:41 +08001566 const std::vector<std::string> servers = {cleartext_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001567 constexpr char host_name[] = "strictmode.notlsips.example.com.";
1568 const std::vector<DnsRecord> records = {
1569 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1570 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1571 };
Ken Chenb9fa2062018-11-13 21:51:13 +08001572
Xiao Ma09b71022018-12-11 17:56:32 +09001573 test::DNSResponder dns(cleartext_addr);
1574 StartDns(dns, records);
Ken Chenb9fa2062018-11-13 21:51:13 +08001575
waynema0e73c2e2019-07-31 15:04:08 +08001576 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
1577 kDefaultIncorrectPrivateDnsHostName));
Ken Chenb9fa2062018-11-13 21:51:13 +08001578
1579 addrinfo* ai_result = nullptr;
1580 EXPECT_NE(0, getaddrinfo(host_name, nullptr, nullptr, &ai_result));
1581 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
1582}
Luke Huang94b10b92018-11-21 20:13:38 +08001583
1584namespace {
1585
Luke Huang70931aa2019-01-31 11:57:41 +08001586int getAsyncResponse(int fd, int* rcode, uint8_t* buf, int bufLen) {
Luke Huang94b10b92018-11-21 20:13:38 +08001587 struct pollfd wait_fd[1];
1588 wait_fd[0].fd = fd;
1589 wait_fd[0].events = POLLIN;
1590 short revents;
1591 int ret;
1592
1593 ret = poll(wait_fd, 1, -1);
1594 revents = wait_fd[0].revents;
1595 if (revents & POLLIN) {
1596 int n = resNetworkResult(fd, rcode, buf, bufLen);
Luke Huangba7bef92018-12-26 16:53:03 +08001597 // Verify that resNetworkResult() closed the fd
1598 char dummy;
1599 EXPECT_EQ(-1, read(fd, &dummy, sizeof dummy));
1600 EXPECT_EQ(EBADF, errno);
Luke Huang94b10b92018-11-21 20:13:38 +08001601 return n;
1602 }
1603 return -1;
1604}
1605
Luke Huang70931aa2019-01-31 11:57:41 +08001606std::string toString(uint8_t* buf, int bufLen, int ipType) {
Luke Huang94b10b92018-11-21 20:13:38 +08001607 ns_msg handle;
1608 int ancount, n = 0;
1609 ns_rr rr;
1610
Luke Huangf8215372019-11-22 11:53:41 +08001611 if (ns_initparse((const uint8_t*)buf, bufLen, &handle) >= 0) {
Luke Huang94b10b92018-11-21 20:13:38 +08001612 ancount = ns_msg_count(handle, ns_s_an);
1613 if (ns_parserr(&handle, ns_s_an, n, &rr) == 0) {
Luke Huang70931aa2019-01-31 11:57:41 +08001614 const uint8_t* rdata = ns_rr_rdata(rr);
Luke Huang94b10b92018-11-21 20:13:38 +08001615 char buffer[INET6_ADDRSTRLEN];
Luke Huangf8215372019-11-22 11:53:41 +08001616 if (inet_ntop(ipType, (const char*)rdata, buffer, sizeof(buffer))) {
Luke Huang94b10b92018-11-21 20:13:38 +08001617 return buffer;
1618 }
1619 }
1620 }
1621 return "";
1622}
1623
1624int dns_open_proxy() {
1625 int s = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
1626 if (s == -1) {
1627 return -1;
1628 }
1629 const int one = 1;
1630 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1631
1632 static const struct sockaddr_un proxy_addr = {
1633 .sun_family = AF_UNIX,
1634 .sun_path = "/dev/socket/dnsproxyd",
1635 };
1636
Luke Huangf8215372019-11-22 11:53:41 +08001637 if (TEMP_FAILURE_RETRY(connect(s, (const struct sockaddr*)&proxy_addr, sizeof(proxy_addr))) !=
Luke Huang94b10b92018-11-21 20:13:38 +08001638 0) {
1639 close(s);
1640 return -1;
1641 }
1642
1643 return s;
1644}
1645
Luke Huangba7bef92018-12-26 16:53:03 +08001646void expectAnswersValid(int fd, int ipType, const std::string& expectedAnswer) {
1647 int rcode = -1;
1648 uint8_t buf[MAXPACKET] = {};
1649
1650 int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
1651 EXPECT_GT(res, 0);
1652 EXPECT_EQ(expectedAnswer, toString(buf, res, ipType));
1653}
1654
1655void expectAnswersNotValid(int fd, int expectedErrno) {
1656 int rcode = -1;
1657 uint8_t buf[MAXPACKET] = {};
1658
1659 int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
1660 EXPECT_EQ(expectedErrno, res);
1661}
1662
Luke Huang94b10b92018-11-21 20:13:38 +08001663} // namespace
1664
1665TEST_F(ResolverTest, Async_NormalQueryV4V6) {
Xiao Ma09b71022018-12-11 17:56:32 +09001666 constexpr char listen_addr[] = "127.0.0.4";
1667 constexpr char host_name[] = "howdy.example.com.";
1668 const std::vector<DnsRecord> records = {
1669 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1670 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1671 };
1672
1673 test::DNSResponder dns(listen_addr);
1674 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08001675 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001676 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08001677
Luke Huangba7bef92018-12-26 16:53:03 +08001678 int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
1679 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001680 EXPECT_TRUE(fd1 != -1);
1681 EXPECT_TRUE(fd2 != -1);
1682
Luke Huang70931aa2019-01-31 11:57:41 +08001683 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001684 int rcode;
1685 int res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
1686 EXPECT_GT(res, 0);
1687 EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
1688
1689 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
1690 EXPECT_GT(res, 0);
1691 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
1692
1693 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
1694
1695 // Re-query verify cache works
Luke Huangba7bef92018-12-26 16:53:03 +08001696 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
1697 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001698
1699 EXPECT_TRUE(fd1 != -1);
1700 EXPECT_TRUE(fd2 != -1);
1701
1702 res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
1703 EXPECT_GT(res, 0);
1704 EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
1705
1706 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
1707 EXPECT_GT(res, 0);
1708 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
1709
1710 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
1711}
1712
1713TEST_F(ResolverTest, Async_BadQuery) {
Xiao Ma09b71022018-12-11 17:56:32 +09001714 constexpr char listen_addr[] = "127.0.0.4";
1715 constexpr char host_name[] = "howdy.example.com.";
1716 const std::vector<DnsRecord> records = {
1717 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1718 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1719 };
1720
1721 test::DNSResponder dns(listen_addr);
1722 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08001723 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001724 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08001725
1726 static struct {
1727 int fd;
1728 const char* dname;
1729 const int queryType;
1730 const int expectRcode;
1731 } kTestData[] = {
Luke Huangba7bef92018-12-26 16:53:03 +08001732 {-1, "", ns_t_aaaa, 0},
1733 {-1, "as65ass46", ns_t_aaaa, 0},
1734 {-1, "454564564564", ns_t_aaaa, 0},
1735 {-1, "h645235", ns_t_a, 0},
1736 {-1, "www.google.com", ns_t_a, 0},
Luke Huang94b10b92018-11-21 20:13:38 +08001737 };
1738
1739 for (auto& td : kTestData) {
1740 SCOPED_TRACE(td.dname);
Luke Huangba7bef92018-12-26 16:53:03 +08001741 td.fd = resNetworkQuery(TEST_NETID, td.dname, ns_c_in, td.queryType, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001742 EXPECT_TRUE(td.fd != -1);
1743 }
1744
1745 // dns_responder return empty resp(packet only contains query part) with no error currently
1746 for (const auto& td : kTestData) {
Luke Huang70931aa2019-01-31 11:57:41 +08001747 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001748 int rcode;
1749 SCOPED_TRACE(td.dname);
1750 int res = getAsyncResponse(td.fd, &rcode, buf, MAXPACKET);
1751 EXPECT_GT(res, 0);
1752 EXPECT_EQ(rcode, td.expectRcode);
1753 }
1754}
1755
1756TEST_F(ResolverTest, Async_EmptyAnswer) {
Xiao Ma09b71022018-12-11 17:56:32 +09001757 constexpr char listen_addr[] = "127.0.0.4";
1758 constexpr char host_name[] = "howdy.example.com.";
1759 const std::vector<DnsRecord> records = {
1760 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1761 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1762 };
1763
1764 test::DNSResponder dns(listen_addr);
1765 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08001766 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001767 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08001768
Luke Huang9c264bb2018-12-18 16:44:41 +08001769 // TODO: Disable retry to make this test explicit.
1770 auto& cv = dns.getCv();
1771 auto& cvMutex = dns.getCvMutex();
1772 int fd1;
1773 // Wait on the condition variable to ensure that the DNS server has handled our first query.
1774 {
1775 std::unique_lock lk(cvMutex);
Luke Huangba7bef92018-12-26 16:53:03 +08001776 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
Luke Huang9c264bb2018-12-18 16:44:41 +08001777 EXPECT_TRUE(fd1 != -1);
1778 EXPECT_EQ(std::cv_status::no_timeout, cv.wait_for(lk, std::chrono::seconds(1)));
1779 }
Luke Huang94b10b92018-11-21 20:13:38 +08001780
Luke Huang94b10b92018-11-21 20:13:38 +08001781 dns.setResponseProbability(0.0);
Luke Huang94b10b92018-11-21 20:13:38 +08001782
Luke Huangba7bef92018-12-26 16:53:03 +08001783 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001784 EXPECT_TRUE(fd2 != -1);
1785
Luke Huangba7bef92018-12-26 16:53:03 +08001786 int fd3 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001787 EXPECT_TRUE(fd3 != -1);
1788
Luke Huang9c264bb2018-12-18 16:44:41 +08001789 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001790 int rcode;
1791
Luke Huang9c264bb2018-12-18 16:44:41 +08001792 // expect no response
1793 int res = getAsyncResponse(fd3, &rcode, buf, MAXPACKET);
1794 EXPECT_EQ(-ETIMEDOUT, res);
Luke Huang94b10b92018-11-21 20:13:38 +08001795
Luke Huang9c264bb2018-12-18 16:44:41 +08001796 // expect no response
Luke Huang94b10b92018-11-21 20:13:38 +08001797 memset(buf, 0, MAXPACKET);
Luke Huang9c264bb2018-12-18 16:44:41 +08001798 res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
1799 EXPECT_EQ(-ETIMEDOUT, res);
Luke Huang94b10b92018-11-21 20:13:38 +08001800
Luke Huang94b10b92018-11-21 20:13:38 +08001801 dns.setResponseProbability(1.0);
Luke Huang94b10b92018-11-21 20:13:38 +08001802
Luke Huangba7bef92018-12-26 16:53:03 +08001803 int fd4 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001804 EXPECT_TRUE(fd4 != -1);
1805
1806 memset(buf, 0, MAXPACKET);
1807 res = getAsyncResponse(fd4, &rcode, buf, MAXPACKET);
1808 EXPECT_GT(res, 0);
1809 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
1810
1811 memset(buf, 0, MAXPACKET);
1812 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
1813 EXPECT_GT(res, 0);
1814 EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
1815}
1816
1817TEST_F(ResolverTest, Async_MalformedQuery) {
Xiao Ma09b71022018-12-11 17:56:32 +09001818 constexpr char listen_addr[] = "127.0.0.4";
1819 constexpr char host_name[] = "howdy.example.com.";
1820 const std::vector<DnsRecord> records = {
1821 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1822 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1823 };
1824
1825 test::DNSResponder dns(listen_addr);
1826 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08001827 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001828 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08001829
1830 int fd = dns_open_proxy();
1831 EXPECT_TRUE(fd > 0);
1832
1833 const std::string badMsg = "16-52512#";
Xiao Ma09b71022018-12-11 17:56:32 +09001834 static const struct {
Luke Huang94b10b92018-11-21 20:13:38 +08001835 const std::string cmd;
1836 const int expectErr;
1837 } kTestData[] = {
Luke Huangba7bef92018-12-26 16:53:03 +08001838 // Too few arguments
Luke Huang94b10b92018-11-21 20:13:38 +08001839 {"resnsend " + badMsg + '\0', -EINVAL},
1840 // Bad netId
Luke Huangba7bef92018-12-26 16:53:03 +08001841 {"resnsend badnetId 0 " + badMsg + '\0', -EINVAL},
Luke Huang94b10b92018-11-21 20:13:38 +08001842 // Bad raw data
Luke Huangba7bef92018-12-26 16:53:03 +08001843 {"resnsend " + std::to_string(TEST_NETID) + " 0 " + badMsg + '\0', -EILSEQ},
Luke Huang94b10b92018-11-21 20:13:38 +08001844 };
1845
1846 for (unsigned int i = 0; i < std::size(kTestData); i++) {
1847 auto& td = kTestData[i];
1848 SCOPED_TRACE(td.cmd);
1849 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, td.cmd.c_str(), td.cmd.size()));
1850 EXPECT_EQ(rc, static_cast<ssize_t>(td.cmd.size()));
1851
1852 int32_t tmp;
1853 rc = TEMP_FAILURE_RETRY(read(fd, &tmp, sizeof(tmp)));
1854 EXPECT_TRUE(rc > 0);
1855 EXPECT_EQ(static_cast<int>(ntohl(tmp)), td.expectErr);
1856 }
1857 // Normal query with answer buffer
1858 // This is raw data of query "howdy.example.com" type 1 class 1
1859 std::string query = "81sBAAABAAAAAAAABWhvd2R5B2V4YW1wbGUDY29tAAABAAE=";
Luke Huangba7bef92018-12-26 16:53:03 +08001860 std::string cmd = "resnsend " + std::to_string(TEST_NETID) + " 0 " + query + '\0';
Luke Huang94b10b92018-11-21 20:13:38 +08001861 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size()));
1862 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size()));
1863
Luke Huang70931aa2019-01-31 11:57:41 +08001864 uint8_t smallBuf[1] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001865 int rcode;
1866 rc = getAsyncResponse(fd, &rcode, smallBuf, 1);
Luke Huangba7bef92018-12-26 16:53:03 +08001867 EXPECT_EQ(-EMSGSIZE, rc);
Luke Huang94b10b92018-11-21 20:13:38 +08001868
1869 // Do the normal test with large buffer again
1870 fd = dns_open_proxy();
1871 EXPECT_TRUE(fd > 0);
1872 rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size()));
1873 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size()));
Luke Huang70931aa2019-01-31 11:57:41 +08001874 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001875 rc = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
1876 EXPECT_EQ("1.2.3.4", toString(buf, rc, AF_INET));
Mike Yu4f3747b2018-12-02 17:54:29 +09001877}
1878
Luke Huangba7bef92018-12-26 16:53:03 +08001879TEST_F(ResolverTest, Async_CacheFlags) {
Xiao Ma09b71022018-12-11 17:56:32 +09001880 constexpr char listen_addr[] = "127.0.0.4";
1881 constexpr char host_name[] = "howdy.example.com.";
Luke Huang40f5f492019-05-09 19:37:35 +08001882 constexpr char another_host_name[] = "howdy.example2.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09001883 const std::vector<DnsRecord> records = {
1884 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1885 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
Luke Huang40f5f492019-05-09 19:37:35 +08001886 {another_host_name, ns_type::ns_t_a, "1.2.3.5"},
1887 {another_host_name, ns_type::ns_t_aaaa, "::1.2.3.5"},
Xiao Ma09b71022018-12-11 17:56:32 +09001888 };
1889
1890 test::DNSResponder dns(listen_addr);
1891 StartDns(dns, records);
Luke Huangba7bef92018-12-26 16:53:03 +08001892 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001893 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huangba7bef92018-12-26 16:53:03 +08001894
1895 // ANDROID_RESOLV_NO_CACHE_STORE
1896 int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1897 ANDROID_RESOLV_NO_CACHE_STORE);
1898 EXPECT_TRUE(fd1 != -1);
1899 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1900 ANDROID_RESOLV_NO_CACHE_STORE);
1901 EXPECT_TRUE(fd2 != -1);
1902 int fd3 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1903 ANDROID_RESOLV_NO_CACHE_STORE);
1904 EXPECT_TRUE(fd3 != -1);
1905
1906 expectAnswersValid(fd3, AF_INET, "1.2.3.4");
1907 expectAnswersValid(fd2, AF_INET, "1.2.3.4");
1908 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
1909
1910 // No cache exists, expect 3 queries
1911 EXPECT_EQ(3U, GetNumQueries(dns, host_name));
1912
1913 // Re-query and cache
1914 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
1915
1916 EXPECT_TRUE(fd1 != -1);
1917
1918 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
1919
1920 // Now we have cache, expect 4 queries
1921 EXPECT_EQ(4U, GetNumQueries(dns, host_name));
1922
1923 // ANDROID_RESOLV_NO_CACHE_LOOKUP
1924 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1925 ANDROID_RESOLV_NO_CACHE_LOOKUP);
1926 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1927 ANDROID_RESOLV_NO_CACHE_LOOKUP);
1928
1929 EXPECT_TRUE(fd1 != -1);
1930 EXPECT_TRUE(fd2 != -1);
1931
1932 expectAnswersValid(fd2, AF_INET, "1.2.3.4");
1933 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
1934
1935 // Skip cache, expect 6 queries
1936 EXPECT_EQ(6U, GetNumQueries(dns, host_name));
1937
1938 // Re-query verify cache works
1939 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
1940 ANDROID_RESOLV_NO_CACHE_STORE);
1941 EXPECT_TRUE(fd1 != -1);
1942 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
1943
1944 // Cache hits, expect still 6 queries
1945 EXPECT_EQ(6U, GetNumQueries(dns, host_name));
Luke Huanga1d74182019-03-19 17:30:36 +08001946
1947 // Start to verify if ANDROID_RESOLV_NO_CACHE_LOOKUP does write response into cache
1948 dns.clearQueries();
1949
1950 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
1951 ANDROID_RESOLV_NO_CACHE_LOOKUP);
1952 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
1953 ANDROID_RESOLV_NO_CACHE_LOOKUP);
1954
1955 EXPECT_TRUE(fd1 != -1);
1956 EXPECT_TRUE(fd2 != -1);
1957
1958 expectAnswersValid(fd2, AF_INET6, "::1.2.3.4");
1959 expectAnswersValid(fd1, AF_INET6, "::1.2.3.4");
1960
1961 // Skip cache, expect 2 queries
1962 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
1963
1964 // Re-query without flags
1965 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
1966 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
1967
1968 EXPECT_TRUE(fd1 != -1);
1969 EXPECT_TRUE(fd2 != -1);
1970
1971 expectAnswersValid(fd2, AF_INET6, "::1.2.3.4");
1972 expectAnswersValid(fd1, AF_INET6, "::1.2.3.4");
1973
1974 // Cache hits, expect still 2 queries
1975 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
Luke Huang40f5f492019-05-09 19:37:35 +08001976
1977 // Test both ANDROID_RESOLV_NO_CACHE_STORE and ANDROID_RESOLV_NO_CACHE_LOOKUP are set
1978 dns.clearQueries();
1979
1980 // Make sure that the cache of "howdy.example2.com" exists.
1981 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_aaaa, 0);
1982 EXPECT_TRUE(fd1 != -1);
1983 expectAnswersValid(fd1, AF_INET6, "::1.2.3.5");
1984 EXPECT_EQ(1U, GetNumQueries(dns, another_host_name));
1985
1986 // Re-query with testFlags
1987 const int testFlag = ANDROID_RESOLV_NO_CACHE_STORE | ANDROID_RESOLV_NO_CACHE_LOOKUP;
1988 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_aaaa, testFlag);
1989 EXPECT_TRUE(fd1 != -1);
1990 expectAnswersValid(fd1, AF_INET6, "::1.2.3.5");
1991 // Expect cache lookup is skipped.
1992 EXPECT_EQ(2U, GetNumQueries(dns, another_host_name));
1993
1994 // Do another query with testFlags
1995 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_a, testFlag);
1996 EXPECT_TRUE(fd1 != -1);
1997 expectAnswersValid(fd1, AF_INET, "1.2.3.5");
1998 // Expect cache lookup is skipped.
1999 EXPECT_EQ(3U, GetNumQueries(dns, another_host_name));
2000
2001 // Re-query with no flags
2002 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_a, 0);
2003 EXPECT_TRUE(fd1 != -1);
2004 expectAnswersValid(fd1, AF_INET, "1.2.3.5");
2005 // Expect no cache hit because cache storing is also skipped in previous query.
2006 EXPECT_EQ(4U, GetNumQueries(dns, another_host_name));
Luke Huangba7bef92018-12-26 16:53:03 +08002007}
2008
2009TEST_F(ResolverTest, Async_NoRetryFlag) {
Luke Huang70931aa2019-01-31 11:57:41 +08002010 constexpr char listen_addr0[] = "127.0.0.4";
2011 constexpr char listen_addr1[] = "127.0.0.6";
Xiao Ma09b71022018-12-11 17:56:32 +09002012 constexpr char host_name[] = "howdy.example.com.";
2013 const std::vector<DnsRecord> records = {
2014 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2015 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
2016 };
2017
Luke Huang70931aa2019-01-31 11:57:41 +08002018 test::DNSResponder dns0(listen_addr0);
2019 test::DNSResponder dns1(listen_addr1);
2020 StartDns(dns0, records);
2021 StartDns(dns1, records);
2022 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr0, listen_addr1}));
Luke Huangba7bef92018-12-26 16:53:03 +08002023
Luke Huang70931aa2019-01-31 11:57:41 +08002024 dns0.clearQueries();
2025 dns1.clearQueries();
2026
2027 dns0.setResponseProbability(0.0);
2028 dns1.setResponseProbability(0.0);
Luke Huangba7bef92018-12-26 16:53:03 +08002029
2030 int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
2031 ANDROID_RESOLV_NO_RETRY);
2032 EXPECT_TRUE(fd1 != -1);
2033
2034 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
2035 ANDROID_RESOLV_NO_RETRY);
2036 EXPECT_TRUE(fd2 != -1);
2037
2038 // expect no response
2039 expectAnswersNotValid(fd1, -ETIMEDOUT);
2040 expectAnswersNotValid(fd2, -ETIMEDOUT);
2041
Luke Huang70931aa2019-01-31 11:57:41 +08002042 // No retry case, expect total 2 queries. The server is selected randomly.
2043 EXPECT_EQ(2U, GetNumQueries(dns0, host_name) + GetNumQueries(dns1, host_name));
Luke Huangba7bef92018-12-26 16:53:03 +08002044
Luke Huang70931aa2019-01-31 11:57:41 +08002045 dns0.clearQueries();
2046 dns1.clearQueries();
Luke Huangba7bef92018-12-26 16:53:03 +08002047
2048 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
2049 EXPECT_TRUE(fd1 != -1);
2050
2051 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
2052 EXPECT_TRUE(fd2 != -1);
2053
2054 // expect no response
2055 expectAnswersNotValid(fd1, -ETIMEDOUT);
2056 expectAnswersNotValid(fd2, -ETIMEDOUT);
2057
2058 // Retry case, expect 4 queries
Luke Huang70931aa2019-01-31 11:57:41 +08002059 EXPECT_EQ(4U, GetNumQueries(dns0, host_name));
2060 EXPECT_EQ(4U, GetNumQueries(dns1, host_name));
2061}
2062
2063TEST_F(ResolverTest, Async_VerifyQueryID) {
2064 constexpr char listen_addr[] = "127.0.0.4";
2065 constexpr char host_name[] = "howdy.example.com.";
2066 const std::vector<DnsRecord> records = {
2067 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2068 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
2069 };
2070
2071 test::DNSResponder dns(listen_addr);
2072 StartDns(dns, records);
2073 std::vector<std::string> servers = {listen_addr};
2074 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
2075
2076 const uint8_t queryBuf1[] = {
2077 /* Header */
2078 0x55, 0x66, /* Transaction ID */
2079 0x01, 0x00, /* Flags */
2080 0x00, 0x01, /* Questions */
2081 0x00, 0x00, /* Answer RRs */
2082 0x00, 0x00, /* Authority RRs */
2083 0x00, 0x00, /* Additional RRs */
2084 /* Queries */
2085 0x05, 0x68, 0x6f, 0x77, 0x64, 0x79, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
2086 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */
2087 0x00, 0x01, /* Type */
2088 0x00, 0x01 /* Class */
2089 };
2090
2091 int fd = resNetworkSend(TEST_NETID, queryBuf1, sizeof(queryBuf1), 0);
2092 EXPECT_TRUE(fd != -1);
2093
2094 uint8_t buf[MAXPACKET] = {};
2095 int rcode;
2096
2097 int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
2098 EXPECT_GT(res, 0);
2099 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
2100
2101 auto hp = reinterpret_cast<HEADER*>(buf);
2102 EXPECT_EQ(21862U, htons(hp->id));
2103
2104 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
2105
2106 const uint8_t queryBuf2[] = {
2107 /* Header */
2108 0x00, 0x53, /* Transaction ID */
2109 0x01, 0x00, /* Flags */
2110 0x00, 0x01, /* Questions */
2111 0x00, 0x00, /* Answer RRs */
2112 0x00, 0x00, /* Authority RRs */
2113 0x00, 0x00, /* Additional RRs */
2114 /* Queries */
2115 0x05, 0x68, 0x6f, 0x77, 0x64, 0x79, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
2116 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */
2117 0x00, 0x01, /* Type */
2118 0x00, 0x01 /* Class */
2119 };
2120
2121 // Re-query verify cache works and query id is correct
2122 fd = resNetworkSend(TEST_NETID, queryBuf2, sizeof(queryBuf2), 0);
2123
2124 EXPECT_TRUE(fd != -1);
2125
2126 res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
2127 EXPECT_GT(res, 0);
2128 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
2129
2130 EXPECT_EQ(0x0053U, htons(hp->id));
2131
2132 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
Luke Huangba7bef92018-12-26 16:53:03 +08002133}
2134
Mike Yu4f3747b2018-12-02 17:54:29 +09002135// This test checks that the resolver should not generate the request containing OPT RR when using
Ken Chen0a015532019-01-02 14:59:38 +08002136// cleartext DNS. If we query the DNS server not supporting EDNS0 and it reponds with
2137// FORMERR_ON_EDNS, we will fallback to no EDNS0 and try again. If the server does no response, we
2138// won't retry so that we get no answer.
Mike Yu4f3747b2018-12-02 17:54:29 +09002139TEST_F(ResolverTest, BrokenEdns) {
2140 typedef test::DNSResponder::Edns Edns;
2141 enum ExpectResult { EXPECT_FAILURE, EXPECT_SUCCESS };
2142
2143 const char OFF[] = "off";
2144 const char OPPORTUNISTIC_UDP[] = "opportunistic_udp";
2145 const char OPPORTUNISTIC_TLS[] = "opportunistic_tls";
2146 const char STRICT[] = "strict";
2147 const char GETHOSTBYNAME[] = "gethostbyname";
2148 const char GETADDRINFO[] = "getaddrinfo";
Mike Yu4f3747b2018-12-02 17:54:29 +09002149 const char ADDR4[] = "192.0.2.1";
2150 const char CLEARTEXT_ADDR[] = "127.0.0.53";
2151 const char CLEARTEXT_PORT[] = "53";
2152 const char TLS_PORT[] = "853";
Luke Huangf8215372019-11-22 11:53:41 +08002153 const std::vector<std::string> servers = {CLEARTEXT_ADDR};
Mike Yu4f3747b2018-12-02 17:54:29 +09002154
Mike Yufc125e42019-05-15 20:41:28 +08002155 test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, ns_rcode::ns_r_servfail);
Mike Yu4f3747b2018-12-02 17:54:29 +09002156 ASSERT_TRUE(dns.startServer());
2157
2158 test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
2159
Luke Huangf8215372019-11-22 11:53:41 +08002160 // clang-format off
Mike Yu4f3747b2018-12-02 17:54:29 +09002161 static const struct TestConfig {
2162 std::string mode;
2163 std::string method;
2164 Edns edns;
2165 ExpectResult expectResult;
2166
2167 std::string asHostName() const {
2168 const char* ednsString;
2169 switch (edns) {
2170 case Edns::ON:
2171 ednsString = "ednsOn";
2172 break;
Ken Chen0a015532019-01-02 14:59:38 +08002173 case Edns::FORMERR_ON_EDNS:
Mike Yu4f3747b2018-12-02 17:54:29 +09002174 ednsString = "ednsFormerr";
2175 break;
2176 case Edns::DROP:
2177 ednsString = "ednsDrop";
2178 break;
2179 default:
2180 ednsString = "";
2181 break;
2182 }
2183 return StringPrintf("%s.%s.%s.", mode.c_str(), method.c_str(), ednsString);
2184 }
2185 } testConfigs[] = {
2186 // In OPPORTUNISTIC_TLS, we get no answer if the DNS server supports TLS but not EDNS0.
2187 // Could such server exist? if so, we might need to fallback to query cleartext DNS.
2188 // Another thing is that {OPPORTUNISTIC_TLS, Edns::DROP} and {STRICT, Edns::DROP} are
2189 // commented out since TLS timeout is not configurable.
2190 // TODO: Uncomment them after TLS timeout is configurable.
2191 {OFF, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
2192 {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
2193 {OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
2194 {STRICT, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
Ken Chen0a015532019-01-02 14:59:38 +08002195 {OFF, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2196 {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2197 {OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
2198 {STRICT, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
Mike Yu4f3747b2018-12-02 17:54:29 +09002199 {OFF, GETHOSTBYNAME, Edns::DROP, EXPECT_SUCCESS},
2200 {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::DROP, EXPECT_SUCCESS},
2201 //{OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::DROP, EXPECT_FAILURE},
2202 //{STRICT, GETHOSTBYNAME, Edns::DROP, EXPECT_FAILURE},
2203 {OFF, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
2204 {OPPORTUNISTIC_UDP, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
2205 {OPPORTUNISTIC_TLS, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
2206 {STRICT, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
Ken Chen0a015532019-01-02 14:59:38 +08002207 {OFF, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2208 {OPPORTUNISTIC_UDP, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2209 {OPPORTUNISTIC_TLS, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
2210 {STRICT, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
Mike Yu4f3747b2018-12-02 17:54:29 +09002211 {OFF, GETADDRINFO, Edns::DROP, EXPECT_SUCCESS},
2212 {OPPORTUNISTIC_UDP, GETADDRINFO, Edns::DROP, EXPECT_SUCCESS},
2213 //{OPPORTUNISTIC_TLS, GETADDRINFO, Edns::DROP, EXPECT_FAILURE},
2214 //{STRICT, GETADDRINFO, Edns::DROP, EXPECT_FAILURE},
2215 };
Luke Huangf8215372019-11-22 11:53:41 +08002216 // clang-format on
Mike Yu4f3747b2018-12-02 17:54:29 +09002217
2218 for (const auto& config : testConfigs) {
2219 const std::string testHostName = config.asHostName();
2220 SCOPED_TRACE(testHostName);
2221
2222 const char* host_name = testHostName.c_str();
2223 dns.addMapping(host_name, ns_type::ns_t_a, ADDR4);
2224 dns.setEdns(config.edns);
2225
2226 if (config.mode == OFF) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002227 if (tls.running()) {
2228 ASSERT_TRUE(tls.stopServer());
2229 }
Xiao Ma09b71022018-12-11 17:56:32 +09002230 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Mike Yu4f3747b2018-12-02 17:54:29 +09002231 } else if (config.mode == OPPORTUNISTIC_UDP) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002232 if (tls.running()) {
2233 ASSERT_TRUE(tls.stopServer());
2234 }
Xiao Ma09b71022018-12-11 17:56:32 +09002235 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08002236 kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002237 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), false));
Mike Yu4f3747b2018-12-02 17:54:29 +09002238 } else if (config.mode == OPPORTUNISTIC_TLS) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002239 if (!tls.running()) {
2240 ASSERT_TRUE(tls.startServer());
2241 }
Xiao Ma09b71022018-12-11 17:56:32 +09002242 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08002243 kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002244 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yu4f3747b2018-12-02 17:54:29 +09002245 } else if (config.mode == STRICT) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002246 if (!tls.running()) {
2247 ASSERT_TRUE(tls.startServer());
2248 }
Xiao Ma09b71022018-12-11 17:56:32 +09002249 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08002250 kDefaultParams, kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08002251 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yu4f3747b2018-12-02 17:54:29 +09002252 }
2253
2254 if (config.method == GETHOSTBYNAME) {
2255 const hostent* h_result = gethostbyname(host_name);
2256 if (config.expectResult == EXPECT_SUCCESS) {
2257 EXPECT_LE(1U, GetNumQueries(dns, host_name));
2258 ASSERT_TRUE(h_result != nullptr);
2259 ASSERT_EQ(4, h_result->h_length);
2260 ASSERT_FALSE(h_result->h_addr_list[0] == nullptr);
2261 EXPECT_EQ(ADDR4, ToString(h_result));
2262 EXPECT_TRUE(h_result->h_addr_list[1] == nullptr);
2263 } else {
2264 EXPECT_EQ(0U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
2265 ASSERT_TRUE(h_result == nullptr);
2266 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
2267 }
2268 } else if (config.method == GETADDRINFO) {
2269 ScopedAddrinfo ai_result;
2270 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
2271 ai_result = safe_getaddrinfo(host_name, nullptr, &hints);
2272 if (config.expectResult == EXPECT_SUCCESS) {
2273 EXPECT_TRUE(ai_result != nullptr);
2274 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
2275 const std::string result_str = ToString(ai_result);
2276 EXPECT_EQ(ADDR4, result_str);
2277 } else {
2278 EXPECT_TRUE(ai_result == nullptr);
2279 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
2280 }
2281 } else {
2282 FAIL() << "Unsupported query method: " << config.method;
2283 }
2284
Mike Yudd4ac2d2019-05-31 16:52:11 +08002285 tls.clearQueries();
Mike Yu4f3747b2018-12-02 17:54:29 +09002286 dns.clearQueries();
2287 }
Mike Yu4f3747b2018-12-02 17:54:29 +09002288}
nuccachena26cc2a2018-07-17 18:07:23 +08002289
Ken Chen0a015532019-01-02 14:59:38 +08002290// DNS-over-TLS validation success, but server does not respond to TLS query after a while.
2291// Resolver should have a reasonable number of retries instead of spinning forever. We don't have
2292// an efficient way to know if resolver is stuck in an infinite loop. However, test case will be
2293// failed due to timeout.
2294TEST_F(ResolverTest, UnstableTls) {
2295 const char CLEARTEXT_ADDR[] = "127.0.0.53";
2296 const char CLEARTEXT_PORT[] = "53";
2297 const char TLS_PORT[] = "853";
2298 const char* host_name1 = "nonexistent1.example.com.";
2299 const char* host_name2 = "nonexistent2.example.com.";
2300 const std::vector<std::string> servers = {CLEARTEXT_ADDR};
2301
Mike Yufc125e42019-05-15 20:41:28 +08002302 test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, ns_rcode::ns_r_servfail);
Ken Chen0a015532019-01-02 14:59:38 +08002303 ASSERT_TRUE(dns.startServer());
2304 dns.setEdns(test::DNSResponder::Edns::FORMERR_ON_EDNS);
2305 test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
2306 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08002307 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002308 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
2309
Ken Chen0a015532019-01-02 14:59:38 +08002310 // Shutdown TLS server to get an error. It's similar to no response case but without waiting.
2311 tls.stopServer();
2312
2313 const hostent* h_result = gethostbyname(host_name1);
2314 EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
2315 ASSERT_TRUE(h_result == nullptr);
2316 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
2317
2318 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
2319 ScopedAddrinfo ai_result = safe_getaddrinfo(host_name2, nullptr, &hints);
2320 EXPECT_TRUE(ai_result == nullptr);
2321 EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
2322}
2323
2324// DNS-over-TLS validation success, but server does not respond to TLS query after a while.
2325// Moreover, server responds RCODE=FORMERR even on non-EDNS query.
2326TEST_F(ResolverTest, BogusDnsServer) {
2327 const char CLEARTEXT_ADDR[] = "127.0.0.53";
2328 const char CLEARTEXT_PORT[] = "53";
2329 const char TLS_PORT[] = "853";
2330 const char* host_name1 = "nonexistent1.example.com.";
2331 const char* host_name2 = "nonexistent2.example.com.";
2332 const std::vector<std::string> servers = {CLEARTEXT_ADDR};
2333
Mike Yufc125e42019-05-15 20:41:28 +08002334 test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, ns_rcode::ns_r_servfail);
Ken Chen0a015532019-01-02 14:59:38 +08002335 ASSERT_TRUE(dns.startServer());
2336 test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
2337 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08002338 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002339 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
2340
Ken Chen0a015532019-01-02 14:59:38 +08002341 // Shutdown TLS server to get an error. It's similar to no response case but without waiting.
2342 tls.stopServer();
2343 dns.setEdns(test::DNSResponder::Edns::FORMERR_UNCOND);
2344
2345 const hostent* h_result = gethostbyname(host_name1);
2346 EXPECT_EQ(0U, GetNumQueries(dns, host_name1));
2347 ASSERT_TRUE(h_result == nullptr);
2348 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
2349
2350 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
2351 ScopedAddrinfo ai_result = safe_getaddrinfo(host_name2, nullptr, &hints);
2352 EXPECT_TRUE(ai_result == nullptr);
2353 EXPECT_EQ(0U, GetNumQueries(dns, host_name2));
2354}
2355
nuccachena26cc2a2018-07-17 18:07:23 +08002356TEST_F(ResolverTest, GetAddrInfo_Dns64Synthesize) {
2357 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002358 constexpr char dns64_name[] = "ipv4only.arpa.";
2359 constexpr char host_name[] = "v4only.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002360 const std::vector<DnsRecord> records = {
2361 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2362 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2363 };
nuccachena26cc2a2018-07-17 18:07:23 +08002364
Xiao Ma09b71022018-12-11 17:56:32 +09002365 test::DNSResponder dns(listen_addr);
Xiao Ma09b71022018-12-11 17:56:32 +09002366 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002367
2368 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002369 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002370
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002371 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002372 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002373 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002374
2375 // hints are necessary in order to let netd know which type of addresses the caller is
2376 // interested in.
Xiao Ma09b71022018-12-11 17:56:32 +09002377 const addrinfo hints = {.ai_family = AF_UNSPEC};
nuccachena26cc2a2018-07-17 18:07:23 +08002378 ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, &hints);
2379 EXPECT_TRUE(result != nullptr);
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002380 // TODO: BUG: there should only be two queries, one AAAA (which returns no records) and one A
2381 // (which returns 1.2.3.4). But there is an extra AAAA.
2382 EXPECT_EQ(3U, GetNumQueries(dns, host_name));
nuccachena26cc2a2018-07-17 18:07:23 +08002383
2384 std::string result_str = ToString(result);
2385 EXPECT_EQ(result_str, "64:ff9b::102:304");
2386
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002387 // Stopping NAT64 prefix discovery disables synthesis.
Luke Huang5bd827c2019-03-14 16:10:04 +08002388 EXPECT_TRUE(mDnsClient.resolvService()->stopPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002389 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_NOT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002390
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002391 dns.clearQueries();
nuccachena26cc2a2018-07-17 18:07:23 +08002392
2393 result = safe_getaddrinfo("v4only", nullptr, &hints);
2394 EXPECT_TRUE(result != nullptr);
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002395 // TODO: BUG: there should only be one query, an AAAA (which returns no records), because the
2396 // A is already cached. But there is an extra AAAA.
2397 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
nuccachena26cc2a2018-07-17 18:07:23 +08002398
2399 result_str = ToString(result);
2400 EXPECT_EQ(result_str, "1.2.3.4");
2401}
2402
nuccachena26cc2a2018-07-17 18:07:23 +08002403TEST_F(ResolverTest, GetAddrInfo_Dns64QuerySpecified) {
2404 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002405 constexpr char dns64_name[] = "ipv4only.arpa.";
2406 constexpr char host_name[] = "v4only.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002407 const std::vector<DnsRecord> records = {
2408 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2409 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2410 };
nuccachena26cc2a2018-07-17 18:07:23 +08002411
Xiao Ma09b71022018-12-11 17:56:32 +09002412 test::DNSResponder dns(listen_addr);
2413 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002414 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002415 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002416
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002417 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002418 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002419 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002420
2421 // Ensure to synthesize AAAA if AF_INET6 is specified, and not to synthesize AAAA
2422 // in AF_INET case.
2423 addrinfo hints;
2424 memset(&hints, 0, sizeof(hints));
2425 hints.ai_family = AF_INET6;
2426 ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, &hints);
2427 EXPECT_TRUE(result != nullptr);
2428 std::string result_str = ToString(result);
2429 EXPECT_EQ(result_str, "64:ff9b::102:304");
2430
2431 hints.ai_family = AF_INET;
2432 result = safe_getaddrinfo("v4only", nullptr, &hints);
2433 EXPECT_TRUE(result != nullptr);
2434 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2435 result_str = ToString(result);
2436 EXPECT_EQ(result_str, "1.2.3.4");
2437}
nuccachena26cc2a2018-07-17 18:07:23 +08002438
2439TEST_F(ResolverTest, GetAddrInfo_Dns64QueryUnspecifiedV6) {
2440 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002441 constexpr char dns64_name[] = "ipv4only.arpa.";
2442 constexpr char host_name[] = "v4v6.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002443 const std::vector<DnsRecord> records = {
2444 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2445 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2446 {host_name, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
2447 };
nuccachena26cc2a2018-07-17 18:07:23 +08002448
Xiao Ma09b71022018-12-11 17:56:32 +09002449 test::DNSResponder dns(listen_addr);
2450 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002451 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002452 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002453
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002454 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002455 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002456 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002457
Xiao Ma09b71022018-12-11 17:56:32 +09002458 const addrinfo hints = {.ai_family = AF_UNSPEC};
nuccachena26cc2a2018-07-17 18:07:23 +08002459 ScopedAddrinfo result = safe_getaddrinfo("v4v6", nullptr, &hints);
2460 EXPECT_TRUE(result != nullptr);
2461 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2462
2463 // In AF_UNSPEC case, do not synthesize AAAA if there's at least one AAAA answer.
Xiao Ma09b71022018-12-11 17:56:32 +09002464 const std::vector<std::string> result_strs = ToStrings(result);
nuccachena26cc2a2018-07-17 18:07:23 +08002465 for (const auto& str : result_strs) {
2466 EXPECT_TRUE(str == "1.2.3.4" || str == "2001:db8::102:304")
2467 << ", result_str='" << str << "'";
2468 }
2469}
2470
2471TEST_F(ResolverTest, GetAddrInfo_Dns64QueryUnspecifiedNoV6) {
2472 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002473 constexpr char dns64_name[] = "ipv4only.arpa.";
2474 constexpr char host_name[] = "v4v6.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002475 const std::vector<DnsRecord> records = {
2476 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2477 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2478 };
nuccachena26cc2a2018-07-17 18:07:23 +08002479
Xiao Ma09b71022018-12-11 17:56:32 +09002480 test::DNSResponder dns(listen_addr);
2481 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002482 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002483 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002484
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002485 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002486 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002487 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002488
Xiao Ma09b71022018-12-11 17:56:32 +09002489 const addrinfo hints = {.ai_family = AF_UNSPEC};
nuccachena26cc2a2018-07-17 18:07:23 +08002490 ScopedAddrinfo result = safe_getaddrinfo("v4v6", nullptr, &hints);
2491 EXPECT_TRUE(result != nullptr);
2492 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2493
2494 // In AF_UNSPEC case, synthesize AAAA if there's no AAAA answer.
2495 std::string result_str = ToString(result);
2496 EXPECT_EQ(result_str, "64:ff9b::102:304");
2497}
2498
2499TEST_F(ResolverTest, GetAddrInfo_Dns64QuerySpecialUseIPv4Addresses) {
2500 constexpr char THIS_NETWORK[] = "this_network";
2501 constexpr char LOOPBACK[] = "loopback";
2502 constexpr char LINK_LOCAL[] = "link_local";
2503 constexpr char MULTICAST[] = "multicast";
2504 constexpr char LIMITED_BROADCAST[] = "limited_broadcast";
2505
2506 constexpr char ADDR_THIS_NETWORK[] = "0.0.0.1";
2507 constexpr char ADDR_LOOPBACK[] = "127.0.0.1";
2508 constexpr char ADDR_LINK_LOCAL[] = "169.254.0.1";
2509 constexpr char ADDR_MULTICAST[] = "224.0.0.1";
2510 constexpr char ADDR_LIMITED_BROADCAST[] = "255.255.255.255";
2511
2512 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002513 constexpr char dns64_name[] = "ipv4only.arpa.";
2514
Xiao Ma09b71022018-12-11 17:56:32 +09002515 test::DNSResponder dns(listen_addr);
2516 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
nuccachena26cc2a2018-07-17 18:07:23 +08002517 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002518 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002519
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002520 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002521 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002522 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002523
Luke Huangf8215372019-11-22 11:53:41 +08002524 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08002525 static const struct TestConfig {
2526 std::string name;
2527 std::string addr;
2528
2529 std::string asHostName() const { return StringPrintf("%s.example.com.", name.c_str()); }
2530 } testConfigs[]{
2531 {THIS_NETWORK, ADDR_THIS_NETWORK},
2532 {LOOPBACK, ADDR_LOOPBACK},
2533 {LINK_LOCAL, ADDR_LINK_LOCAL},
2534 {MULTICAST, ADDR_MULTICAST},
2535 {LIMITED_BROADCAST, ADDR_LIMITED_BROADCAST}
2536 };
Luke Huangf8215372019-11-22 11:53:41 +08002537 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08002538
2539 for (const auto& config : testConfigs) {
2540 const std::string testHostName = config.asHostName();
2541 SCOPED_TRACE(testHostName);
2542
2543 const char* host_name = testHostName.c_str();
2544 dns.addMapping(host_name, ns_type::ns_t_a, config.addr.c_str());
2545
2546 addrinfo hints;
2547 memset(&hints, 0, sizeof(hints));
2548 hints.ai_family = AF_INET6;
2549 ScopedAddrinfo result = safe_getaddrinfo(config.name.c_str(), nullptr, &hints);
2550 // In AF_INET6 case, don't return IPv4 answers
2551 EXPECT_TRUE(result == nullptr);
2552 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2553 dns.clearQueries();
2554
2555 memset(&hints, 0, sizeof(hints));
2556 hints.ai_family = AF_UNSPEC;
2557 result = safe_getaddrinfo(config.name.c_str(), nullptr, &hints);
2558 EXPECT_TRUE(result != nullptr);
2559 // Expect IPv6 query only. IPv4 answer has been cached in previous query.
2560 EXPECT_LE(1U, GetNumQueries(dns, host_name));
2561 // In AF_UNSPEC case, don't synthesize special use IPv4 address.
2562 std::string result_str = ToString(result);
2563 EXPECT_EQ(result_str, config.addr.c_str());
2564 dns.clearQueries();
2565 }
2566}
2567
2568TEST_F(ResolverTest, GetAddrInfo_Dns64QueryWithNullArgumentHints) {
2569 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002570 constexpr char dns64_name[] = "ipv4only.arpa.";
2571 constexpr char host_name[] = "v4only.example.com.";
2572 constexpr char host_name2[] = "v4v6.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002573 const std::vector<DnsRecord> records = {
2574 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2575 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2576 {host_name2, ns_type::ns_t_a, "1.2.3.4"},
2577 {host_name2, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
2578 };
nuccachena26cc2a2018-07-17 18:07:23 +08002579
Xiao Ma09b71022018-12-11 17:56:32 +09002580 test::DNSResponder dns(listen_addr);
2581 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002582 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002583 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002584
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002585 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002586 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002587 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002588
2589 // Assign argument hints of getaddrinfo() as null is equivalent to set ai_family AF_UNSPEC.
2590 // In AF_UNSPEC case, synthesize AAAA if there has A answer only.
2591 ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, nullptr);
2592 EXPECT_TRUE(result != nullptr);
2593 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2594 std::string result_str = ToString(result);
2595 EXPECT_EQ(result_str, "64:ff9b::102:304");
2596 dns.clearQueries();
2597
2598 // In AF_UNSPEC case, do not synthesize AAAA if there's at least one AAAA answer.
2599 result = safe_getaddrinfo("v4v6", nullptr, nullptr);
2600 EXPECT_TRUE(result != nullptr);
2601 EXPECT_LE(2U, GetNumQueries(dns, host_name2));
2602 std::vector<std::string> result_strs = ToStrings(result);
2603 for (const auto& str : result_strs) {
2604 EXPECT_TRUE(str == "1.2.3.4" || str == "2001:db8::102:304")
2605 << ", result_str='" << str << "'";
2606 }
2607}
2608
2609TEST_F(ResolverTest, GetAddrInfo_Dns64QueryNullArgumentNode) {
2610 constexpr char ADDR_ANYADDR_V4[] = "0.0.0.0";
2611 constexpr char ADDR_ANYADDR_V6[] = "::";
2612 constexpr char ADDR_LOCALHOST_V4[] = "127.0.0.1";
2613 constexpr char ADDR_LOCALHOST_V6[] = "::1";
2614
2615 constexpr char PORT_NAME_HTTP[] = "http";
2616 constexpr char PORT_NUMBER_HTTP[] = "80";
2617
2618 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002619 constexpr char dns64_name[] = "ipv4only.arpa.";
2620
Xiao Ma09b71022018-12-11 17:56:32 +09002621 test::DNSResponder dns(listen_addr);
2622 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
nuccachena26cc2a2018-07-17 18:07:23 +08002623 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002624 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002625
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002626 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002627 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002628 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002629
Luke Huangf8215372019-11-22 11:53:41 +08002630 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08002631 // If node is null, return address is listed by libc/getaddrinfo.c as follows.
2632 // - passive socket -> anyaddr (0.0.0.0 or ::)
2633 // - non-passive socket -> localhost (127.0.0.1 or ::1)
2634 static const struct TestConfig {
2635 int flag;
2636 std::string addr_v4;
2637 std::string addr_v6;
2638
2639 std::string asParameters() const {
2640 return StringPrintf("flag=%d, addr_v4=%s, addr_v6=%s", flag, addr_v4.c_str(),
2641 addr_v6.c_str());
2642 }
2643 } testConfigs[]{
2644 {0 /* non-passive */, ADDR_LOCALHOST_V4, ADDR_LOCALHOST_V6},
2645 {AI_PASSIVE, ADDR_ANYADDR_V4, ADDR_ANYADDR_V6}
2646 };
Luke Huangf8215372019-11-22 11:53:41 +08002647 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08002648
2649 for (const auto& config : testConfigs) {
2650 SCOPED_TRACE(config.asParameters());
2651
Xiao Ma09b71022018-12-11 17:56:32 +09002652 addrinfo hints = {
Nick Desaulnierscd6395a2019-10-11 09:15:24 -07002653 .ai_flags = config.flag,
Xiao Ma09b71022018-12-11 17:56:32 +09002654 .ai_family = AF_UNSPEC, // any address family
2655 .ai_socktype = 0, // any type
2656 .ai_protocol = 0, // any protocol
Xiao Ma09b71022018-12-11 17:56:32 +09002657 };
nuccachena26cc2a2018-07-17 18:07:23 +08002658
2659 // Assign hostname as null and service as port name.
2660 ScopedAddrinfo result = safe_getaddrinfo(nullptr, PORT_NAME_HTTP, &hints);
2661 ASSERT_TRUE(result != nullptr);
2662
2663 // Can't be synthesized because it should not get into Netd.
2664 std::vector<std::string> result_strs = ToStrings(result);
2665 for (const auto& str : result_strs) {
2666 EXPECT_TRUE(str == config.addr_v4 || str == config.addr_v6)
2667 << ", result_str='" << str << "'";
2668 }
2669
2670 // Assign hostname as null and service as numeric port number.
2671 hints.ai_flags = config.flag | AI_NUMERICSERV;
2672 result = safe_getaddrinfo(nullptr, PORT_NUMBER_HTTP, &hints);
2673 ASSERT_TRUE(result != nullptr);
2674
2675 // Can't be synthesized because it should not get into Netd.
2676 result_strs = ToStrings(result);
2677 for (const auto& str : result_strs) {
2678 EXPECT_TRUE(str == config.addr_v4 || str == config.addr_v6)
2679 << ", result_str='" << str << "'";
2680 }
2681 }
2682}
2683
2684TEST_F(ResolverTest, GetHostByAddr_ReverseDnsQueryWithHavingNat64Prefix) {
2685 struct hostent* result = nullptr;
2686 struct in_addr v4addr;
2687 struct in6_addr v6addr;
2688
2689 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002690 constexpr char dns64_name[] = "ipv4only.arpa.";
2691 constexpr char ptr_name[] = "v4v6.example.com.";
2692 // PTR record for IPv4 address 1.2.3.4
2693 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2694 // PTR record for IPv6 address 2001:db8::102:304
2695 constexpr char ptr_addr_v6[] =
2696 "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 +09002697 const std::vector<DnsRecord> records = {
2698 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2699 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2700 {ptr_addr_v6, ns_type::ns_t_ptr, ptr_name},
2701 };
nuccachena26cc2a2018-07-17 18:07:23 +08002702
Xiao Ma09b71022018-12-11 17:56:32 +09002703 test::DNSResponder dns(listen_addr);
2704 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002705 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002706 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002707
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002708 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002709 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002710 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002711
2712 // Reverse IPv4 DNS query. Prefix should have no effect on it.
2713 inet_pton(AF_INET, "1.2.3.4", &v4addr);
2714 result = gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET);
2715 ASSERT_TRUE(result != nullptr);
2716 std::string result_str = result->h_name ? result->h_name : "null";
2717 EXPECT_EQ(result_str, "v4v6.example.com");
2718
2719 // Reverse IPv6 DNS query. Prefix should have no effect on it.
2720 inet_pton(AF_INET6, "2001:db8::102:304", &v6addr);
2721 result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2722 ASSERT_TRUE(result != nullptr);
2723 result_str = result->h_name ? result->h_name : "null";
2724 EXPECT_EQ(result_str, "v4v6.example.com");
2725}
2726
2727TEST_F(ResolverTest, GetHostByAddr_ReverseDns64Query) {
2728 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002729 constexpr char dns64_name[] = "ipv4only.arpa.";
2730 constexpr char ptr_name[] = "v4only.example.com.";
2731 // PTR record for IPv4 address 1.2.3.4
2732 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2733 // PTR record for IPv6 address 64:ff9b::1.2.3.4
2734 constexpr char ptr_addr_v6_nomapping[] =
2735 "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.";
2736 constexpr char ptr_name_v6_synthesis[] = "v6synthesis.example.com.";
2737 // PTR record for IPv6 address 64:ff9b::5.6.7.8
2738 constexpr char ptr_addr_v6_synthesis[] =
2739 "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 +09002740 const std::vector<DnsRecord> records = {
2741 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2742 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2743 {ptr_addr_v6_synthesis, ns_type::ns_t_ptr, ptr_name_v6_synthesis},
2744 };
nuccachena26cc2a2018-07-17 18:07:23 +08002745
Xiao Ma09b71022018-12-11 17:56:32 +09002746 test::DNSResponder dns(listen_addr);
2747 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002748 // "ptr_addr_v6_nomapping" is not mapped in DNS server
nuccachena26cc2a2018-07-17 18:07:23 +08002749 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002750 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002751
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002752 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002753 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002754 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002755
2756 // Synthesized PTR record doesn't exist on DNS server
2757 // Reverse IPv6 DNS64 query while DNS server doesn't have an answer for synthesized address.
2758 // After querying synthesized address failed, expect that prefix is removed from IPv6
2759 // synthesized address and do reverse IPv4 query instead.
2760 struct in6_addr v6addr;
2761 inet_pton(AF_INET6, "64:ff9b::1.2.3.4", &v6addr);
2762 struct hostent* result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2763 ASSERT_TRUE(result != nullptr);
2764 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_nomapping)); // PTR record not exist
2765 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4)); // PTR record exist
2766 std::string result_str = result->h_name ? result->h_name : "null";
2767 EXPECT_EQ(result_str, "v4only.example.com");
2768 // Check that return address has been mapped from IPv4 to IPv6 address because Netd
2769 // removes NAT64 prefix and does IPv4 DNS reverse lookup in this case. Then, Netd
2770 // fakes the return IPv4 address as original queried IPv6 address.
2771 result_str = ToString(result);
2772 EXPECT_EQ(result_str, "64:ff9b::102:304");
2773 dns.clearQueries();
2774
2775 // Synthesized PTR record exists on DNS server
2776 // Reverse IPv6 DNS64 query while DNS server has an answer for synthesized address.
2777 // Expect to Netd pass through synthesized address for DNS queries.
2778 inet_pton(AF_INET6, "64:ff9b::5.6.7.8", &v6addr);
2779 result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2780 ASSERT_TRUE(result != nullptr);
2781 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_synthesis));
2782 result_str = result->h_name ? result->h_name : "null";
2783 EXPECT_EQ(result_str, "v6synthesis.example.com");
2784}
2785
2786TEST_F(ResolverTest, GetHostByAddr_ReverseDns64QueryFromHostFile) {
2787 constexpr char dns64_name[] = "ipv4only.arpa.";
2788 constexpr char host_name[] = "localhost";
2789 // The address is synthesized by prefix64:localhost.
2790 constexpr char host_addr[] = "64:ff9b::7f00:1";
nuccachena26cc2a2018-07-17 18:07:23 +08002791 constexpr char listen_addr[] = "::1";
Xiao Ma09b71022018-12-11 17:56:32 +09002792
2793 test::DNSResponder dns(listen_addr);
2794 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
nuccachena26cc2a2018-07-17 18:07:23 +08002795 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002796 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002797
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002798 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002799 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002800 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002801
2802 // Using synthesized "localhost" address to be a trick for resolving host name
2803 // from host file /etc/hosts and "localhost" is the only name in /etc/hosts. Note that this is
2804 // not realistic: the code never synthesizes AAAA records for addresses in 127.0.0.0/8.
2805 struct in6_addr v6addr;
2806 inet_pton(AF_INET6, host_addr, &v6addr);
2807 struct hostent* result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2808 ASSERT_TRUE(result != nullptr);
2809 // Expect no DNS queries; localhost is resolved via /etc/hosts.
2810 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
2811
Luke Huangf8215372019-11-22 11:53:41 +08002812 ASSERT_EQ(sizeof(in6_addr), (unsigned)result->h_length);
nuccachena26cc2a2018-07-17 18:07:23 +08002813 ASSERT_EQ(AF_INET6, result->h_addrtype);
2814 std::string result_str = ToString(result);
2815 EXPECT_EQ(result_str, host_addr);
2816 result_str = result->h_name ? result->h_name : "null";
2817 EXPECT_EQ(result_str, host_name);
2818}
2819
Hungming Chen9e6185a2019-06-04 16:09:19 +08002820TEST_F(ResolverTest, GetHostByAddr_cnamesClasslessReverseDelegation) {
2821 // IPv4 addresses in the subnet with notation '/' or '-'.
2822 constexpr char addr_slash[] = "192.0.2.1";
2823 constexpr char addr_hyphen[] = "192.0.3.1";
2824
2825 // Used to verify DNS reverse query for classless reverse lookup zone. See detail in RFC 2317
2826 // section 4.
2827 const static std::vector<DnsRecord> records = {
2828 // The records for reverse querying "192.0.2.1" in the subnet with notation '/'.
2829 {"1.2.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0/25.2.0.192.in-addr.arpa."},
2830 {"1.0/25.2.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
2831
2832 // The records for reverse querying "192.0.3.1" in the subnet with notation '-'.
2833 {"1.3.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0-127.3.0.192.in-addr.arpa."},
2834 {"1.0-127.3.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
2835 };
2836
2837 test::DNSResponder dns;
2838 StartDns(dns, records);
2839 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
2840
2841 for (const auto& address : {addr_slash, addr_hyphen}) {
2842 SCOPED_TRACE(address);
2843
2844 in_addr v4addr;
2845 ASSERT_TRUE(inet_pton(AF_INET, address, &v4addr));
2846 hostent* result = gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET);
2847 ASSERT_TRUE(result != nullptr);
2848 EXPECT_STREQ("hello.example.com", result->h_name);
2849 }
2850}
2851
nuccachena26cc2a2018-07-17 18:07:23 +08002852TEST_F(ResolverTest, GetNameInfo_ReverseDnsQueryWithHavingNat64Prefix) {
2853 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002854 constexpr char dns64_name[] = "ipv4only.arpa.";
2855 constexpr char ptr_name[] = "v4v6.example.com.";
2856 // PTR record for IPv4 address 1.2.3.4
2857 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2858 // PTR record for IPv6 address 2001:db8::102:304
2859 constexpr char ptr_addr_v6[] =
2860 "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 +09002861 const std::vector<DnsRecord> records = {
2862 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2863 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2864 {ptr_addr_v6, ns_type::ns_t_ptr, ptr_name},
2865 };
nuccachena26cc2a2018-07-17 18:07:23 +08002866
Xiao Ma09b71022018-12-11 17:56:32 +09002867 test::DNSResponder dns(listen_addr);
2868 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002869 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002870 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002871
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002872 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002873 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002874 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002875
Luke Huangf8215372019-11-22 11:53:41 +08002876 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08002877 static const struct TestConfig {
2878 int flag;
2879 int family;
2880 std::string addr;
2881 std::string host;
2882
2883 std::string asParameters() const {
2884 return StringPrintf("flag=%d, family=%d, addr=%s, host=%s", flag, family, addr.c_str(),
2885 host.c_str());
2886 }
2887 } testConfigs[]{
2888 {NI_NAMEREQD, AF_INET, "1.2.3.4", "v4v6.example.com"},
2889 {NI_NUMERICHOST, AF_INET, "1.2.3.4", "1.2.3.4"},
2890 {0, AF_INET, "1.2.3.4", "v4v6.example.com"},
2891 {0, AF_INET, "5.6.7.8", "5.6.7.8"}, // unmapped
2892 {NI_NAMEREQD, AF_INET6, "2001:db8::102:304", "v4v6.example.com"},
2893 {NI_NUMERICHOST, AF_INET6, "2001:db8::102:304", "2001:db8::102:304"},
2894 {0, AF_INET6, "2001:db8::102:304", "v4v6.example.com"},
2895 {0, AF_INET6, "2001:db8::506:708", "2001:db8::506:708"}, // unmapped
2896 };
Luke Huangf8215372019-11-22 11:53:41 +08002897 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08002898
2899 // Reverse IPv4/IPv6 DNS query. Prefix should have no effect on it.
2900 for (const auto& config : testConfigs) {
2901 SCOPED_TRACE(config.asParameters());
2902
2903 int rv;
2904 char host[NI_MAXHOST];
2905 struct sockaddr_in sin;
2906 struct sockaddr_in6 sin6;
2907 if (config.family == AF_INET) {
2908 memset(&sin, 0, sizeof(sin));
2909 sin.sin_family = AF_INET;
2910 inet_pton(AF_INET, config.addr.c_str(), &sin.sin_addr);
Luke Huangf8215372019-11-22 11:53:41 +08002911 rv = getnameinfo((const struct sockaddr*)&sin, sizeof(sin), host, sizeof(host), nullptr,
2912 0, config.flag);
nuccachena26cc2a2018-07-17 18:07:23 +08002913 if (config.flag == NI_NAMEREQD) EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4));
2914 } else if (config.family == AF_INET6) {
2915 memset(&sin6, 0, sizeof(sin6));
2916 sin6.sin6_family = AF_INET6;
2917 inet_pton(AF_INET6, config.addr.c_str(), &sin6.sin6_addr);
Luke Huangf8215372019-11-22 11:53:41 +08002918 rv = getnameinfo((const struct sockaddr*)&sin6, sizeof(sin6), host, sizeof(host),
nuccachena26cc2a2018-07-17 18:07:23 +08002919 nullptr, 0, config.flag);
2920 if (config.flag == NI_NAMEREQD) EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6));
2921 }
2922 ASSERT_EQ(0, rv);
2923 std::string result_str = host;
2924 EXPECT_EQ(result_str, config.host);
2925 dns.clearQueries();
2926 }
2927}
2928
2929TEST_F(ResolverTest, GetNameInfo_ReverseDns64Query) {
2930 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002931 constexpr char dns64_name[] = "ipv4only.arpa.";
2932 constexpr char ptr_name[] = "v4only.example.com.";
2933 // PTR record for IPv4 address 1.2.3.4
2934 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2935 // PTR record for IPv6 address 64:ff9b::1.2.3.4
2936 constexpr char ptr_addr_v6_nomapping[] =
2937 "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.";
2938 constexpr char ptr_name_v6_synthesis[] = "v6synthesis.example.com.";
2939 // PTR record for IPv6 address 64:ff9b::5.6.7.8
2940 constexpr char ptr_addr_v6_synthesis[] =
2941 "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 +09002942 const std::vector<DnsRecord> records = {
2943 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2944 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2945 {ptr_addr_v6_synthesis, ns_type::ns_t_ptr, ptr_name_v6_synthesis},
2946 };
nuccachena26cc2a2018-07-17 18:07:23 +08002947
Xiao Ma09b71022018-12-11 17:56:32 +09002948 test::DNSResponder dns(listen_addr);
2949 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002950 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002951 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002952
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002953 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002954 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002955 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002956
Luke Huangf8215372019-11-22 11:53:41 +08002957 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08002958 static const struct TestConfig {
2959 bool hasSynthesizedPtrRecord;
2960 int flag;
2961 std::string addr;
2962 std::string host;
2963
2964 std::string asParameters() const {
2965 return StringPrintf("hasSynthesizedPtrRecord=%d, flag=%d, addr=%s, host=%s",
2966 hasSynthesizedPtrRecord, flag, addr.c_str(), host.c_str());
2967 }
2968 } testConfigs[]{
2969 {false, NI_NAMEREQD, "64:ff9b::102:304", "v4only.example.com"},
2970 {false, NI_NUMERICHOST, "64:ff9b::102:304", "64:ff9b::102:304"},
2971 {false, 0, "64:ff9b::102:304", "v4only.example.com"},
2972 {true, NI_NAMEREQD, "64:ff9b::506:708", "v6synthesis.example.com"},
2973 {true, NI_NUMERICHOST, "64:ff9b::506:708", "64:ff9b::506:708"},
2974 {true, 0, "64:ff9b::506:708", "v6synthesis.example.com"}
2975 };
Luke Huangf8215372019-11-22 11:53:41 +08002976 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08002977
2978 // hasSynthesizedPtrRecord = false
2979 // Synthesized PTR record doesn't exist on DNS server
2980 // Reverse IPv6 DNS64 query while DNS server doesn't have an answer for synthesized address.
2981 // After querying synthesized address failed, expect that prefix is removed from IPv6
2982 // synthesized address and do reverse IPv4 query instead.
2983 //
2984 // hasSynthesizedPtrRecord = true
2985 // Synthesized PTR record exists on DNS server
2986 // Reverse IPv6 DNS64 query while DNS server has an answer for synthesized address.
2987 // Expect to just pass through synthesized address for DNS queries.
2988 for (const auto& config : testConfigs) {
2989 SCOPED_TRACE(config.asParameters());
2990
2991 char host[NI_MAXHOST];
2992 struct sockaddr_in6 sin6;
2993 memset(&sin6, 0, sizeof(sin6));
2994 sin6.sin6_family = AF_INET6;
2995 inet_pton(AF_INET6, config.addr.c_str(), &sin6.sin6_addr);
Luke Huangf8215372019-11-22 11:53:41 +08002996 int rv = getnameinfo((const struct sockaddr*)&sin6, sizeof(sin6), host, sizeof(host),
nuccachena26cc2a2018-07-17 18:07:23 +08002997 nullptr, 0, config.flag);
2998 ASSERT_EQ(0, rv);
2999 if (config.flag == NI_NAMEREQD) {
3000 if (config.hasSynthesizedPtrRecord) {
3001 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_synthesis));
3002 } else {
3003 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_nomapping)); // PTR record not exist.
3004 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4)); // PTR record exist.
3005 }
3006 }
3007 std::string result_str = host;
3008 EXPECT_EQ(result_str, config.host);
3009 dns.clearQueries();
3010 }
3011}
3012
3013TEST_F(ResolverTest, GetNameInfo_ReverseDns64QueryFromHostFile) {
3014 constexpr char dns64_name[] = "ipv4only.arpa.";
3015 constexpr char host_name[] = "localhost";
3016 // The address is synthesized by prefix64:localhost.
3017 constexpr char host_addr[] = "64:ff9b::7f00:1";
nuccachena26cc2a2018-07-17 18:07:23 +08003018 constexpr char listen_addr[] = "::1";
Xiao Ma09b71022018-12-11 17:56:32 +09003019
3020 test::DNSResponder dns(listen_addr);
3021 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
nuccachena26cc2a2018-07-17 18:07:23 +08003022 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003023 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003024
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003025 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003026 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003027 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003028
3029 // Using synthesized "localhost" address to be a trick for resolving host name
3030 // from host file /etc/hosts and "localhost" is the only name in /etc/hosts. Note that this is
3031 // not realistic: the code never synthesizes AAAA records for addresses in 127.0.0.0/8.
3032 char host[NI_MAXHOST];
Xiao Ma09b71022018-12-11 17:56:32 +09003033 struct sockaddr_in6 sin6 = {.sin6_family = AF_INET6};
nuccachena26cc2a2018-07-17 18:07:23 +08003034 inet_pton(AF_INET6, host_addr, &sin6.sin6_addr);
Luke Huangf8215372019-11-22 11:53:41 +08003035 int rv = getnameinfo((const struct sockaddr*)&sin6, sizeof(sin6), host, sizeof(host), nullptr,
nuccachena26cc2a2018-07-17 18:07:23 +08003036 0, NI_NAMEREQD);
3037 ASSERT_EQ(0, rv);
3038 // Expect no DNS queries; localhost is resolved via /etc/hosts.
3039 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
3040
3041 std::string result_str = host;
3042 EXPECT_EQ(result_str, host_name);
3043}
3044
Hungming Chen9e6185a2019-06-04 16:09:19 +08003045TEST_F(ResolverTest, GetNameInfo_cnamesClasslessReverseDelegation) {
3046 // IPv4 addresses in the subnet with notation '/' or '-'.
3047 constexpr char addr_slash[] = "192.0.2.1";
3048 constexpr char addr_hyphen[] = "192.0.3.1";
3049
3050 // Used to verify DNS reverse query for classless reverse lookup zone. See detail in RFC 2317
3051 // section 4.
3052 const static std::vector<DnsRecord> records = {
3053 // The records for reverse querying "192.0.2.1" in the subnet with notation '/'.
3054 {"1.2.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0/25.2.0.192.in-addr.arpa."},
3055 {"1.0/25.2.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
3056
3057 // The records for reverse querying "192.0.3.1" in the subnet with notation '-'.
3058 {"1.3.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0-127.3.0.192.in-addr.arpa."},
3059 {"1.0-127.3.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
3060 };
3061
3062 test::DNSResponder dns;
3063 StartDns(dns, records);
3064 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3065
3066 for (const auto& address : {addr_slash, addr_hyphen}) {
3067 SCOPED_TRACE(address);
3068
3069 char host[NI_MAXHOST];
3070 sockaddr_in sin = {.sin_family = AF_INET};
3071 ASSERT_TRUE(inet_pton(AF_INET, address, &sin.sin_addr));
3072 int rv = getnameinfo((const sockaddr*)&sin, sizeof(sin), host, sizeof(host), nullptr, 0,
3073 NI_NAMEREQD);
3074 ASSERT_EQ(0, rv);
3075 EXPECT_STREQ("hello.example.com", host);
3076 }
3077}
3078
nuccachena26cc2a2018-07-17 18:07:23 +08003079TEST_F(ResolverTest, GetHostByName2_Dns64Synthesize) {
Xiao Ma09b71022018-12-11 17:56:32 +09003080 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08003081 constexpr char dns64_name[] = "ipv4only.arpa.";
3082 constexpr char host_name[] = "ipv4only.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09003083 const std::vector<DnsRecord> records = {
3084 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
3085 {host_name, ns_type::ns_t_a, "1.2.3.4"},
3086 };
nuccachena26cc2a2018-07-17 18:07:23 +08003087
Xiao Ma09b71022018-12-11 17:56:32 +09003088 test::DNSResponder dns(listen_addr);
3089 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08003090 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003091 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003092
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003093 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003094 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003095 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003096
3097 // Query an IPv4-only hostname. Expect that gets a synthesized address.
3098 struct hostent* result = gethostbyname2("ipv4only", AF_INET6);
3099 ASSERT_TRUE(result != nullptr);
3100 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3101 std::string result_str = ToString(result);
3102 EXPECT_EQ(result_str, "64:ff9b::102:304");
3103}
nuccachena26cc2a2018-07-17 18:07:23 +08003104
3105TEST_F(ResolverTest, GetHostByName2_DnsQueryWithHavingNat64Prefix) {
3106 constexpr char dns64_name[] = "ipv4only.arpa.";
3107 constexpr char host_name[] = "v4v6.example.com.";
nuccachena26cc2a2018-07-17 18:07:23 +08003108 constexpr char listen_addr[] = "::1";
Xiao Ma09b71022018-12-11 17:56:32 +09003109 const std::vector<DnsRecord> records = {
3110 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
3111 {host_name, ns_type::ns_t_a, "1.2.3.4"},
3112 {host_name, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
3113 };
3114
3115 test::DNSResponder dns(listen_addr);
3116 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08003117 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003118 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003119
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003120 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003121 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003122 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003123
3124 // IPv4 DNS query. Prefix should have no effect on it.
3125 struct hostent* result = gethostbyname2("v4v6", AF_INET);
3126 ASSERT_TRUE(result != nullptr);
3127 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3128 std::string result_str = ToString(result);
3129 EXPECT_EQ(result_str, "1.2.3.4");
3130 dns.clearQueries();
3131
3132 // IPv6 DNS query. Prefix should have no effect on it.
3133 result = gethostbyname2("v4v6", AF_INET6);
3134 ASSERT_TRUE(result != nullptr);
3135 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3136 result_str = ToString(result);
3137 EXPECT_EQ(result_str, "2001:db8::102:304");
3138}
3139
3140TEST_F(ResolverTest, GetHostByName2_Dns64QuerySpecialUseIPv4Addresses) {
3141 constexpr char THIS_NETWORK[] = "this_network";
3142 constexpr char LOOPBACK[] = "loopback";
3143 constexpr char LINK_LOCAL[] = "link_local";
3144 constexpr char MULTICAST[] = "multicast";
3145 constexpr char LIMITED_BROADCAST[] = "limited_broadcast";
3146
3147 constexpr char ADDR_THIS_NETWORK[] = "0.0.0.1";
3148 constexpr char ADDR_LOOPBACK[] = "127.0.0.1";
3149 constexpr char ADDR_LINK_LOCAL[] = "169.254.0.1";
3150 constexpr char ADDR_MULTICAST[] = "224.0.0.1";
3151 constexpr char ADDR_LIMITED_BROADCAST[] = "255.255.255.255";
3152
3153 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08003154 constexpr char dns64_name[] = "ipv4only.arpa.";
3155
Xiao Ma09b71022018-12-11 17:56:32 +09003156 test::DNSResponder dns(listen_addr);
3157 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
nuccachena26cc2a2018-07-17 18:07:23 +08003158 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003159 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003160
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003161 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003162 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003163 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003164
Luke Huangf8215372019-11-22 11:53:41 +08003165 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08003166 static const struct TestConfig {
3167 std::string name;
3168 std::string addr;
3169
3170 std::string asHostName() const {
Luke Huangf8215372019-11-22 11:53:41 +08003171 return StringPrintf("%s.example.com.", name.c_str());
nuccachena26cc2a2018-07-17 18:07:23 +08003172 }
3173 } testConfigs[]{
3174 {THIS_NETWORK, ADDR_THIS_NETWORK},
3175 {LOOPBACK, ADDR_LOOPBACK},
3176 {LINK_LOCAL, ADDR_LINK_LOCAL},
3177 {MULTICAST, ADDR_MULTICAST},
3178 {LIMITED_BROADCAST, ADDR_LIMITED_BROADCAST}
3179 };
Luke Huangf8215372019-11-22 11:53:41 +08003180 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08003181
3182 for (const auto& config : testConfigs) {
3183 const std::string testHostName = config.asHostName();
3184 SCOPED_TRACE(testHostName);
3185
3186 const char* host_name = testHostName.c_str();
3187 dns.addMapping(host_name, ns_type::ns_t_a, config.addr.c_str());
3188
3189 struct hostent* result = gethostbyname2(config.name.c_str(), AF_INET6);
3190 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3191
3192 // In AF_INET6 case, don't synthesize special use IPv4 address.
3193 // Expect to have no answer
3194 EXPECT_EQ(nullptr, result);
3195
3196 dns.clearQueries();
3197 }
Bernie Innocenti2fef2b82018-12-20 15:56:40 +09003198}
Mike Yuf14e1a92019-05-10 13:54:58 +08003199
3200TEST_F(ResolverTest, PrefixDiscoveryBypassTls) {
3201 constexpr char listen_addr[] = "::1";
3202 constexpr char cleartext_port[] = "53";
3203 constexpr char tls_port[] = "853";
3204 constexpr char dns64_name[] = "ipv4only.arpa.";
3205 const std::vector<std::string> servers = {listen_addr};
3206
3207 test::DNSResponder dns(listen_addr);
3208 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
3209 test::DnsTlsFrontend tls(listen_addr, tls_port, listen_addr, cleartext_port);
3210 ASSERT_TRUE(tls.startServer());
3211
3212 // Setup OPPORTUNISTIC mode and wait for the validation complete.
waynema0e73c2e2019-07-31 15:04:08 +08003213 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08003214 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yuf14e1a92019-05-10 13:54:58 +08003215 tls.clearQueries();
3216
3217 // Start NAT64 prefix discovery and wait for it complete.
3218 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003219 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
Mike Yuf14e1a92019-05-10 13:54:58 +08003220
3221 // Verify it bypassed TLS even though there's a TLS server available.
3222 EXPECT_EQ(0, tls.queries());
3223 EXPECT_EQ(1U, GetNumQueries(dns, dns64_name));
3224
3225 // Restart the testing network to reset the cache.
3226 mDnsClient.TearDown();
3227 mDnsClient.SetUp();
3228 dns.clearQueries();
3229
3230 // Setup STRICT mode and wait for the validation complete.
waynema0e73c2e2019-07-31 15:04:08 +08003231 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
3232 kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08003233 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yuf14e1a92019-05-10 13:54:58 +08003234 tls.clearQueries();
3235
3236 // Start NAT64 prefix discovery and wait for it to complete.
3237 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003238 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
Mike Yuf14e1a92019-05-10 13:54:58 +08003239
3240 // Verify it bypassed TLS despite STRICT mode.
3241 EXPECT_EQ(0, tls.queries());
3242 EXPECT_EQ(1U, GetNumQueries(dns, dns64_name));
3243}
Luke Huang9807e6b2019-05-20 16:17:12 +08003244
3245namespace {
3246
Luke Huang0d592bc2019-05-25 18:24:03 +08003247class ScopedSetNetworkForProcess {
3248 public:
3249 explicit ScopedSetNetworkForProcess(unsigned netId) {
3250 mStoredNetId = getNetworkForProcess();
3251 if (netId == mStoredNetId) return;
3252 EXPECT_EQ(0, setNetworkForProcess(netId));
3253 }
3254 ~ScopedSetNetworkForProcess() { EXPECT_EQ(0, setNetworkForProcess(mStoredNetId)); }
3255
3256 private:
3257 unsigned mStoredNetId;
3258};
3259
3260class ScopedSetNetworkForResolv {
3261 public:
3262 explicit ScopedSetNetworkForResolv(unsigned netId) { EXPECT_EQ(0, setNetworkForResolv(netId)); }
3263 ~ScopedSetNetworkForResolv() { EXPECT_EQ(0, setNetworkForResolv(NETID_UNSET)); }
3264};
3265
Luke Huang9807e6b2019-05-20 16:17:12 +08003266void sendCommand(int fd, const std::string& cmd) {
3267 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size() + 1));
3268 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size() + 1));
3269}
3270
3271int32_t readBE32(int fd) {
3272 int32_t tmp;
3273 int n = TEMP_FAILURE_RETRY(read(fd, &tmp, sizeof(tmp)));
3274 EXPECT_TRUE(n > 0);
3275 return ntohl(tmp);
3276}
3277
Luke Huang0d592bc2019-05-25 18:24:03 +08003278int readResponseCode(int fd) {
Luke Huang9807e6b2019-05-20 16:17:12 +08003279 char buf[4];
3280 int n = TEMP_FAILURE_RETRY(read(fd, &buf, sizeof(buf)));
3281 EXPECT_TRUE(n > 0);
3282 // The format of response code is that 4 bytes for the code & null.
3283 buf[3] = '\0';
3284 int result;
3285 EXPECT_TRUE(ParseInt(buf, &result));
3286 return result;
3287}
3288
Luke Huang0d592bc2019-05-25 18:24:03 +08003289bool checkAndClearUseLocalNameserversFlag(unsigned* netid) {
3290 if (netid == nullptr || ((*netid) & NETID_USE_LOCAL_NAMESERVERS) == 0) {
3291 return false;
3292 }
3293 *netid = (*netid) & ~NETID_USE_LOCAL_NAMESERVERS;
3294 return true;
3295}
3296
Luke Huangf8215372019-11-22 11:53:41 +08003297aidl::android::net::UidRangeParcel makeUidRangeParcel(int start, int stop) {
3298 aidl::android::net::UidRangeParcel res;
Luke Huang0d592bc2019-05-25 18:24:03 +08003299 res.start = start;
3300 res.stop = stop;
3301
3302 return res;
3303}
3304
3305void expectNetIdWithLocalNameserversFlag(unsigned netId) {
3306 unsigned dnsNetId = 0;
3307 EXPECT_EQ(0, getNetworkForDns(&dnsNetId));
3308 EXPECT_TRUE(checkAndClearUseLocalNameserversFlag(&dnsNetId));
3309 EXPECT_EQ(netId, static_cast<unsigned>(dnsNetId));
3310}
3311
3312void expectDnsNetIdEquals(unsigned netId) {
3313 unsigned dnsNetId = 0;
3314 EXPECT_EQ(0, getNetworkForDns(&dnsNetId));
3315 EXPECT_EQ(netId, static_cast<unsigned>(dnsNetId));
3316}
3317
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003318void expectDnsNetIdIsDefaultNetwork(INetd* netdService) {
Luke Huang0d592bc2019-05-25 18:24:03 +08003319 int currentNetid;
3320 EXPECT_TRUE(netdService->networkGetDefault(&currentNetid).isOk());
3321 expectDnsNetIdEquals(currentNetid);
3322}
3323
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003324void expectDnsNetIdWithVpn(INetd* netdService, unsigned vpnNetId, unsigned expectedNetId) {
Luke Huang0d592bc2019-05-25 18:24:03 +08003325 EXPECT_TRUE(netdService->networkCreateVpn(vpnNetId, false /* secure */).isOk());
3326 uid_t uid = getuid();
3327 // Add uid to VPN
3328 EXPECT_TRUE(netdService->networkAddUidRanges(vpnNetId, {makeUidRangeParcel(uid, uid)}).isOk());
3329 expectDnsNetIdEquals(expectedNetId);
3330 EXPECT_TRUE(netdService->networkDestroy(vpnNetId).isOk());
3331}
3332
Luke Huang9807e6b2019-05-20 16:17:12 +08003333} // namespace
3334
3335TEST_F(ResolverTest, getDnsNetId) {
3336 // We've called setNetworkForProcess in SetupOemNetwork, so reset to default first.
3337 setNetworkForProcess(NETID_UNSET);
Luke Huang0d592bc2019-05-25 18:24:03 +08003338
3339 expectDnsNetIdIsDefaultNetwork(mDnsClient.netdService());
3340 expectDnsNetIdWithVpn(mDnsClient.netdService(), TEST_VPN_NETID, TEST_VPN_NETID);
Luke Huang9807e6b2019-05-20 16:17:12 +08003341
3342 // Test with setNetworkForProcess
Luke Huang0d592bc2019-05-25 18:24:03 +08003343 {
3344 ScopedSetNetworkForProcess scopedSetNetworkForProcess(TEST_NETID);
3345 expectDnsNetIdEquals(TEST_NETID);
3346 }
3347
3348 // Test with setNetworkForProcess with NETID_USE_LOCAL_NAMESERVERS
3349 {
3350 ScopedSetNetworkForProcess scopedSetNetworkForProcess(TEST_NETID |
3351 NETID_USE_LOCAL_NAMESERVERS);
3352 expectNetIdWithLocalNameserversFlag(TEST_NETID);
3353 }
Luke Huang9807e6b2019-05-20 16:17:12 +08003354
3355 // Test with setNetworkForResolv
Luke Huang0d592bc2019-05-25 18:24:03 +08003356 {
3357 ScopedSetNetworkForResolv scopedSetNetworkForResolv(TEST_NETID);
3358 expectDnsNetIdEquals(TEST_NETID);
3359 }
3360
3361 // Test with setNetworkForResolv with NETID_USE_LOCAL_NAMESERVERS
3362 {
3363 ScopedSetNetworkForResolv scopedSetNetworkForResolv(TEST_NETID |
3364 NETID_USE_LOCAL_NAMESERVERS);
3365 expectNetIdWithLocalNameserversFlag(TEST_NETID);
3366 }
3367
3368 // Test with setNetworkForResolv under bypassable vpn
3369 {
3370 ScopedSetNetworkForResolv scopedSetNetworkForResolv(TEST_NETID);
3371 expectDnsNetIdWithVpn(mDnsClient.netdService(), TEST_VPN_NETID, TEST_NETID);
3372 }
Luke Huang9807e6b2019-05-20 16:17:12 +08003373
3374 // Create socket connected to DnsProxyListener
3375 int fd = dns_open_proxy();
3376 EXPECT_TRUE(fd > 0);
3377 unique_fd ufd(fd);
3378
3379 // Test command with wrong netId
3380 sendCommand(fd, "getdnsnetid abc");
Luke Huang0d592bc2019-05-25 18:24:03 +08003381 EXPECT_EQ(ResponseCode::DnsProxyQueryResult, readResponseCode(fd));
Luke Huang9807e6b2019-05-20 16:17:12 +08003382 EXPECT_EQ(-EINVAL, readBE32(fd));
3383
3384 // Test unsupported command
3385 sendCommand(fd, "getdnsnetidNotSupported");
3386 // Keep in sync with FrameworkListener.cpp (500, "Command not recognized")
Luke Huang0d592bc2019-05-25 18:24:03 +08003387 EXPECT_EQ(500, readResponseCode(fd));
Luke Huang9807e6b2019-05-20 16:17:12 +08003388}
Sehee Park2c118782019-05-07 13:02:45 +09003389
3390TEST_F(ResolverTest, BlockDnsQueryWithUidRule) {
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003391 // This test relies on blocking traffic on loopback, which xt_qtaguid does not do.
3392 // See aosp/358413 and b/34444781 for why.
3393 SKIP_IF_BPF_NOT_SUPPORTED;
3394
Sehee Park2c118782019-05-07 13:02:45 +09003395 constexpr char listen_addr1[] = "127.0.0.4";
3396 constexpr char listen_addr2[] = "::1";
3397 constexpr char host_name[] = "howdy.example.com.";
3398 const std::vector<DnsRecord> records = {
3399 {host_name, ns_type::ns_t_a, "1.2.3.4"},
3400 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
3401 };
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003402 INetd* netdService = mDnsClient.netdService();
Sehee Park2c118782019-05-07 13:02:45 +09003403
3404 test::DNSResponder dns1(listen_addr1);
3405 test::DNSResponder dns2(listen_addr2);
3406 StartDns(dns1, records);
3407 StartDns(dns2, records);
3408
3409 std::vector<std::string> servers = {listen_addr1, listen_addr2};
3410 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
3411 dns1.clearQueries();
3412 dns2.clearQueries();
3413
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003414 // Add drop rule for TEST_UID. Also enable the standby chain because it might not be enabled.
3415 // Unfortunately we cannot use FIREWALL_CHAIN_NONE, or custom iptables rules, for this purpose
3416 // because netd calls fchown() on the DNS query sockets, and "iptables -m owner" matches the
3417 // UID of the socket creator, not the UID set by fchown().
3418 //
3419 // TODO: migrate FIREWALL_CHAIN_NONE to eBPF as well.
3420 EXPECT_TRUE(netdService->firewallEnableChildChain(INetd::FIREWALL_CHAIN_STANDBY, true).isOk());
3421 EXPECT_TRUE(netdService
Sehee Park2c118782019-05-07 13:02:45 +09003422 ->firewallSetUidRule(INetd::FIREWALL_CHAIN_STANDBY, TEST_UID,
3423 INetd::FIREWALL_RULE_DENY)
3424 .isOk());
3425
3426 // Save uid
3427 int suid = getuid();
3428
3429 // Switch to TEST_UID
3430 EXPECT_TRUE(seteuid(TEST_UID) == 0);
3431
3432 // Dns Query
3433 int fd1 = resNetworkQuery(TEST_NETID, host_name, ns_c_in, ns_t_a, 0);
3434 int fd2 = resNetworkQuery(TEST_NETID, host_name, ns_c_in, ns_t_aaaa, 0);
3435 EXPECT_TRUE(fd1 != -1);
3436 EXPECT_TRUE(fd2 != -1);
3437
3438 uint8_t buf[MAXPACKET] = {};
3439 int rcode;
3440 int res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
3441 EXPECT_EQ(-ECONNREFUSED, res);
3442
3443 memset(buf, 0, MAXPACKET);
3444 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
3445 EXPECT_EQ(-ECONNREFUSED, res);
3446
3447 // Restore uid
3448 EXPECT_TRUE(seteuid(suid) == 0);
3449
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003450 // Remove drop rule for TEST_UID, and disable the standby chain.
3451 EXPECT_TRUE(netdService
Sehee Park2c118782019-05-07 13:02:45 +09003452 ->firewallSetUidRule(INetd::FIREWALL_CHAIN_STANDBY, TEST_UID,
3453 INetd::FIREWALL_RULE_ALLOW)
3454 .isOk());
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003455 EXPECT_TRUE(netdService->firewallEnableChildChain(INetd::FIREWALL_CHAIN_STANDBY, false).isOk());
Sehee Park2c118782019-05-07 13:02:45 +09003456}
Mike Yua772c202019-09-23 17:47:21 +08003457
Mike Yu40e67072019-10-09 21:14:09 +08003458namespace {
3459
3460const std::string kDotConnectTimeoutMsFlag(
3461 "persist.device_config.netd_native.dot_connect_timeout_ms");
3462
3463class ScopedSystemProperties {
3464 public:
3465 explicit ScopedSystemProperties(const std::string& key, const std::string& value)
3466 : mStoredKey(key) {
3467 mStoredValue = android::base::GetProperty(key, "");
3468 android::base::SetProperty(key, value);
3469 }
3470 ~ScopedSystemProperties() { android::base::SetProperty(mStoredKey, mStoredValue); }
3471
3472 private:
3473 std::string mStoredKey;
3474 std::string mStoredValue;
3475};
3476
3477} // namespace
3478
Mike Yua772c202019-09-23 17:47:21 +08003479TEST_F(ResolverTest, ConnectTlsServerTimeout) {
Mike Yu40e67072019-10-09 21:14:09 +08003480 constexpr int expectedTimeout = 1000;
3481 constexpr char hostname1[] = "query1.example.com.";
3482 constexpr char hostname2[] = "query2.example.com.";
Mike Yua772c202019-09-23 17:47:21 +08003483 const std::vector<DnsRecord> records = {
Mike Yu40e67072019-10-09 21:14:09 +08003484 {hostname1, ns_type::ns_t_a, "1.2.3.4"},
3485 {hostname2, ns_type::ns_t_a, "1.2.3.5"},
Mike Yua772c202019-09-23 17:47:21 +08003486 };
3487
3488 test::DNSResponder dns;
3489 StartDns(dns, records);
Mike Yu40e67072019-10-09 21:14:09 +08003490 test::DnsTlsFrontend tls;
Mike Yua772c202019-09-23 17:47:21 +08003491 ASSERT_TRUE(tls.startServer());
3492
Mike Yu40e67072019-10-09 21:14:09 +08003493 // The resolver will adjust the timeout value to 1000ms since the value is too small.
3494 ScopedSystemProperties scopedSystemProperties(kDotConnectTimeoutMsFlag, "100");
Mike Yua772c202019-09-23 17:47:21 +08003495
Mike Yu40e67072019-10-09 21:14:09 +08003496 // Set up resolver to opportunistic mode with the default configuration.
Luke Huangf8215372019-11-22 11:53:41 +08003497 const aidl::android::net::ResolverParamsParcel parcel =
3498 DnsResponderClient::GetDefaultResolverParamsParcel();
Mike Yu40e67072019-10-09 21:14:09 +08003499 ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
Mike Yua772c202019-09-23 17:47:21 +08003500 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
3501 dns.clearQueries();
3502 tls.clearQueries();
3503
3504 // The server becomes unresponsive to the handshake request.
3505 tls.setHangOnHandshakeForTesting(true);
3506
3507 // Expect the things happening in getaddrinfo():
3508 // 1. Connect to the private DNS server.
3509 // 2. SSL handshake times out.
3510 // 3. Fallback to UDP transport, and then get the answer.
Mike Yu40e67072019-10-09 21:14:09 +08003511 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
3512 auto [result, timeTakenMs] = safe_getaddrinfo_time_taken(hostname1, nullptr, hints);
Mike Yua772c202019-09-23 17:47:21 +08003513
Mike Yu40e67072019-10-09 21:14:09 +08003514 EXPECT_NE(nullptr, result);
Mike Yua772c202019-09-23 17:47:21 +08003515 EXPECT_EQ(0, tls.queries());
Mike Yu40e67072019-10-09 21:14:09 +08003516 EXPECT_EQ(1U, GetNumQueries(dns, hostname1));
3517 EXPECT_EQ(records.at(0).addr, ToString(result));
Mike Yua772c202019-09-23 17:47:21 +08003518
Mike Yu40e67072019-10-09 21:14:09 +08003519 // A loose upper bound is set by adding 2000ms buffer time. Theoretically, getaddrinfo()
3520 // should just take a bit more than expetTimeout milliseconds.
3521 EXPECT_GE(timeTakenMs, expectedTimeout);
3522 EXPECT_LE(timeTakenMs, expectedTimeout + 2000);
3523
3524 // Set the server to be responsive. Verify that the resolver will attempt to reconnect
3525 // to the server and then get the result within the timeout.
3526 tls.setHangOnHandshakeForTesting(false);
3527 std::tie(result, timeTakenMs) = safe_getaddrinfo_time_taken(hostname2, nullptr, hints);
3528
3529 EXPECT_NE(nullptr, result);
3530 EXPECT_EQ(1, tls.queries());
3531 EXPECT_EQ(1U, GetNumQueries(dns, hostname2));
3532 EXPECT_EQ(records.at(1).addr, ToString(result));
3533
3534 EXPECT_LE(timeTakenMs, expectedTimeout);
Mike Yua772c202019-09-23 17:47:21 +08003535}
Hungming Chenbb90ab32019-10-28 18:20:31 +08003536
Ken Chen766feae2019-10-30 15:13:44 +08003537TEST_F(ResolverTest, FlushNetworkCache) {
Luke Huang0b5a76c2019-11-23 03:00:00 +08003538 SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsClient.resolvService(), 4);
Ken Chen766feae2019-10-30 15:13:44 +08003539 test::DNSResponder dns;
3540 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3541 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3542
3543 const hostent* result = gethostbyname("hello");
3544 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
3545
3546 // get result from cache
3547 result = gethostbyname("hello");
3548 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
3549
3550 EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk());
3551
3552 result = gethostbyname("hello");
3553 EXPECT_EQ(2U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
3554}
3555
3556TEST_F(ResolverTest, FlushNetworkCache_random) {
Luke Huang0b5a76c2019-11-23 03:00:00 +08003557 SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsClient.resolvService(), 4);
Ken Chen766feae2019-10-30 15:13:44 +08003558 constexpr int num_flush = 10;
3559 constexpr int num_queries = 20;
3560 test::DNSResponder dns;
3561 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3562 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3563 const addrinfo hints = {.ai_family = AF_INET};
3564
3565 std::thread t([this]() {
3566 for (int i = 0; i < num_flush; ++i) {
3567 unsigned delay = arc4random_uniform(10 * 1000); // 10ms
3568 usleep(delay);
3569 EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk());
3570 }
3571 });
3572
3573 for (int i = 0; i < num_queries; ++i) {
3574 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3575 EXPECT_TRUE(result != nullptr);
3576 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3577 }
3578 t.join();
3579}
3580
3581// flush cache while one query is wait-for-response, another is pending.
3582TEST_F(ResolverTest, FlushNetworkCache_concurrent) {
Luke Huang0b5a76c2019-11-23 03:00:00 +08003583 SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsClient.resolvService(), 4);
Ken Chen766feae2019-10-30 15:13:44 +08003584 const char* listen_addr1 = "127.0.0.9";
3585 const char* listen_addr2 = "127.0.0.10";
3586 test::DNSResponder dns1(listen_addr1);
3587 test::DNSResponder dns2(listen_addr2);
3588 StartDns(dns1, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3589 StartDns(dns2, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3590 addrinfo hints = {.ai_family = AF_INET};
3591
3592 // step 1: set server#1 into deferred responding mode
3593 dns1.setDeferredResp(true);
3594 std::thread t1([&listen_addr1, &hints, this]() {
3595 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr1}));
3596 // step 3: query
3597 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3598 // step 9: check result
3599 EXPECT_TRUE(result != nullptr);
3600 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3601 });
3602
3603 // step 2: wait for the query to reach the server
3604 while (GetNumQueries(dns1, kHelloExampleCom) == 0) {
3605 usleep(1000); // 1ms
3606 }
3607
3608 std::thread t2([&listen_addr2, &hints, &dns2, this]() {
3609 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr2}));
3610 // step 5: query (should be blocked in resolver)
3611 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3612 // step 7: check result
3613 EXPECT_TRUE(result != nullptr);
3614 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3615 EXPECT_EQ(1U, GetNumQueriesForType(dns2, ns_type::ns_t_a, kHelloExampleCom));
3616 });
3617
3618 // step 4: wait a bit for the 2nd query to enter pending state
3619 usleep(100 * 1000); // 100ms
3620 // step 6: flush cache (will unblock pending queries)
3621 EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk());
3622 t2.join();
3623
3624 // step 8: resume server#1
3625 dns1.setDeferredResp(false);
3626 t1.join();
3627
3628 // step 10: verify if result is correctly cached
3629 dns2.clearQueries();
3630 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3631 EXPECT_EQ(0U, GetNumQueries(dns2, kHelloExampleCom));
3632 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3633}
3634
Hungming Chenbb90ab32019-10-28 18:20:31 +08003635// Parameterized tests.
3636// TODO: Merge the existing tests as parameterized test if possible.
3637// TODO: Perhaps move parameterized tests to an independent file.
3638enum class CallType { GETADDRINFO, GETHOSTBYNAME };
3639class ResolverParameterizedTest : public ResolverTest,
Hungming Chen63779052019-10-30 15:06:13 +08003640 public testing::WithParamInterface<CallType> {
3641 protected:
3642 void VerifyQueryHelloExampleComV4(const test::DNSResponder& dns, const CallType calltype) {
3643 if (calltype == CallType::GETADDRINFO) {
3644 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
3645 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3646 ASSERT_TRUE(result != nullptr);
3647 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3648 } else if (calltype == CallType::GETHOSTBYNAME) {
3649 const hostent* result = gethostbyname("hello");
3650 ASSERT_TRUE(result != nullptr);
3651 ASSERT_EQ(4, result->h_length);
3652 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
3653 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3654 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
3655 } else {
3656 FAIL() << "Unsupported call type: " << static_cast<uint32_t>(calltype);
3657 }
3658 EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom));
3659 }
3660};
Hungming Chenbb90ab32019-10-28 18:20:31 +08003661
Hungming Chen63779052019-10-30 15:06:13 +08003662INSTANTIATE_TEST_SUITE_P(QueryCallTest, ResolverParameterizedTest,
Hungming Chenbb90ab32019-10-28 18:20:31 +08003663 testing::Values(CallType::GETADDRINFO, CallType::GETHOSTBYNAME),
3664 [](const testing::TestParamInfo<CallType>& info) {
Hungming Chenbb90ab32019-10-28 18:20:31 +08003665 switch (info.param) {
3666 case CallType::GETADDRINFO:
Hungming Chen63779052019-10-30 15:06:13 +08003667 return "GetAddrInfo";
Hungming Chenbb90ab32019-10-28 18:20:31 +08003668 case CallType::GETHOSTBYNAME:
Hungming Chen63779052019-10-30 15:06:13 +08003669 return "GetHostByName";
Hungming Chenbb90ab32019-10-28 18:20:31 +08003670 default:
Hungming Chen63779052019-10-30 15:06:13 +08003671 return "InvalidParameter"; // Should not happen.
Hungming Chenbb90ab32019-10-28 18:20:31 +08003672 }
Hungming Chenbb90ab32019-10-28 18:20:31 +08003673 });
3674
3675TEST_P(ResolverParameterizedTest, AuthoritySectionAndAdditionalSection) {
3676 // DNS response may have more information in authority section and additional section.
3677 // Currently, getanswer() of packages/modules/DnsResolver/getaddrinfo.cpp doesn't parse the
3678 // content of authority section and additional section. Test these sections if they crash
3679 // the resolver, just in case. See also RFC 1035 section 4.1.
3680 const auto& calltype = GetParam();
3681 test::DNSHeader header(kDefaultDnsHeader);
3682
3683 // Create a DNS response which has a authoritative nameserver record in authority
3684 // section and its relevant address record in additional section.
3685 //
3686 // Question
3687 // hello.example.com. IN A
3688 // Answer
3689 // hello.example.com. IN A 1.2.3.4
3690 // Authority:
3691 // hello.example.com. IN NS ns1.example.com.
3692 // Additional:
3693 // ns1.example.com. IN A 5.6.7.8
3694 //
3695 // A response may have only question, answer, and authority section. Current testing response
3696 // should be able to cover this condition.
3697
3698 // Question section.
3699 test::DNSQuestion question{
3700 .qname = {.name = kHelloExampleCom},
3701 .qtype = ns_type::ns_t_a,
3702 .qclass = ns_c_in,
3703 };
3704 header.questions.push_back(std::move(question));
3705
3706 // Answer section.
3707 test::DNSRecord recordAnswer{
3708 .name = {.name = kHelloExampleCom},
3709 .rtype = ns_type::ns_t_a,
3710 .rclass = ns_c_in,
3711 .ttl = 0, // no cache
3712 };
Hungming Chen63779052019-10-30 15:06:13 +08003713 EXPECT_TRUE(test::DNSResponder::fillRdata(kHelloExampleComAddrV4, recordAnswer));
Hungming Chenbb90ab32019-10-28 18:20:31 +08003714 header.answers.push_back(std::move(recordAnswer));
3715
3716 // Authority section.
3717 test::DNSRecord recordAuthority{
3718 .name = {.name = kHelloExampleCom},
3719 .rtype = ns_type::ns_t_ns,
3720 .rclass = ns_c_in,
3721 .ttl = 0, // no cache
3722 };
3723 EXPECT_TRUE(test::DNSResponder::fillRdata("ns1.example.com.", recordAuthority));
3724 header.authorities.push_back(std::move(recordAuthority));
3725
3726 // Additional section.
3727 test::DNSRecord recordAdditional{
3728 .name = {.name = "ns1.example.com."},
3729 .rtype = ns_type::ns_t_a,
3730 .rclass = ns_c_in,
3731 .ttl = 0, // no cache
3732 };
3733 EXPECT_TRUE(test::DNSResponder::fillRdata("5.6.7.8", recordAdditional));
3734 header.additionals.push_back(std::move(recordAdditional));
3735
3736 // Start DNS server.
3737 test::DNSResponder dns(test::DNSResponder::MappingType::DNS_HEADER);
3738 dns.addMappingDnsHeader(kHelloExampleCom, ns_type::ns_t_a, header);
3739 ASSERT_TRUE(dns.startServer());
3740 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3741 dns.clearQueries();
3742
3743 // Expect that get the address and the resolver doesn't crash.
Hungming Chen63779052019-10-30 15:06:13 +08003744 VerifyQueryHelloExampleComV4(dns, calltype);
3745}
3746
3747TEST_P(ResolverParameterizedTest, MessageCompression) {
3748 const auto& calltype = GetParam();
3749
3750 // The response with compressed domain name by a pointer. See RFC 1035 section 4.1.4.
3751 //
3752 // Ignoring the other fields of the message, the domain name of question section and answer
3753 // section are presented as:
3754 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3755 // 12 | 5 | h |
3756 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3757 // 14 | e | l |
3758 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3759 // 16 | l | o |
3760 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3761 // 18 | 7 | e |
3762 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3763 // 20 | x | a |
3764 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3765 // 22 | m | p |
3766 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3767 // 24 | l | e |
3768 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3769 // 26 | 3 | c |
3770 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3771 // 28 | o | m |
3772 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3773 // 30 | 0 | ... |
3774 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3775 //
3776 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3777 // 35 | 1 1| 12 |
3778 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3779 const std::vector<uint8_t> kResponseAPointer = {
3780 /* Header */
3781 0x00, 0x00, /* Transaction ID: 0x0000 */
3782 0x81, 0x80, /* Flags: qr rd ra */
3783 0x00, 0x01, /* Questions: 1 */
3784 0x00, 0x01, /* Answer RRs: 1 */
3785 0x00, 0x00, /* Authority RRs: 0 */
3786 0x00, 0x00, /* Additional RRs: 0 */
3787 /* Queries */
3788 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
3789 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */
3790 0x00, 0x01, /* Type: A */
3791 0x00, 0x01, /* Class: IN */
3792 /* Answers */
3793 0xc0, 0x0c, /* Name: hello.example.com (a pointer) */
3794 0x00, 0x01, /* Type: A */
3795 0x00, 0x01, /* Class: IN */
3796 0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */
3797 0x00, 0x04, /* Data length: 4 */
3798 0x01, 0x02, 0x03, 0x04 /* Address: 1.2.3.4 */
3799 };
3800
3801 // The response with compressed domain name by a sequence of labels ending with a pointer. See
3802 // RFC 1035 section 4.1.4.
3803 //
3804 // Ignoring the other fields of the message, the domain name of question section and answer
3805 // section are presented as:
3806 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3807 // 12 | 5 | h |
3808 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3809 // 14 | e | l |
3810 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3811 // 16 | l | o |
3812 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3813 // 18 | 7 | e |
3814 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3815 // 20 | x | a |
3816 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3817 // 22 | m | p |
3818 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3819 // 24 | l | e |
3820 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3821 // 26 | 3 | c |
3822 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3823 // 28 | o | m |
3824 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3825 // 30 | 0 | ... |
3826 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3827 //
3828 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3829 // 35 | 5 | h |
3830 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3831 // 37 | e | l |
3832 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3833 // 39 | l | o |
3834 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3835 // 41 | 1 1| 18 |
3836 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3837 const std::vector<uint8_t> kResponseLabelEndingWithAPointer = {
3838 /* Header */
3839 0x00, 0x00, /* Transaction ID: 0x0000 */
3840 0x81, 0x80, /* Flags: qr rd ra */
3841 0x00, 0x01, /* Questions: 1 */
3842 0x00, 0x01, /* Answer RRs: 1 */
3843 0x00, 0x00, /* Authority RRs: 0 */
3844 0x00, 0x00, /* Additional RRs: 0 */
3845 /* Queries */
3846 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
3847 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */
3848 0x00, 0x01, /* Type: A */
3849 0x00, 0x01, /* Class: IN */
3850 /* Answers */
3851 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0xc0,
3852 0x12, /* Name: hello.example.com (a label ending with a pointer) */
3853 0x00, 0x01, /* Type: A */
3854 0x00, 0x01, /* Class: IN */
3855 0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */
3856 0x00, 0x04, /* Data length: 4 */
3857 0x01, 0x02, 0x03, 0x04 /* Address: 1.2.3.4 */
3858 };
3859
3860 for (const auto& response : {kResponseAPointer, kResponseLabelEndingWithAPointer}) {
3861 SCOPED_TRACE(StringPrintf("Hex dump: %s", toHex(makeSlice(response)).c_str()));
3862
3863 test::DNSResponder dns(test::DNSResponder::MappingType::BINARY_PACKET);
3864 dns.addMappingBinaryPacket(kHelloExampleComQueryV4, response);
3865 StartDns(dns, {});
3866 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3867
3868 // Expect no cache because the TTL of testing responses are 0.
3869 VerifyQueryHelloExampleComV4(dns, calltype);
Hungming Chenbb90ab32019-10-28 18:20:31 +08003870 }
Mike Yu40e67072019-10-09 21:14:09 +08003871}