blob: 8b05cda4fdb7e07daf3b48905101f2dfc6c27b38 [file] [log] [blame]
Ken Chenb9fa2062018-11-13 21:51:13 +08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
Lorenzo Colitti0a8b4aa2019-06-26 22:31:03 +090010 * Unless required by applicable law or agreed to in writing, software
Ken Chenb9fa2062018-11-13 21:51:13 +080011 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
Bernie Innocenti3952ccc2019-03-03 19:39:53 +090018#define LOG_TAG "resolv_integration_test"
Ken Chenb9fa2062018-11-13 21:51:13 +080019
Hungming Chen5bf09772019-04-25 11:16:13 +080020#include <android-base/logging.h>
Bernie Innocenti41b82c42019-06-05 22:38:25 +090021#include <android-base/parseint.h>
Mike Yu40e67072019-10-09 21:14:09 +080022#include <android-base/properties.h>
Bernie Innocenti41b82c42019-06-05 22:38:25 +090023#include <android-base/stringprintf.h>
24#include <android-base/unique_fd.h>
25#include <android/multinetwork.h> // ResNsendFlags
Ken Chenb9fa2062018-11-13 21:51:13 +080026#include <arpa/inet.h>
Luke Huang94b10b92018-11-21 20:13:38 +080027#include <arpa/nameser.h>
Hungming Chene8f970c2019-04-10 17:34:06 +080028#include <binder/ProcessState.h>
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +090029#include <bpf/BpfUtils.h>
Bernie Innocenti41b82c42019-06-05 22:38:25 +090030#include <cutils/sockets.h>
31#include <gmock/gmock-matchers.h>
32#include <gtest/gtest.h>
Ken Chenb9fa2062018-11-13 21:51:13 +080033#include <netdb.h>
Luke Huang9d2d25b2019-06-14 00:34:05 +080034#include <netdutils/InternetAddresses.h>
Luke Huang579ddc72019-06-14 00:59:39 +080035#include <netdutils/NetworkConstants.h> // SHA256_SIZE
Luke Huang9d2d25b2019-06-14 00:34:05 +080036#include <netdutils/ResponseCode.h>
Hungming Chen63779052019-10-30 15:06:13 +080037#include <netdutils/Slice.h>
Luke Huang9d2d25b2019-06-14 00:34:05 +080038#include <netdutils/SocketOption.h>
Mike Yu40e67072019-10-09 21:14:09 +080039#include <netdutils/Stopwatch.h>
Luke Huang94b10b92018-11-21 20:13:38 +080040#include <netinet/in.h>
41#include <poll.h> /* poll */
Bernie Innocenti41b82c42019-06-05 22:38:25 +090042#include <private/android_filesystem_config.h>
Luke Huang94b10b92018-11-21 20:13:38 +080043#include <resolv.h>
Ken Chenb9fa2062018-11-13 21:51:13 +080044#include <stdarg.h>
Ken Chenb9fa2062018-11-13 21:51:13 +080045#include <stdlib.h>
Luke Huang94b10b92018-11-21 20:13:38 +080046#include <sys/socket.h>
47#include <sys/un.h>
Ken Chenb9fa2062018-11-13 21:51:13 +080048#include <unistd.h>
49
50#include <algorithm>
51#include <chrono>
52#include <iterator>
53#include <numeric>
54#include <thread>
55
Luke Huangf8215372019-11-22 11:53:41 +080056#include <aidl/android/net/IDnsResolver.h>
57#include <android/binder_manager.h>
58#include <android/binder_process.h>
Bernie Innocenti41b82c42019-06-05 22:38:25 +090059#include "NetdClient.h"
Bernie Innocenti41b82c42019-06-05 22:38:25 +090060#include "ResolverStats.h"
Luke Huangf8215372019-11-22 11:53:41 +080061#include "netid_client.h" // NETID_UNSET
62#include "params.h" // MAXNS
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +090063#include "test_utils.h"
Hungming Chene8f970c2019-04-10 17:34:06 +080064#include "tests/dns_metrics_listener/dns_metrics_listener.h"
chenbruceb43ec752019-07-24 20:19:41 +080065#include "tests/dns_responder/dns_responder.h"
Luke Huangf8215372019-11-22 11:53:41 +080066#include "tests/dns_responder/dns_responder_client_ndk.h"
Hungming Chenc6556622019-10-02 16:01:07 +080067#include "tests/dns_responder/dns_tls_certificate.h"
chenbruceb43ec752019-07-24 20:19:41 +080068#include "tests/dns_responder/dns_tls_frontend.h"
Luke Huangfde82482019-06-04 01:04:53 +080069#include "tests/resolv_test_utils.h"
Ken Chenb9fa2062018-11-13 21:51:13 +080070
Luke Huang0d592bc2019-05-25 18:24:03 +080071// Valid VPN netId range is 100 ~ 65535
72constexpr int TEST_VPN_NETID = 65502;
Luke Huang94b10b92018-11-21 20:13:38 +080073constexpr int MAXPACKET = (8 * 1024);
Ken Chenb9fa2062018-11-13 21:51:13 +080074
Sehee Park2c118782019-05-07 13:02:45 +090075// Use maximum reserved appId for applications to avoid conflict with existing uids.
76static const int TEST_UID = 99999;
77
Ken Chenb9fa2062018-11-13 21:51:13 +080078// Semi-public Bionic hook used by the NDK (frameworks/base/native/android/net.c)
79// Tested here for convenience.
80extern "C" int android_getaddrinfofornet(const char* hostname, const char* servname,
81 const addrinfo* hints, unsigned netid, unsigned mark,
82 struct addrinfo** result);
83
Luke Huang70070852019-11-25 18:25:50 +080084using aidl::android::net::IDnsResolver;
Luke Huangf8215372019-11-22 11:53:41 +080085using aidl::android::net::INetd;
Mike Yu8ac63402019-12-02 15:28:38 +080086using aidl::android::net::ResolverParamsParcel;
Luke Huang9807e6b2019-05-20 16:17:12 +080087using android::base::ParseInt;
Ken Chenb9fa2062018-11-13 21:51:13 +080088using android::base::StringPrintf;
Luke Huang9807e6b2019-05-20 16:17:12 +080089using android::base::unique_fd;
Ken Chenb9fa2062018-11-13 21:51:13 +080090using android::net::ResolverStats;
Hungming Chene8f970c2019-04-10 17:34:06 +080091using android::net::metrics::DnsMetricsListener;
Ken Chenb9fa2062018-11-13 21:51:13 +080092using android::netdutils::enableSockopt;
Hungming Chen63779052019-10-30 15:06:13 +080093using android::netdutils::makeSlice;
Luke Huang9807e6b2019-05-20 16:17:12 +080094using android::netdutils::ResponseCode;
Luke Huang9d2d25b2019-06-14 00:34:05 +080095using android::netdutils::ScopedAddrinfo;
Mike Yu40e67072019-10-09 21:14:09 +080096using android::netdutils::Stopwatch;
Hungming Chen63779052019-10-30 15:06:13 +080097using android::netdutils::toHex;
Ken Chenb9fa2062018-11-13 21:51:13 +080098
99// TODO: move into libnetdutils?
100namespace {
Luke Huangfde82482019-06-04 01:04:53 +0800101
Ken Chenb9fa2062018-11-13 21:51:13 +0800102ScopedAddrinfo safe_getaddrinfo(const char* node, const char* service,
103 const struct addrinfo* hints) {
104 addrinfo* result = nullptr;
105 if (getaddrinfo(node, service, hints, &result) != 0) {
106 result = nullptr; // Should already be the case, but...
107 }
108 return ScopedAddrinfo(result);
109}
Luke Huangfde82482019-06-04 01:04:53 +0800110
Mike Yu40e67072019-10-09 21:14:09 +0800111std::pair<ScopedAddrinfo, int> safe_getaddrinfo_time_taken(const char* node, const char* service,
112 const addrinfo& hints) {
113 Stopwatch s;
114 ScopedAddrinfo result = safe_getaddrinfo(node, service, &hints);
115 return {std::move(result), s.timeTakenUs() / 1000};
116}
117
Ken Chenb9fa2062018-11-13 21:51:13 +0800118} // namespace
119
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900120class ResolverTest : public ::testing::Test {
Hungming Chene8f970c2019-04-10 17:34:06 +0800121 public:
Hungming Chen5bf09772019-04-25 11:16:13 +0800122 static void SetUpTestCase() {
123 // Get binder service.
124 // Note that |mDnsClient| is not used for getting binder service in this static function.
125 // The reason is that wants to keep |mDnsClient| as a non-static data member. |mDnsClient|
126 // which sets up device network configuration could be independent from every test.
Luke Huangf8215372019-11-22 11:53:41 +0800127 // TODO: Perhaps add a static function in resolv_test_binder_utils.{cpp,h} to get binder
128 // service.
129
130 AIBinder* binder = AServiceManager_getService("dnsresolver");
131 ndk::SpAIBinder resolvBinder = ndk::SpAIBinder(binder);
132 auto resolvService = aidl::android::net::IDnsResolver::fromBinder(resolvBinder);
Hungming Chen5bf09772019-04-25 11:16:13 +0800133 ASSERT_NE(nullptr, resolvService.get());
134
135 // Subscribe the death recipient to the service IDnsResolver for detecting Netd death.
Luke Huang70070852019-11-25 18:25:50 +0800136 // GTEST assertion macros are not invoked for generating a test failure in the death
137 // recipient because the macros can't indicate failed test if Netd died between tests.
138 // Moreover, continuing testing may have no meaningful after Netd death. Therefore, the
139 // death recipient aborts process by GTEST_LOG_(FATAL) once Netd died.
Luke Huangf8215372019-11-22 11:53:41 +0800140 sResolvDeathRecipient = AIBinder_DeathRecipient_new([](void*) {
141 constexpr char errorMessage[] = "Netd died";
142 LOG(ERROR) << errorMessage;
143 GTEST_LOG_(FATAL) << errorMessage;
144 });
145 ASSERT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, sResolvDeathRecipient, nullptr));
Hungming Chen5bf09772019-04-25 11:16:13 +0800146
147 // Subscribe the DNS listener for verifying DNS metrics event contents.
Luke Huangf8215372019-11-22 11:53:41 +0800148 sDnsMetricsListener = ndk::SharedRefBase::make<DnsMetricsListener>(
149 TEST_NETID /*monitor specific network*/);
Hungming Chen5bf09772019-04-25 11:16:13 +0800150 ASSERT_TRUE(resolvService->registerEventListener(sDnsMetricsListener).isOk());
151
152 // Start the binder thread pool for listening DNS metrics events and receiving death
153 // recipient.
Luke Huangf8215372019-11-22 11:53:41 +0800154 ABinderProcess_startThreadPool();
Hungming Chene8f970c2019-04-10 17:34:06 +0800155 }
Luke Huangf8215372019-11-22 11:53:41 +0800156 static void TearDownTestCase() { AIBinder_DeathRecipient_delete(sResolvDeathRecipient); }
Hungming Chene8f970c2019-04-10 17:34:06 +0800157
Ken Chenb9fa2062018-11-13 21:51:13 +0800158 protected:
Xiao Ma09b71022018-12-11 17:56:32 +0900159 struct DnsRecord {
160 std::string host_name; // host name
161 ns_type type; // record type
162 std::string addr; // ipv4/v6 address
163 };
164
Hungming Chen5bf09772019-04-25 11:16:13 +0800165 void SetUp() { mDnsClient.SetUp(); }
Mike Yu960243d2020-01-17 19:02:15 +0800166 void TearDown() {
167 // Ensure the dump works at the end of each test.
168 DumpResolverService();
169
170 mDnsClient.TearDown();
171 }
nuccachena26cc2a2018-07-17 18:07:23 +0800172
Xiao Ma09b71022018-12-11 17:56:32 +0900173 void StartDns(test::DNSResponder& dns, const std::vector<DnsRecord>& records) {
174 for (const auto& r : records) {
175 dns.addMapping(r.host_name, r.type, r.addr);
176 }
177
178 ASSERT_TRUE(dns.startServer());
179 dns.clearQueries();
180 }
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900181
Mike Yu960243d2020-01-17 19:02:15 +0800182 void DumpResolverService() {
183 unique_fd fd(open("/dev/null", O_WRONLY));
184 EXPECT_EQ(mDnsClient.resolvService()->dump(fd, nullptr, 0), 0);
185
186 const char* querylogCmd[] = {"querylog"}; // Keep it sync with DnsQueryLog::DUMP_KEYWORD.
187 EXPECT_EQ(mDnsClient.resolvService()->dump(fd, querylogCmd, std::size(querylogCmd)), 0);
188 }
189
Hungming Chene8f970c2019-04-10 17:34:06 +0800190 bool WaitForNat64Prefix(ExpectNat64PrefixStatus status,
191 std::chrono::milliseconds timeout = std::chrono::milliseconds(1000)) {
Hungming Chen5bf09772019-04-25 11:16:13 +0800192 return sDnsMetricsListener->waitForNat64Prefix(status, timeout);
Hungming Chene8f970c2019-04-10 17:34:06 +0800193 }
194
Mike Yu724f77d2019-08-16 11:14:50 +0800195 bool WaitForPrivateDnsValidation(std::string serverAddr, bool validated) {
196 return sDnsMetricsListener->waitForPrivateDnsValidation(serverAddr, validated);
197 }
198
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900199 DnsResponderClient mDnsClient;
Xiao Ma09b71022018-12-11 17:56:32 +0900200
Hungming Chen5bf09772019-04-25 11:16:13 +0800201 // Use a shared static DNS listener for all tests to avoid registering lots of listeners
202 // which may be released late until process terminated. Currently, registered DNS listener
203 // is removed by binder death notification which is fired when the process hosting an
204 // IBinder has gone away. If every test in ResolverTest registers its DNS listener, Netd
205 // may temporarily hold lots of dead listeners until the unit test process terminates.
206 // TODO: Perhaps add an unregistering listener binder call or fork a listener process which
207 // could be terminated earlier.
Luke Huangf8215372019-11-22 11:53:41 +0800208 static std::shared_ptr<DnsMetricsListener>
209 sDnsMetricsListener; // Initialized in SetUpTestCase.
Hungming Chen5bf09772019-04-25 11:16:13 +0800210
211 // Use a shared static death recipient to monitor the service death. The static death
212 // recipient could monitor the death not only during the test but also between tests.
Luke Huangf8215372019-11-22 11:53:41 +0800213 static AIBinder_DeathRecipient* sResolvDeathRecipient; // Initialized in SetUpTestCase.
Ken Chenb9fa2062018-11-13 21:51:13 +0800214};
215
Hungming Chen5bf09772019-04-25 11:16:13 +0800216// Initialize static member of class.
Luke Huangf8215372019-11-22 11:53:41 +0800217std::shared_ptr<DnsMetricsListener> ResolverTest::sDnsMetricsListener;
218AIBinder_DeathRecipient* ResolverTest::sResolvDeathRecipient;
Hungming Chen5bf09772019-04-25 11:16:13 +0800219
Ken Chenb9fa2062018-11-13 21:51:13 +0800220TEST_F(ResolverTest, GetHostByName) {
Xiao Ma09b71022018-12-11 17:56:32 +0900221 constexpr char nonexistent_host_name[] = "nonexistent.example.com.";
222
223 test::DNSResponder dns;
224 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.3"}});
225 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800226
227 const hostent* result;
Ken Chenb9fa2062018-11-13 21:51:13 +0800228 result = gethostbyname("nonexistent");
229 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, nonexistent_host_name));
230 ASSERT_TRUE(result == nullptr);
231 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
232
233 dns.clearQueries();
234 result = gethostbyname("hello");
Xiao Ma09b71022018-12-11 17:56:32 +0900235 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
Ken Chenb9fa2062018-11-13 21:51:13 +0800236 ASSERT_FALSE(result == nullptr);
237 ASSERT_EQ(4, result->h_length);
238 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
239 EXPECT_EQ("1.2.3.3", ToString(result));
240 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800241}
242
lifr4e4a2e02019-01-29 16:53:51 +0800243TEST_F(ResolverTest, GetHostByName_cnames) {
244 constexpr char host_name[] = "host.example.com.";
245 size_t cnamecount = 0;
246 test::DNSResponder dns;
247
248 const std::vector<DnsRecord> records = {
249 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
250 {"a.example.com.", ns_type::ns_t_cname, "b.example.com."},
251 {"b.example.com.", ns_type::ns_t_cname, "c.example.com."},
252 {"c.example.com.", ns_type::ns_t_cname, "d.example.com."},
253 {"d.example.com.", ns_type::ns_t_cname, "e.example.com."},
254 {"e.example.com.", ns_type::ns_t_cname, host_name},
255 {host_name, ns_type::ns_t_a, "1.2.3.3"},
256 {host_name, ns_type::ns_t_aaaa, "2001:db8::42"},
257 };
258 StartDns(dns, records);
259 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
260
261 // using gethostbyname2() to resolve ipv4 hello.example.com. to 1.2.3.3
262 // Ensure the v4 address and cnames are correct
263 const hostent* result;
264 result = gethostbyname2("hello", AF_INET);
265 ASSERT_FALSE(result == nullptr);
266
267 for (int i = 0; result != nullptr && result->h_aliases[i] != nullptr; i++) {
268 std::string domain_name = records[i].host_name.substr(0, records[i].host_name.size() - 1);
269 EXPECT_EQ(result->h_aliases[i], domain_name);
270 cnamecount++;
271 }
272 // The size of "Non-cname type" record in DNS records is 2
273 ASSERT_EQ(cnamecount, records.size() - 2);
274 ASSERT_EQ(4, result->h_length);
275 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
276 EXPECT_EQ("1.2.3.3", ToString(result));
277 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
278 EXPECT_EQ(1U, dns.queries().size()) << dns.dumpQueries();
279
280 // using gethostbyname2() to resolve ipv6 hello.example.com. to 2001:db8::42
281 // Ensure the v6 address and cnames are correct
282 cnamecount = 0;
283 dns.clearQueries();
284 result = gethostbyname2("hello", AF_INET6);
285 for (unsigned i = 0; result != nullptr && result->h_aliases[i] != nullptr; i++) {
286 std::string domain_name = records[i].host_name.substr(0, records[i].host_name.size() - 1);
287 EXPECT_EQ(result->h_aliases[i], domain_name);
288 cnamecount++;
289 }
290 // The size of "Non-cname type" DNS record in records is 2
291 ASSERT_EQ(cnamecount, records.size() - 2);
292 ASSERT_FALSE(result == nullptr);
293 ASSERT_EQ(16, result->h_length);
294 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
295 EXPECT_EQ("2001:db8::42", ToString(result));
296 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
297}
298
299TEST_F(ResolverTest, GetHostByName_cnamesInfiniteLoop) {
300 test::DNSResponder dns;
301 const std::vector<DnsRecord> records = {
302 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
303 {"a.example.com.", ns_type::ns_t_cname, kHelloExampleCom},
304 };
305 StartDns(dns, records);
306 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
307
308 const hostent* result;
309 result = gethostbyname2("hello", AF_INET);
310 ASSERT_TRUE(result == nullptr);
311
312 dns.clearQueries();
313 result = gethostbyname2("hello", AF_INET6);
314 ASSERT_TRUE(result == nullptr);
315}
316
Ken Chenb9fa2062018-11-13 21:51:13 +0800317TEST_F(ResolverTest, GetHostByName_localhost) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800318 constexpr char name_camelcase[] = "LocalHost";
Ken Chenb9fa2062018-11-13 21:51:13 +0800319 constexpr char name_ip6_dot[] = "ip6-localhost.";
320 constexpr char name_ip6_fqdn[] = "ip6-localhost.example.com.";
321
322 // Add a dummy nameserver which shouldn't receive any queries
Xiao Ma09b71022018-12-11 17:56:32 +0900323 test::DNSResponder dns;
324 StartDns(dns, {});
325 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800326
327 // Expect no DNS queries; localhost is resolved via /etc/hosts
Xiao Ma09b71022018-12-11 17:56:32 +0900328 const hostent* result = gethostbyname(kLocalHost);
Ken Chenb9fa2062018-11-13 21:51:13 +0800329 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
330 ASSERT_FALSE(result == nullptr);
331 ASSERT_EQ(4, result->h_length);
332 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900333 EXPECT_EQ(kLocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800334 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
335
336 // Ensure the hosts file resolver ignores case of hostnames
337 result = gethostbyname(name_camelcase);
338 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
339 ASSERT_FALSE(result == nullptr);
340 ASSERT_EQ(4, result->h_length);
341 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900342 EXPECT_EQ(kLocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800343 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
344
345 // The hosts file also contains ip6-localhost, but gethostbyname() won't
chenbruce018fdb22019-06-12 18:08:04 +0800346 // return it. This would be easy to
Ken Chenb9fa2062018-11-13 21:51:13 +0800347 // change, but there's no point in changing the legacy behavior; new code
348 // should be calling getaddrinfo() anyway.
349 // So we check the legacy behavior, which results in amusing A-record
350 // lookups for ip6-localhost, with and without search domains appended.
351 dns.clearQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900352 result = gethostbyname(kIp6LocalHost);
Sehee Parkbbca0202018-11-16 10:53:16 +0900353 EXPECT_EQ(2U, dns.queries().size()) << dns.dumpQueries();
354 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, name_ip6_dot)) << dns.dumpQueries();
355 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, name_ip6_fqdn)) << dns.dumpQueries();
Ken Chenb9fa2062018-11-13 21:51:13 +0800356 ASSERT_TRUE(result == nullptr);
357
358 // Finally, use gethostbyname2() to resolve ip6-localhost to ::1 from
359 // the hosts file.
360 dns.clearQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900361 result = gethostbyname2(kIp6LocalHost, AF_INET6);
Ken Chenb9fa2062018-11-13 21:51:13 +0800362 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
363 ASSERT_FALSE(result == nullptr);
364 ASSERT_EQ(16, result->h_length);
365 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900366 EXPECT_EQ(kIp6LocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800367 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800368}
369
370TEST_F(ResolverTest, GetHostByName_numeric) {
371 // Add a dummy nameserver which shouldn't receive any queries
Xiao Ma09b71022018-12-11 17:56:32 +0900372 test::DNSResponder dns;
373 StartDns(dns, {});
374 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800375
376 // Numeric v4 address: expect no DNS queries
377 constexpr char numeric_v4[] = "192.168.0.1";
Ken Chenb9fa2062018-11-13 21:51:13 +0800378 const hostent* result = gethostbyname(numeric_v4);
Sehee Parkbbca0202018-11-16 10:53:16 +0900379 EXPECT_EQ(0U, dns.queries().size());
Ken Chenb9fa2062018-11-13 21:51:13 +0800380 ASSERT_FALSE(result == nullptr);
381 ASSERT_EQ(4, result->h_length); // v4
382 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
383 EXPECT_EQ(numeric_v4, ToString(result));
384 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
385
386 // gethostbyname() recognizes a v6 address, and fails with no DNS queries
387 constexpr char numeric_v6[] = "2001:db8::42";
388 dns.clearQueries();
389 result = gethostbyname(numeric_v6);
Sehee Parkbbca0202018-11-16 10:53:16 +0900390 EXPECT_EQ(0U, dns.queries().size());
Ken Chenb9fa2062018-11-13 21:51:13 +0800391 EXPECT_TRUE(result == nullptr);
392
393 // Numeric v6 address with gethostbyname2(): succeeds with no DNS queries
394 dns.clearQueries();
395 result = gethostbyname2(numeric_v6, AF_INET6);
Sehee Parkbbca0202018-11-16 10:53:16 +0900396 EXPECT_EQ(0U, dns.queries().size());
Ken Chenb9fa2062018-11-13 21:51:13 +0800397 ASSERT_FALSE(result == nullptr);
398 ASSERT_EQ(16, result->h_length); // v6
399 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
400 EXPECT_EQ(numeric_v6, ToString(result));
401 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
402
403 // Numeric v6 address with scope work with getaddrinfo(),
404 // but gethostbyname2() does not understand them; it issues two dns
405 // queries, then fails. This hardly ever happens, there's no point
406 // in fixing this. This test simply verifies the current (bogus)
407 // behavior to avoid further regressions (like crashes, or leaks).
408 constexpr char numeric_v6_scope[] = "fe80::1%lo";
409 dns.clearQueries();
410 result = gethostbyname2(numeric_v6_scope, AF_INET6);
Sehee Parkbbca0202018-11-16 10:53:16 +0900411 EXPECT_EQ(2U, dns.queries().size()); // OUCH!
Ken Chenb9fa2062018-11-13 21:51:13 +0800412 ASSERT_TRUE(result == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800413}
414
415TEST_F(ResolverTest, BinderSerialization) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800416 std::vector<int> params_offsets = {
Luke Huang5bd827c2019-03-14 16:10:04 +0800417 IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY,
418 IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD,
419 IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES,
420 IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES,
421 IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC,
422 IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT,
Ken Chenb9fa2062018-11-13 21:51:13 +0800423 };
Bernie Innocentib102dd22018-12-04 14:57:48 +0900424 const int size = static_cast<int>(params_offsets.size());
Luke Huang5bd827c2019-03-14 16:10:04 +0800425 EXPECT_EQ(size, IDnsResolver::RESOLVER_PARAMS_COUNT);
Ken Chenb9fa2062018-11-13 21:51:13 +0800426 std::sort(params_offsets.begin(), params_offsets.end());
Bernie Innocentib102dd22018-12-04 14:57:48 +0900427 for (int i = 0; i < size; ++i) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800428 EXPECT_EQ(params_offsets[i], i);
429 }
430}
431
432TEST_F(ResolverTest, GetHostByName_Binder) {
Luke Huangf8215372019-11-22 11:53:41 +0800433 std::vector<std::string> domains = {"example.com"};
Ken Chenb9fa2062018-11-13 21:51:13 +0800434 std::vector<std::unique_ptr<test::DNSResponder>> dns;
435 std::vector<std::string> servers;
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900436 std::vector<DnsResponderClient::Mapping> mappings;
437 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupMappings(1, domains, &mappings));
438 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupDNSServers(4, mappings, &dns, &servers));
Ken Chenb9fa2062018-11-13 21:51:13 +0800439 ASSERT_EQ(1U, mappings.size());
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900440 const DnsResponderClient::Mapping& mapping = mappings[0];
Ken Chenb9fa2062018-11-13 21:51:13 +0800441
Xiao Ma09b71022018-12-11 17:56:32 +0900442 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains, kDefaultParams));
Ken Chenb9fa2062018-11-13 21:51:13 +0800443
444 const hostent* result = gethostbyname(mapping.host.c_str());
Bernie Innocentib102dd22018-12-04 14:57:48 +0900445 const size_t total_queries =
Luke Huangfde82482019-06-04 01:04:53 +0800446 std::accumulate(dns.begin(), dns.end(), 0, [&mapping](size_t total, auto& d) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800447 return total + GetNumQueriesForType(*d, ns_type::ns_t_a, mapping.entry.c_str());
448 });
449
450 EXPECT_LE(1U, total_queries);
451 ASSERT_FALSE(result == nullptr);
452 ASSERT_EQ(4, result->h_length);
453 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
454 EXPECT_EQ(mapping.ip4, ToString(result));
455 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
456
457 std::vector<std::string> res_servers;
458 std::vector<std::string> res_domains;
Mike Yu0a1c53d2018-11-26 13:26:21 +0900459 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +0900460 res_params res_params;
Ken Chenb9fa2062018-11-13 21:51:13 +0800461 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +0800462 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800463 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
464 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
465 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chenb9fa2062018-11-13 21:51:13 +0800466 EXPECT_EQ(servers.size(), res_servers.size());
467 EXPECT_EQ(domains.size(), res_domains.size());
Mike Yu0a1c53d2018-11-26 13:26:21 +0900468 EXPECT_EQ(0U, res_tls_servers.size());
Luke Huang5bd827c2019-03-14 16:10:04 +0800469 ASSERT_EQ(static_cast<size_t>(IDnsResolver::RESOLVER_PARAMS_COUNT), kDefaultParams.size());
470 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY],
471 res_params.sample_validity);
472 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD],
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +0900473 res_params.success_threshold);
Luke Huang5bd827c2019-03-14 16:10:04 +0800474 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES], res_params.min_samples);
475 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES], res_params.max_samples);
476 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
Ken Chenb9fa2062018-11-13 21:51:13 +0800477 res_params.base_timeout_msec);
478 EXPECT_EQ(servers.size(), res_stats.size());
479
Bernie Innocenti0c067e42019-04-01 15:33:16 +0900480 EXPECT_THAT(res_servers, testing::UnorderedElementsAreArray(servers));
481 EXPECT_THAT(res_domains, testing::UnorderedElementsAreArray(domains));
Ken Chenb9fa2062018-11-13 21:51:13 +0800482}
483
484TEST_F(ResolverTest, GetAddrInfo) {
Xiao Ma09b71022018-12-11 17:56:32 +0900485 constexpr char listen_addr[] = "127.0.0.4";
486 constexpr char listen_addr2[] = "127.0.0.5";
487 constexpr char host_name[] = "howdy.example.com.";
Ken Chenb9fa2062018-11-13 21:51:13 +0800488
Xiao Ma09b71022018-12-11 17:56:32 +0900489 const std::vector<DnsRecord> records = {
490 {host_name, ns_type::ns_t_a, "1.2.3.4"},
491 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
492 };
493 test::DNSResponder dns(listen_addr);
494 test::DNSResponder dns2(listen_addr2);
495 StartDns(dns, records);
496 StartDns(dns2, records);
Ken Chenb9fa2062018-11-13 21:51:13 +0800497
Xiao Ma09b71022018-12-11 17:56:32 +0900498 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr}));
Ken Chenb9fa2062018-11-13 21:51:13 +0800499 dns.clearQueries();
500 dns2.clearQueries();
501
502 ScopedAddrinfo result = safe_getaddrinfo("howdy", nullptr, nullptr);
503 EXPECT_TRUE(result != nullptr);
504 size_t found = GetNumQueries(dns, host_name);
505 EXPECT_LE(1U, found);
506 // Could be A or AAAA
507 std::string result_str = ToString(result);
508 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
Luke Huangf8215372019-11-22 11:53:41 +0800509 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +0800510
511 // Verify that the name is cached.
512 size_t old_found = found;
513 result = safe_getaddrinfo("howdy", nullptr, nullptr);
514 EXPECT_TRUE(result != nullptr);
515 found = GetNumQueries(dns, host_name);
516 EXPECT_LE(1U, found);
517 EXPECT_EQ(old_found, found);
518 result_str = ToString(result);
Luke Huangf8215372019-11-22 11:53:41 +0800519 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4") << result_str;
Ken Chenb9fa2062018-11-13 21:51:13 +0800520
521 // Change the DNS resolver, ensure that queries are still cached.
Xiao Ma09b71022018-12-11 17:56:32 +0900522 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr2}));
Ken Chenb9fa2062018-11-13 21:51:13 +0800523 dns.clearQueries();
524 dns2.clearQueries();
525
526 result = safe_getaddrinfo("howdy", nullptr, nullptr);
527 EXPECT_TRUE(result != nullptr);
528 found = GetNumQueries(dns, host_name);
529 size_t found2 = GetNumQueries(dns2, host_name);
530 EXPECT_EQ(0U, found);
531 EXPECT_LE(0U, found2);
532
533 // Could be A or AAAA
534 result_str = ToString(result);
535 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
Luke Huangf8215372019-11-22 11:53:41 +0800536 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +0800537}
538
539TEST_F(ResolverTest, GetAddrInfoV4) {
Xiao Ma09b71022018-12-11 17:56:32 +0900540 test::DNSResponder dns;
541 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.5"}});
542 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800543
Xiao Ma09b71022018-12-11 17:56:32 +0900544 const addrinfo hints = {.ai_family = AF_INET};
545 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
Ken Chenb9fa2062018-11-13 21:51:13 +0800546 EXPECT_TRUE(result != nullptr);
Xiao Ma09b71022018-12-11 17:56:32 +0900547 EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom));
Ken Chenb9fa2062018-11-13 21:51:13 +0800548 EXPECT_EQ("1.2.3.5", ToString(result));
549}
550
551TEST_F(ResolverTest, GetAddrInfo_localhost) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800552 // Add a dummy nameserver which shouldn't receive any queries
Xiao Ma09b71022018-12-11 17:56:32 +0900553 test::DNSResponder dns;
554 StartDns(dns, {});
555 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800556
Xiao Ma09b71022018-12-11 17:56:32 +0900557 ScopedAddrinfo result = safe_getaddrinfo(kLocalHost, nullptr, nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800558 EXPECT_TRUE(result != nullptr);
559 // Expect no DNS queries; localhost is resolved via /etc/hosts
560 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900561 EXPECT_EQ(kLocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800562
Xiao Ma09b71022018-12-11 17:56:32 +0900563 result = safe_getaddrinfo(kIp6LocalHost, nullptr, nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800564 EXPECT_TRUE(result != nullptr);
565 // Expect no DNS queries; ip6-localhost is resolved via /etc/hosts
566 EXPECT_TRUE(dns.queries().empty()) << dns.dumpQueries();
Xiao Ma09b71022018-12-11 17:56:32 +0900567 EXPECT_EQ(kIp6LocalHostAddr, ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +0800568}
569
Luke Huangd8ac4752019-06-18 17:05:47 +0800570TEST_F(ResolverTest, GetAddrInfo_InvalidSocketType) {
571 test::DNSResponder dns;
572 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, "1.2.3.5"}});
573 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
574
575 // TODO: Test other invalid socket types.
576 const addrinfo hints = {
577 .ai_family = AF_UNSPEC,
Luke Huangd8ac4752019-06-18 17:05:47 +0800578 .ai_socktype = SOCK_PACKET,
579 };
580 addrinfo* result = nullptr;
581 // This is a valid hint, but the query won't be sent because the socket type is
582 // not supported.
583 EXPECT_EQ(EAI_NODATA, getaddrinfo("hello", nullptr, &hints, &result));
584 ScopedAddrinfo result_cleanup(result);
585 EXPECT_EQ(nullptr, result);
586}
587
Ken Chen92bed612018-12-22 21:46:55 +0800588// Verify if the resolver correctly handle multiple queries simultaneously
589// step 1: set dns server#1 into deferred responding mode.
590// step 2: thread#1 query "hello.example.com." --> resolver send query to server#1.
591// step 3: thread#2 query "hello.example.com." --> resolver hold the request and wait for
592// response of previous pending query sent by thread#1.
593// step 4: thread#3 query "konbanha.example.com." --> resolver send query to server#3. Server
594// respond to resolver immediately.
595// step 5: check if server#1 get 1 query by thread#1, server#2 get 0 query, server#3 get 1 query.
596// step 6: resume dns server#1 to respond dns query in step#2.
597// step 7: thread#1 and #2 should get returned from DNS query after step#6. Also, check the
598// number of queries in server#2 is 0 to ensure thread#2 does not wake up unexpectedly
599// before signaled by thread#1.
600TEST_F(ResolverTest, GetAddrInfoV4_deferred_resp) {
601 const char* listen_addr1 = "127.0.0.9";
602 const char* listen_addr2 = "127.0.0.10";
603 const char* listen_addr3 = "127.0.0.11";
604 const char* listen_srv = "53";
605 const char* host_name_deferred = "hello.example.com.";
606 const char* host_name_normal = "konbanha.example.com.";
Mike Yufc125e42019-05-15 20:41:28 +0800607 test::DNSResponder dns1(listen_addr1, listen_srv, ns_rcode::ns_r_servfail);
608 test::DNSResponder dns2(listen_addr2, listen_srv, ns_rcode::ns_r_servfail);
609 test::DNSResponder dns3(listen_addr3, listen_srv, ns_rcode::ns_r_servfail);
Ken Chen92bed612018-12-22 21:46:55 +0800610 dns1.addMapping(host_name_deferred, ns_type::ns_t_a, "1.2.3.4");
611 dns2.addMapping(host_name_deferred, ns_type::ns_t_a, "1.2.3.4");
612 dns3.addMapping(host_name_normal, ns_type::ns_t_a, "1.2.3.5");
613 ASSERT_TRUE(dns1.startServer());
614 ASSERT_TRUE(dns2.startServer());
615 ASSERT_TRUE(dns3.startServer());
616 const std::vector<std::string> servers_for_t1 = {listen_addr1};
617 const std::vector<std::string> servers_for_t2 = {listen_addr2};
618 const std::vector<std::string> servers_for_t3 = {listen_addr3};
619 addrinfo hints = {.ai_family = AF_INET};
620 const std::vector<int> params = {300, 25, 8, 8, 5000};
621 bool t3_task_done = false;
622
623 dns1.setDeferredResp(true);
624 std::thread t1([&, this]() {
625 ASSERT_TRUE(
626 mDnsClient.SetResolversForNetwork(servers_for_t1, kDefaultSearchDomains, params));
627 ScopedAddrinfo result = safe_getaddrinfo(host_name_deferred, nullptr, &hints);
628 // t3's dns query should got returned first
629 EXPECT_TRUE(t3_task_done);
630 EXPECT_EQ(1U, GetNumQueries(dns1, host_name_deferred));
631 EXPECT_TRUE(result != nullptr);
632 EXPECT_EQ("1.2.3.4", ToString(result));
633 });
634
635 // ensuring t1 and t2 handler functions are processed in order
636 usleep(100 * 1000);
637 std::thread t2([&, this]() {
638 ASSERT_TRUE(
639 mDnsClient.SetResolversForNetwork(servers_for_t2, kDefaultSearchDomains, params));
640 ScopedAddrinfo result = safe_getaddrinfo(host_name_deferred, nullptr, &hints);
641 EXPECT_TRUE(t3_task_done);
642 EXPECT_EQ(0U, GetNumQueries(dns2, host_name_deferred));
643 EXPECT_TRUE(result != nullptr);
644 EXPECT_EQ("1.2.3.4", ToString(result));
645
646 std::vector<std::string> res_servers;
647 std::vector<std::string> res_domains;
648 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +0900649 res_params res_params;
Ken Chen92bed612018-12-22 21:46:55 +0800650 std::vector<ResolverStats> res_stats;
651 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800652 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
653 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains,
654 &res_tls_servers, &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chen92bed612018-12-22 21:46:55 +0800655 EXPECT_EQ(0, wait_for_pending_req_timeout_count);
656 });
657
658 // ensuring t2 and t3 handler functions are processed in order
659 usleep(100 * 1000);
660 std::thread t3([&, this]() {
661 ASSERT_TRUE(
662 mDnsClient.SetResolversForNetwork(servers_for_t3, kDefaultSearchDomains, params));
663 ScopedAddrinfo result = safe_getaddrinfo(host_name_normal, nullptr, &hints);
664 EXPECT_EQ(1U, GetNumQueries(dns1, host_name_deferred));
665 EXPECT_EQ(0U, GetNumQueries(dns2, host_name_deferred));
666 EXPECT_EQ(1U, GetNumQueries(dns3, host_name_normal));
667 EXPECT_TRUE(result != nullptr);
668 EXPECT_EQ("1.2.3.5", ToString(result));
669
670 t3_task_done = true;
671 dns1.setDeferredResp(false);
672 });
673 t3.join();
674 t1.join();
675 t2.join();
676}
677
lifr4e4a2e02019-01-29 16:53:51 +0800678TEST_F(ResolverTest, GetAddrInfo_cnames) {
679 constexpr char host_name[] = "host.example.com.";
680 test::DNSResponder dns;
681 const std::vector<DnsRecord> records = {
682 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
683 {"a.example.com.", ns_type::ns_t_cname, "b.example.com."},
684 {"b.example.com.", ns_type::ns_t_cname, "c.example.com."},
685 {"c.example.com.", ns_type::ns_t_cname, "d.example.com."},
686 {"d.example.com.", ns_type::ns_t_cname, "e.example.com."},
687 {"e.example.com.", ns_type::ns_t_cname, host_name},
688 {host_name, ns_type::ns_t_a, "1.2.3.3"},
689 {host_name, ns_type::ns_t_aaaa, "2001:db8::42"},
690 };
691 StartDns(dns, records);
692 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
693
694 addrinfo hints = {.ai_family = AF_INET};
695 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
696 EXPECT_TRUE(result != nullptr);
697 EXPECT_EQ("1.2.3.3", ToString(result));
698
699 dns.clearQueries();
700 hints = {.ai_family = AF_INET6};
701 result = safe_getaddrinfo("hello", nullptr, &hints);
702 EXPECT_TRUE(result != nullptr);
703 EXPECT_EQ("2001:db8::42", ToString(result));
704}
705
706TEST_F(ResolverTest, GetAddrInfo_cnamesNoIpAddress) {
707 test::DNSResponder dns;
708 const std::vector<DnsRecord> records = {
709 {kHelloExampleCom, ns_type::ns_t_cname, "a.example.com."},
710 };
711 StartDns(dns, records);
712 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
713
714 addrinfo hints = {.ai_family = AF_INET};
715 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
716 EXPECT_TRUE(result == nullptr);
717
718 dns.clearQueries();
719 hints = {.ai_family = AF_INET6};
720 result = safe_getaddrinfo("hello", nullptr, &hints);
721 EXPECT_TRUE(result == nullptr);
722}
723
724TEST_F(ResolverTest, GetAddrInfo_cnamesIllegalRdata) {
725 test::DNSResponder dns;
726 const std::vector<DnsRecord> records = {
727 {kHelloExampleCom, ns_type::ns_t_cname, ".!#?"},
728 };
729 StartDns(dns, records);
730 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
731
732 addrinfo hints = {.ai_family = AF_INET};
733 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
734 EXPECT_TRUE(result == nullptr);
735
736 dns.clearQueries();
737 hints = {.ai_family = AF_INET6};
738 result = safe_getaddrinfo("hello", nullptr, &hints);
739 EXPECT_TRUE(result == nullptr);
740}
741
Ken Chenb9fa2062018-11-13 21:51:13 +0800742TEST_F(ResolverTest, MultidomainResolution) {
Xiao Ma09b71022018-12-11 17:56:32 +0900743 constexpr char host_name[] = "nihao.example2.com.";
Luke Huangf8215372019-11-22 11:53:41 +0800744 std::vector<std::string> searchDomains = {"example1.com", "example2.com", "example3.com"};
Ken Chenb9fa2062018-11-13 21:51:13 +0800745
Xiao Ma09b71022018-12-11 17:56:32 +0900746 test::DNSResponder dns("127.0.0.6");
747 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.3"}});
748 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({"127.0.0.6"}, searchDomains));
749
Ken Chenb9fa2062018-11-13 21:51:13 +0800750 const hostent* result = gethostbyname("nihao");
Xiao Ma09b71022018-12-11 17:56:32 +0900751
Ken Chenb9fa2062018-11-13 21:51:13 +0800752 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
753 ASSERT_FALSE(result == nullptr);
754 ASSERT_EQ(4, result->h_length);
755 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
756 EXPECT_EQ("1.2.3.3", ToString(result));
757 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
Ken Chenb9fa2062018-11-13 21:51:13 +0800758}
759
760TEST_F(ResolverTest, GetAddrInfoV6_numeric) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800761 constexpr char host_name[] = "ohayou.example.com.";
762 constexpr char numeric_addr[] = "fe80::1%lo";
763
Xiao Ma09b71022018-12-11 17:56:32 +0900764 test::DNSResponder dns;
Ken Chenb9fa2062018-11-13 21:51:13 +0800765 dns.setResponseProbability(0.0);
Xiao Ma09b71022018-12-11 17:56:32 +0900766 StartDns(dns, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
767 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +0800768
769 addrinfo hints = {.ai_family = AF_INET6};
770 ScopedAddrinfo result = safe_getaddrinfo(numeric_addr, nullptr, &hints);
771 EXPECT_TRUE(result != nullptr);
772 EXPECT_EQ(numeric_addr, ToString(result));
773 EXPECT_TRUE(dns.queries().empty()); // Ensure no DNS queries were sent out
774
775 // Now try a non-numeric hostname query with the AI_NUMERICHOST flag set.
776 // We should fail without sending out a DNS query.
777 hints.ai_flags |= AI_NUMERICHOST;
778 result = safe_getaddrinfo(host_name, nullptr, &hints);
779 EXPECT_TRUE(result == nullptr);
780 EXPECT_TRUE(dns.queries().empty()); // Ensure no DNS queries were sent out
781}
782
783TEST_F(ResolverTest, GetAddrInfoV6_failing) {
Xiao Ma09b71022018-12-11 17:56:32 +0900784 constexpr char listen_addr0[] = "127.0.0.7";
785 constexpr char listen_addr1[] = "127.0.0.8";
Ken Chenb9fa2062018-11-13 21:51:13 +0800786 const char* host_name = "ohayou.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +0900787
788 test::DNSResponder dns0(listen_addr0);
789 test::DNSResponder dns1(listen_addr1);
Ken Chenb9fa2062018-11-13 21:51:13 +0800790 dns0.setResponseProbability(0.0);
Xiao Ma09b71022018-12-11 17:56:32 +0900791 StartDns(dns0, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
792 StartDns(dns1, {{host_name, ns_type::ns_t_aaaa, "2001:db8::6"}});
793
Luke Huangf8215372019-11-22 11:53:41 +0800794 std::vector<std::string> servers = {listen_addr0, listen_addr1};
Ken Chenb9fa2062018-11-13 21:51:13 +0800795 // <sample validity in s> <success threshold in percent> <min samples> <max samples>
796 int sample_count = 8;
Luke Huangf8215372019-11-22 11:53:41 +0800797 const std::vector<int> params = {300, 25, sample_count, sample_count};
Xiao Ma09b71022018-12-11 17:56:32 +0900798 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, kDefaultSearchDomains, params));
Ken Chenb9fa2062018-11-13 21:51:13 +0800799
800 // Repeatedly perform resolutions for non-existing domains until MAXNSSAMPLES resolutions have
801 // reached the dns0, which is set to fail. No more requests should then arrive at that server
802 // for the next sample_lifetime seconds.
803 // TODO: This approach is implementation-dependent, change once metrics reporting is available.
Xiao Ma09b71022018-12-11 17:56:32 +0900804 const addrinfo hints = {.ai_family = AF_INET6};
Bernie Innocentib102dd22018-12-04 14:57:48 +0900805 for (int i = 0; i < sample_count; ++i) {
Ken Chenb9fa2062018-11-13 21:51:13 +0800806 std::string domain = StringPrintf("nonexistent%d", i);
807 ScopedAddrinfo result = safe_getaddrinfo(domain.c_str(), nullptr, &hints);
808 }
809 // Due to 100% errors for all possible samples, the server should be ignored from now on and
810 // only the second one used for all following queries, until NSSAMPLE_VALIDITY is reached.
811 dns0.clearQueries();
812 dns1.clearQueries();
813 ScopedAddrinfo result = safe_getaddrinfo("ohayou", nullptr, &hints);
814 EXPECT_TRUE(result != nullptr);
815 EXPECT_EQ(0U, GetNumQueries(dns0, host_name));
816 EXPECT_EQ(1U, GetNumQueries(dns1, host_name));
817}
818
819TEST_F(ResolverTest, GetAddrInfoV6_nonresponsive) {
Xiao Ma09b71022018-12-11 17:56:32 +0900820 constexpr char listen_addr0[] = "127.0.0.7";
821 constexpr char listen_addr1[] = "127.0.0.8";
822 constexpr char listen_srv[] = "53";
823 constexpr char host_name1[] = "ohayou.example.com.";
824 constexpr char host_name2[] = "ciao.example.com.";
Luke Huang483cf332019-06-03 17:24:51 +0800825 const std::vector<std::string> defaultSearchDomain = {"example.com"};
826 // The minimal timeout is 1000ms, so we can't decrease timeout
827 // So reduce retry count.
828 const std::vector<int> reduceRetryParams = {
829 300, // sample validity in seconds
830 25, // success threshod in percent
831 8, 8, // {MIN,MAX}_SAMPLES
832 1000, // BASE_TIMEOUT_MSEC
833 1, // retry count
834 };
Xiao Ma09b71022018-12-11 17:56:32 +0900835 const std::vector<DnsRecord> records0 = {
836 {host_name1, ns_type::ns_t_aaaa, "2001:db8::5"},
837 {host_name2, ns_type::ns_t_aaaa, "2001:db8::5"},
838 };
839 const std::vector<DnsRecord> records1 = {
840 {host_name1, ns_type::ns_t_aaaa, "2001:db8::6"},
841 {host_name2, ns_type::ns_t_aaaa, "2001:db8::6"},
842 };
Ken Chenb9fa2062018-11-13 21:51:13 +0800843
844 // dns0 does not respond with 100% probability, while
845 // dns1 responds normally, at least initially.
Mike Yufc125e42019-05-15 20:41:28 +0800846 test::DNSResponder dns0(listen_addr0, listen_srv, static_cast<ns_rcode>(-1));
847 test::DNSResponder dns1(listen_addr1, listen_srv, static_cast<ns_rcode>(-1));
Ken Chenb9fa2062018-11-13 21:51:13 +0800848 dns0.setResponseProbability(0.0);
Xiao Ma09b71022018-12-11 17:56:32 +0900849 StartDns(dns0, records0);
850 StartDns(dns1, records1);
Luke Huang483cf332019-06-03 17:24:51 +0800851 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr0, listen_addr1}, defaultSearchDomain,
852 reduceRetryParams));
Ken Chenb9fa2062018-11-13 21:51:13 +0800853
Luke Huang483cf332019-06-03 17:24:51 +0800854 // Specify ai_socktype to make getaddrinfo will only query 1 time
855 const addrinfo hints = {.ai_family = AF_INET6, .ai_socktype = SOCK_STREAM};
Ken Chenb9fa2062018-11-13 21:51:13 +0800856
857 // dns0 will ignore the request, and we'll fallback to dns1 after the first
858 // retry.
859 ScopedAddrinfo result = safe_getaddrinfo(host_name1, nullptr, &hints);
860 EXPECT_TRUE(result != nullptr);
861 EXPECT_EQ(1U, GetNumQueries(dns0, host_name1));
862 EXPECT_EQ(1U, GetNumQueries(dns1, host_name1));
863
864 // Now make dns1 also ignore 100% requests... The resolve should alternate
Luke Huang483cf332019-06-03 17:24:51 +0800865 // queries between the nameservers and fail
Ken Chenb9fa2062018-11-13 21:51:13 +0800866 dns1.setResponseProbability(0.0);
867 addrinfo* result2 = nullptr;
868 EXPECT_EQ(EAI_NODATA, getaddrinfo(host_name2, nullptr, &hints, &result2));
869 EXPECT_EQ(nullptr, result2);
Luke Huang483cf332019-06-03 17:24:51 +0800870 EXPECT_EQ(1U, GetNumQueries(dns0, host_name2));
871 EXPECT_EQ(1U, GetNumQueries(dns1, host_name2));
Ken Chenb9fa2062018-11-13 21:51:13 +0800872}
873
874TEST_F(ResolverTest, GetAddrInfoV6_concurrent) {
Xiao Ma09b71022018-12-11 17:56:32 +0900875 constexpr char listen_addr0[] = "127.0.0.9";
876 constexpr char listen_addr1[] = "127.0.0.10";
877 constexpr char listen_addr2[] = "127.0.0.11";
878 constexpr char host_name[] = "konbanha.example.com.";
879
880 test::DNSResponder dns0(listen_addr0);
881 test::DNSResponder dns1(listen_addr1);
882 test::DNSResponder dns2(listen_addr2);
883 StartDns(dns0, {{host_name, ns_type::ns_t_aaaa, "2001:db8::5"}});
884 StartDns(dns1, {{host_name, ns_type::ns_t_aaaa, "2001:db8::6"}});
885 StartDns(dns2, {{host_name, ns_type::ns_t_aaaa, "2001:db8::7"}});
886
Luke Huangf8215372019-11-22 11:53:41 +0800887 const std::vector<std::string> servers = {listen_addr0, listen_addr1, listen_addr2};
Ken Chenb9fa2062018-11-13 21:51:13 +0800888 std::vector<std::thread> threads(10);
889 for (std::thread& thread : threads) {
Luke Huangf8215372019-11-22 11:53:41 +0800890 thread = std::thread([this, &servers]() {
891 unsigned delay = arc4random_uniform(1 * 1000 * 1000); // <= 1s
Ken Chenb9fa2062018-11-13 21:51:13 +0800892 usleep(delay);
893 std::vector<std::string> serverSubset;
894 for (const auto& server : servers) {
895 if (arc4random_uniform(2)) {
896 serverSubset.push_back(server);
897 }
898 }
899 if (serverSubset.empty()) serverSubset = servers;
Xiao Ma09b71022018-12-11 17:56:32 +0900900 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(serverSubset));
901 const addrinfo hints = {.ai_family = AF_INET6};
Ken Chenb9fa2062018-11-13 21:51:13 +0800902 addrinfo* result = nullptr;
903 int rv = getaddrinfo("konbanha", nullptr, &hints, &result);
904 EXPECT_EQ(0, rv) << "error [" << rv << "] " << gai_strerror(rv);
905 if (result) {
906 freeaddrinfo(result);
907 result = nullptr;
908 }
909 });
910 }
911 for (std::thread& thread : threads) {
912 thread.join();
913 }
Ken Chen92bed612018-12-22 21:46:55 +0800914
915 std::vector<std::string> res_servers;
916 std::vector<std::string> res_domains;
917 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +0900918 res_params res_params;
Ken Chen92bed612018-12-22 21:46:55 +0800919 std::vector<ResolverStats> res_stats;
920 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +0800921 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
922 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
923 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Ken Chen92bed612018-12-22 21:46:55 +0800924 EXPECT_EQ(0, wait_for_pending_req_timeout_count);
Ken Chenb9fa2062018-11-13 21:51:13 +0800925}
926
Mike Yu8ac63402019-12-02 15:28:38 +0800927TEST_F(ResolverTest, SkipBadServersDueToInternalError) {
928 constexpr char listen_addr1[] = "fe80::1";
929 constexpr char listen_addr2[] = "255.255.255.255";
930 constexpr char listen_addr3[] = "127.0.0.3";
931
932 test::DNSResponder dns(listen_addr3);
933 ASSERT_TRUE(dns.startServer());
934
935 ResolverParamsParcel parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
936 parcel.servers = {listen_addr1, listen_addr2, listen_addr3};
937
938 // Bad servers can be distinguished after two attempts.
939 parcel.minSamples = 2;
940 ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
941
942 // Start querying five times.
943 for (int i = 0; i < 5; i++) {
944 std::string hostName = StringPrintf("hello%d.com.", i);
945 dns.addMapping(hostName, ns_type::ns_t_a, "1.2.3.4");
946 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
947 EXPECT_TRUE(safe_getaddrinfo(hostName.c_str(), nullptr, &hints) != nullptr);
948 }
949
950 std::vector<std::string> res_servers;
951 std::vector<std::string> res_domains;
952 std::vector<std::string> res_tls_servers;
953 res_params res_params;
954 std::vector<ResolverStats> res_stats;
955 int wait_for_pending_req_timeout_count;
956 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
957 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
958 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
959
960 // Verify the result by means of the statistics.
961 EXPECT_EQ(res_stats[0].successes, 0);
962 EXPECT_EQ(res_stats[1].successes, 0);
963 EXPECT_EQ(res_stats[2].successes, 5);
964 EXPECT_EQ(res_stats[0].internal_errors, 2);
965 EXPECT_EQ(res_stats[1].internal_errors, 2);
966 EXPECT_EQ(res_stats[2].internal_errors, 0);
967}
968
969TEST_F(ResolverTest, SkipBadServersDueToTimeout) {
970 constexpr char listen_addr1[] = "127.0.0.3";
971 constexpr char listen_addr2[] = "127.0.0.4";
972
973 // Set dns1 non-responsive and dns2 workable.
974 test::DNSResponder dns1(listen_addr1, test::kDefaultListenService, static_cast<ns_rcode>(-1));
975 test::DNSResponder dns2(listen_addr2);
976 dns1.setResponseProbability(0.0);
977 ASSERT_TRUE(dns1.startServer());
978 ASSERT_TRUE(dns2.startServer());
979
980 ResolverParamsParcel parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
981 parcel.servers = {listen_addr1, listen_addr2};
982
983 // Bad servers can be distinguished after two attempts.
984 parcel.minSamples = 2;
985 ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
986
987 // Start querying five times.
988 for (int i = 0; i < 5; i++) {
989 std::string hostName = StringPrintf("hello%d.com.", i);
990 dns1.addMapping(hostName, ns_type::ns_t_a, "1.2.3.4");
991 dns2.addMapping(hostName, ns_type::ns_t_a, "1.2.3.5");
992 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
993 EXPECT_TRUE(safe_getaddrinfo(hostName.c_str(), nullptr, &hints) != nullptr);
994 }
995
996 std::vector<std::string> res_servers;
997 std::vector<std::string> res_domains;
998 std::vector<std::string> res_tls_servers;
999 res_params res_params;
1000 std::vector<ResolverStats> res_stats;
1001 int wait_for_pending_req_timeout_count;
1002 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
1003 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
1004 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
1005
1006 // Verify the result by means of the statistics as well as the query counts.
1007 EXPECT_EQ(res_stats[0].successes, 0);
1008 EXPECT_EQ(res_stats[1].successes, 5);
1009 EXPECT_EQ(res_stats[0].timeouts, 2);
1010 EXPECT_EQ(res_stats[1].timeouts, 0);
1011 EXPECT_EQ(dns1.queries().size(), 2U);
1012 EXPECT_EQ(dns2.queries().size(), 5U);
1013}
1014
chenbrucefd837fa2019-10-29 18:35:36 +08001015TEST_F(ResolverTest, GetAddrInfoFromCustTable_InvalidInput) {
1016 constexpr char hostnameNoip[] = "noip.example.com.";
1017 constexpr char hostnameInvalidip[] = "invalidip.example.com.";
1018 const std::vector<aidl::android::net::ResolverHostsParcel> invalidCustHosts = {
1019 {"", hostnameNoip},
1020 {"wrong IP", hostnameInvalidip},
1021 };
1022 test::DNSResponder dns;
1023 StartDns(dns, {});
1024 auto resolverParams = DnsResponderClient::GetDefaultResolverParamsParcel();
1025 resolverParams.hosts = invalidCustHosts;
1026 ASSERT_TRUE(mDnsClient.resolvService()->setResolverConfiguration(resolverParams).isOk());
1027 for (const auto& hostname : {hostnameNoip, hostnameInvalidip}) {
1028 // The query won't get data from customized table because of invalid customized table
1029 // and DNSResponder also has no records. hostnameNoip has never registered and
1030 // hostnameInvalidip has registered but wrong IP.
1031 const addrinfo hints = {.ai_family = AF_UNSPEC};
1032 ScopedAddrinfo result = safe_getaddrinfo(hostname, nullptr, &hints);
1033 ASSERT_TRUE(result == nullptr);
1034 EXPECT_EQ(4U, GetNumQueries(dns, hostname));
1035 }
1036}
1037
1038TEST_F(ResolverTest, GetAddrInfoFromCustTable) {
1039 constexpr char hostnameV4[] = "v4only.example.com.";
1040 constexpr char hostnameV6[] = "v6only.example.com.";
1041 constexpr char hostnameV4V6[] = "v4v6.example.com.";
1042 constexpr char custAddrV4[] = "1.2.3.4";
1043 constexpr char custAddrV6[] = "::1.2.3.4";
1044 constexpr char dnsSvAddrV4[] = "1.2.3.5";
1045 constexpr char dnsSvAddrV6[] = "::1.2.3.5";
1046 const std::vector<aidl::android::net::ResolverHostsParcel> custHostV4 = {
1047 {custAddrV4, hostnameV4},
1048 };
1049 const std::vector<aidl::android::net::ResolverHostsParcel> custHostV6 = {
1050 {custAddrV6, hostnameV6},
1051 };
1052 const std::vector<aidl::android::net::ResolverHostsParcel> custHostV4V6 = {
1053 {custAddrV4, hostnameV4V6},
1054 {custAddrV6, hostnameV4V6},
1055 };
1056 const std::vector<DnsRecord> dnsSvHostV4 = {
1057 {hostnameV4, ns_type::ns_t_a, dnsSvAddrV4},
1058 };
1059 const std::vector<DnsRecord> dnsSvHostV6 = {
1060 {hostnameV6, ns_type::ns_t_aaaa, dnsSvAddrV6},
1061 };
1062 const std::vector<DnsRecord> dnsSvHostV4V6 = {
1063 {hostnameV4V6, ns_type::ns_t_a, dnsSvAddrV4},
1064 {hostnameV4V6, ns_type::ns_t_aaaa, dnsSvAddrV6},
1065 };
1066 struct TestConfig {
1067 const std::string name;
1068 const std::vector<aidl::android::net::ResolverHostsParcel> customizedHosts;
1069 const std::vector<DnsRecord> dnsserverHosts;
1070 const std::vector<std::string> queryResult;
1071 std::string asParameters() const {
1072 return StringPrintf("name: %s, customizedHosts: %s, dnsserverHosts: %s", name.c_str(),
1073 customizedHosts.empty() ? "No" : "Yes",
1074 dnsserverHosts.empty() ? "No" : "Yes");
1075 }
1076 } testConfigs[]{
1077 // clang-format off
1078 {hostnameV4, {}, {}, {}},
1079 {hostnameV4, {}, dnsSvHostV4, {dnsSvAddrV4}},
1080 {hostnameV4, custHostV4, {}, {custAddrV4}},
1081 {hostnameV4, custHostV4, dnsSvHostV4, {custAddrV4}},
1082 {hostnameV6, {}, {}, {}},
1083 {hostnameV6, {}, dnsSvHostV6, {dnsSvAddrV6}},
1084 {hostnameV6, custHostV6, {}, {custAddrV6}},
1085 {hostnameV6, custHostV6, dnsSvHostV6, {custAddrV6}},
1086 {hostnameV4V6, {}, {}, {}},
1087 {hostnameV4V6, {}, dnsSvHostV4V6, {dnsSvAddrV4, dnsSvAddrV6}},
1088 {hostnameV4V6, custHostV4V6, {}, {custAddrV4, custAddrV6}},
1089 {hostnameV4V6, custHostV4V6, dnsSvHostV4V6, {custAddrV4, custAddrV6}},
1090 // clang-format on
1091 };
1092
1093 for (const auto& config : testConfigs) {
1094 SCOPED_TRACE(config.asParameters());
1095
1096 test::DNSResponder dns;
1097 StartDns(dns, config.dnsserverHosts);
1098
1099 auto resolverParams = DnsResponderClient::GetDefaultResolverParamsParcel();
1100 resolverParams.hosts = config.customizedHosts;
1101 ASSERT_TRUE(mDnsClient.resolvService()->setResolverConfiguration(resolverParams).isOk());
1102 const addrinfo hints = {.ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM};
1103 ScopedAddrinfo result = safe_getaddrinfo(config.name.c_str(), nullptr, &hints);
1104 if (config.customizedHosts.empty() && config.dnsserverHosts.empty()) {
1105 ASSERT_TRUE(result == nullptr);
1106 EXPECT_EQ(2U, GetNumQueries(dns, config.name.c_str()));
1107 } else {
1108 ASSERT_TRUE(result != nullptr);
1109 EXPECT_THAT(ToStrings(result), testing::UnorderedElementsAreArray(config.queryResult));
1110 EXPECT_EQ(config.customizedHosts.empty() ? 2U : 0U,
1111 GetNumQueries(dns, config.name.c_str()));
1112 }
1113
1114 EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk());
1115 }
1116}
1117
1118TEST_F(ResolverTest, GetAddrInfoFromCustTable_Modify) {
1119 constexpr char hostnameV4V6[] = "v4v6.example.com.";
1120 constexpr char custAddrV4[] = "1.2.3.4";
1121 constexpr char custAddrV6[] = "::1.2.3.4";
1122 constexpr char dnsSvAddrV4[] = "1.2.3.5";
1123 constexpr char dnsSvAddrV6[] = "::1.2.3.5";
1124 const std::vector<DnsRecord> dnsSvHostV4V6 = {
1125 {hostnameV4V6, ns_type::ns_t_a, dnsSvAddrV4},
1126 {hostnameV4V6, ns_type::ns_t_aaaa, dnsSvAddrV6},
1127 };
1128 const std::vector<aidl::android::net::ResolverHostsParcel> custHostV4V6 = {
1129 {custAddrV4, hostnameV4V6},
1130 {custAddrV6, hostnameV4V6},
1131 };
1132 test::DNSResponder dns;
1133 StartDns(dns, dnsSvHostV4V6);
1134 auto resolverParams = DnsResponderClient::GetDefaultResolverParamsParcel();
1135
1136 resolverParams.hosts = custHostV4V6;
1137 ASSERT_TRUE(mDnsClient.resolvService()->setResolverConfiguration(resolverParams).isOk());
1138 const addrinfo hints = {.ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM};
1139 ScopedAddrinfo result = safe_getaddrinfo(hostnameV4V6, nullptr, &hints);
1140 ASSERT_TRUE(result != nullptr);
1141 EXPECT_THAT(ToStrings(result), testing::UnorderedElementsAreArray({custAddrV4, custAddrV6}));
1142 EXPECT_EQ(0U, GetNumQueries(dns, hostnameV4V6));
1143
1144 resolverParams.hosts = {};
1145 ASSERT_TRUE(mDnsClient.resolvService()->setResolverConfiguration(resolverParams).isOk());
1146 result = safe_getaddrinfo(hostnameV4V6, nullptr, &hints);
1147 ASSERT_TRUE(result != nullptr);
1148 EXPECT_THAT(ToStrings(result), testing::UnorderedElementsAreArray({dnsSvAddrV4, dnsSvAddrV6}));
1149 EXPECT_EQ(2U, GetNumQueries(dns, hostnameV4V6));
1150}
1151
Ken Chenb9fa2062018-11-13 21:51:13 +08001152TEST_F(ResolverTest, EmptySetup) {
Ken Chenb9fa2062018-11-13 21:51:13 +08001153 std::vector<std::string> servers;
1154 std::vector<std::string> domains;
Xiao Ma09b71022018-12-11 17:56:32 +09001155 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
Ken Chenb9fa2062018-11-13 21:51:13 +08001156 std::vector<std::string> res_servers;
1157 std::vector<std::string> res_domains;
Mike Yu0a1c53d2018-11-26 13:26:21 +09001158 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +09001159 res_params res_params;
Ken Chenb9fa2062018-11-13 21:51:13 +08001160 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));
Ken Chenb9fa2062018-11-13 21:51:13 +08001165 EXPECT_EQ(0U, res_servers.size());
1166 EXPECT_EQ(0U, res_domains.size());
Mike Yu0a1c53d2018-11-26 13:26:21 +09001167 EXPECT_EQ(0U, res_tls_servers.size());
Luke Huang5bd827c2019-03-14 16:10:04 +08001168 ASSERT_EQ(static_cast<size_t>(IDnsResolver::RESOLVER_PARAMS_COUNT), kDefaultParams.size());
1169 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY],
1170 res_params.sample_validity);
1171 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD],
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +09001172 res_params.success_threshold);
Luke Huang5bd827c2019-03-14 16:10:04 +08001173 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES], res_params.min_samples);
1174 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES], res_params.max_samples);
1175 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
Ken Chenb9fa2062018-11-13 21:51:13 +08001176 res_params.base_timeout_msec);
Luke Huang5bd827c2019-03-14 16:10:04 +08001177 EXPECT_EQ(kDefaultParams[IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT], res_params.retry_count);
Ken Chenb9fa2062018-11-13 21:51:13 +08001178}
1179
1180TEST_F(ResolverTest, SearchPathChange) {
Xiao Ma09b71022018-12-11 17:56:32 +09001181 constexpr char listen_addr[] = "127.0.0.13";
1182 constexpr char host_name1[] = "test13.domain1.org.";
1183 constexpr char host_name2[] = "test13.domain2.org.";
Luke Huangf8215372019-11-22 11:53:41 +08001184 std::vector<std::string> servers = {listen_addr};
1185 std::vector<std::string> domains = {"domain1.org"};
Xiao Ma09b71022018-12-11 17:56:32 +09001186
1187 const std::vector<DnsRecord> records = {
1188 {host_name1, ns_type::ns_t_aaaa, "2001:db8::13"},
1189 {host_name2, ns_type::ns_t_aaaa, "2001:db8::1:13"},
1190 };
1191 test::DNSResponder dns(listen_addr);
1192 StartDns(dns, records);
1193 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
Ken Chenb9fa2062018-11-13 21:51:13 +08001194
1195 const addrinfo hints = {.ai_family = AF_INET6};
1196 ScopedAddrinfo result = safe_getaddrinfo("test13", nullptr, &hints);
1197 EXPECT_TRUE(result != nullptr);
1198 EXPECT_EQ(1U, dns.queries().size());
1199 EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
1200 EXPECT_EQ("2001:db8::13", ToString(result));
1201
1202 // Test that changing the domain search path on its own works.
Luke Huangf8215372019-11-22 11:53:41 +08001203 domains = {"domain2.org"};
Xiao Ma09b71022018-12-11 17:56:32 +09001204 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, domains));
Ken Chenb9fa2062018-11-13 21:51:13 +08001205 dns.clearQueries();
1206
1207 result = safe_getaddrinfo("test13", nullptr, &hints);
1208 EXPECT_TRUE(result != nullptr);
1209 EXPECT_EQ(1U, dns.queries().size());
1210 EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
1211 EXPECT_EQ("2001:db8::1:13", ToString(result));
1212}
1213
Luke Huang2dac4382019-06-24 13:28:44 +08001214namespace {
1215
Luke Huangf8215372019-11-22 11:53:41 +08001216std::vector<std::string> getResolverDomains(aidl::android::net::IDnsResolver* dnsResolverService,
Luke Huang2dac4382019-06-24 13:28:44 +08001217 unsigned netId) {
1218 std::vector<std::string> res_servers;
1219 std::vector<std::string> res_domains;
1220 std::vector<std::string> res_tls_servers;
1221 res_params res_params;
1222 std::vector<ResolverStats> res_stats;
1223 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +08001224 DnsResponderClient::GetResolverInfo(dnsResolverService, netId, &res_servers, &res_domains,
1225 &res_tls_servers, &res_params, &res_stats,
1226 &wait_for_pending_req_timeout_count);
Luke Huang2dac4382019-06-24 13:28:44 +08001227 return res_domains;
1228}
1229
1230} // namespace
1231
1232TEST_F(ResolverTest, SearchPathPrune) {
1233 constexpr size_t DUPLICATED_DOMAIN_NUM = 3;
1234 constexpr char listen_addr[] = "127.0.0.13";
1235 constexpr char domian_name1[] = "domain13.org.";
1236 constexpr char domian_name2[] = "domain14.org.";
1237 constexpr char host_name1[] = "test13.domain13.org.";
1238 constexpr char host_name2[] = "test14.domain14.org.";
1239 std::vector<std::string> servers = {listen_addr};
1240
1241 std::vector<std::string> testDomains1;
1242 std::vector<std::string> testDomains2;
1243 // Domain length should be <= 255
1244 // Max number of domains in search path is 6
1245 for (size_t i = 0; i < MAXDNSRCH + 1; i++) {
1246 // Fill up with invalid domain
1247 testDomains1.push_back(std::string(300, i + '0'));
1248 // Fill up with valid but duplicated domain
1249 testDomains2.push_back(StringPrintf("domain%zu.org", i % DUPLICATED_DOMAIN_NUM));
1250 }
1251
1252 // Add valid domain used for query.
1253 testDomains1.push_back(domian_name1);
1254
1255 // Add valid domain twice used for query.
1256 testDomains2.push_back(domian_name2);
1257 testDomains2.push_back(domian_name2);
1258
1259 const std::vector<DnsRecord> records = {
1260 {host_name1, ns_type::ns_t_aaaa, "2001:db8::13"},
1261 {host_name2, ns_type::ns_t_aaaa, "2001:db8::1:13"},
1262 };
1263 test::DNSResponder dns(listen_addr);
1264 StartDns(dns, records);
1265 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, testDomains1));
1266
1267 const addrinfo hints = {.ai_family = AF_INET6};
1268 ScopedAddrinfo result = safe_getaddrinfo("test13", nullptr, &hints);
1269
1270 EXPECT_TRUE(result != nullptr);
1271
1272 EXPECT_EQ(1U, dns.queries().size());
1273 EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
1274 EXPECT_EQ("2001:db8::13", ToString(result));
1275
1276 const auto& res_domains1 = getResolverDomains(mDnsClient.resolvService(), TEST_NETID);
1277 // Expect 1 valid domain, invalid domains are removed.
1278 ASSERT_EQ(1U, res_domains1.size());
1279 EXPECT_EQ(domian_name1, res_domains1[0]);
1280
1281 dns.clearQueries();
1282
1283 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, testDomains2));
1284
1285 result = safe_getaddrinfo("test14", nullptr, &hints);
1286 EXPECT_TRUE(result != nullptr);
1287
1288 // (3 domains * 2 retries) + 1 success query = 7
1289 EXPECT_EQ(7U, dns.queries().size());
1290 EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
1291 EXPECT_EQ("2001:db8::1:13", ToString(result));
1292
1293 const auto& res_domains2 = getResolverDomains(mDnsClient.resolvService(), TEST_NETID);
1294 // Expect 4 valid domain, duplicate domains are removed.
1295 EXPECT_EQ(DUPLICATED_DOMAIN_NUM + 1U, res_domains2.size());
1296 EXPECT_THAT(
1297 std::vector<std::string>({"domain0.org", "domain1.org", "domain2.org", domian_name2}),
1298 testing::ElementsAreArray(res_domains2));
1299}
1300
Mike Yu0a1c53d2018-11-26 13:26:21 +09001301// If we move this function to dns_responder_client, it will complicate the dependency need of
1302// dns_tls_frontend.h.
1303static void setupTlsServers(const std::vector<std::string>& servers,
waynema0e73c2e2019-07-31 15:04:08 +08001304 std::vector<std::unique_ptr<test::DnsTlsFrontend>>* tls) {
Xiao Ma09b71022018-12-11 17:56:32 +09001305 constexpr char listen_udp[] = "53";
1306 constexpr char listen_tls[] = "853";
Mike Yu0a1c53d2018-11-26 13:26:21 +09001307
1308 for (const auto& server : servers) {
1309 auto t = std::make_unique<test::DnsTlsFrontend>(server, listen_tls, server, listen_udp);
1310 t = std::make_unique<test::DnsTlsFrontend>(server, listen_tls, server, listen_udp);
1311 t->startServer();
Mike Yu0a1c53d2018-11-26 13:26:21 +09001312 tls->push_back(std::move(t));
1313 }
1314}
1315
Mike Yu0a1c53d2018-11-26 13:26:21 +09001316TEST_F(ResolverTest, MaxServerPrune_Binder) {
Mike Yu0a1c53d2018-11-26 13:26:21 +09001317 std::vector<std::string> domains;
1318 std::vector<std::unique_ptr<test::DNSResponder>> dns;
1319 std::vector<std::unique_ptr<test::DnsTlsFrontend>> tls;
1320 std::vector<std::string> servers;
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +09001321 std::vector<DnsResponderClient::Mapping> mappings;
Mike Yu0a1c53d2018-11-26 13:26:21 +09001322
1323 for (unsigned i = 0; i < MAXDNSRCH + 1; i++) {
1324 domains.push_back(StringPrintf("example%u.com", i));
1325 }
Bernie Innocentia5c7b7b2019-01-17 21:28:24 +09001326 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupMappings(1, domains, &mappings));
1327 ASSERT_NO_FATAL_FAILURE(mDnsClient.SetupDNSServers(MAXNS + 1, mappings, &dns, &servers));
waynema0e73c2e2019-07-31 15:04:08 +08001328 ASSERT_NO_FATAL_FAILURE(setupTlsServers(servers, &tls));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001329
waynema0e73c2e2019-07-31 15:04:08 +08001330 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, domains, kDefaultParams,
1331 kDefaultPrivateDnsHostName));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001332
Mike Yu383855b2019-01-15 17:53:27 +08001333 // If the private DNS validation hasn't completed yet before backend DNS servers stop,
1334 // TLS servers will get stuck in handleOneRequest(), which causes this test stuck in
1335 // ~DnsTlsFrontend() because the TLS server loop threads can't be terminated.
1336 // So, wait for private DNS validation done before stopping backend DNS servers.
1337 for (int i = 0; i < MAXNS; i++) {
chenbruceaff85842019-05-31 15:46:42 +08001338 LOG(INFO) << "Waiting for private DNS validation on " << tls[i]->listen_address() << ".";
Mike Yu724f77d2019-08-16 11:14:50 +08001339 EXPECT_TRUE(WaitForPrivateDnsValidation(tls[i]->listen_address(), true));
chenbruceaff85842019-05-31 15:46:42 +08001340 LOG(INFO) << "private DNS validation on " << tls[i]->listen_address() << " done.";
Mike Yu383855b2019-01-15 17:53:27 +08001341 }
1342
Mike Yu0a1c53d2018-11-26 13:26:21 +09001343 std::vector<std::string> res_servers;
1344 std::vector<std::string> res_domains;
1345 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +09001346 res_params res_params;
Mike Yu0a1c53d2018-11-26 13:26:21 +09001347 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +08001348 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +08001349 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
1350 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
1351 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001352
1353 // Check the size of the stats and its contents.
1354 EXPECT_EQ(static_cast<size_t>(MAXNS), res_servers.size());
1355 EXPECT_EQ(static_cast<size_t>(MAXNS), res_tls_servers.size());
1356 EXPECT_EQ(static_cast<size_t>(MAXDNSRCH), res_domains.size());
1357 EXPECT_TRUE(std::equal(servers.begin(), servers.begin() + MAXNS, res_servers.begin()));
1358 EXPECT_TRUE(std::equal(servers.begin(), servers.begin() + MAXNS, res_tls_servers.begin()));
1359 EXPECT_TRUE(std::equal(domains.begin(), domains.begin() + MAXDNSRCH, res_domains.begin()));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001360}
1361
1362TEST_F(ResolverTest, ResolverStats) {
Xiao Ma09b71022018-12-11 17:56:32 +09001363 constexpr char listen_addr1[] = "127.0.0.4";
1364 constexpr char listen_addr2[] = "127.0.0.5";
1365 constexpr char listen_addr3[] = "127.0.0.6";
Mike Yu0a1c53d2018-11-26 13:26:21 +09001366
1367 // Set server 1 timeout.
Mike Yufc125e42019-05-15 20:41:28 +08001368 test::DNSResponder dns1(listen_addr1, "53", static_cast<ns_rcode>(-1));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001369 dns1.setResponseProbability(0.0);
1370 ASSERT_TRUE(dns1.startServer());
1371
1372 // Set server 2 responding server failure.
Xiao Ma09b71022018-12-11 17:56:32 +09001373 test::DNSResponder dns2(listen_addr2);
Mike Yu0a1c53d2018-11-26 13:26:21 +09001374 dns2.setResponseProbability(0.0);
1375 ASSERT_TRUE(dns2.startServer());
1376
1377 // Set server 3 workable.
Xiao Ma09b71022018-12-11 17:56:32 +09001378 test::DNSResponder dns3(listen_addr3);
1379 dns3.addMapping(kHelloExampleCom, ns_type::ns_t_a, "1.2.3.4");
Mike Yu0a1c53d2018-11-26 13:26:21 +09001380 ASSERT_TRUE(dns3.startServer());
1381
1382 std::vector<std::string> servers = {listen_addr1, listen_addr2, listen_addr3};
Xiao Ma09b71022018-12-11 17:56:32 +09001383 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001384
1385 dns3.clearQueries();
Xiao Ma09b71022018-12-11 17:56:32 +09001386 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
Mike Yu0a1c53d2018-11-26 13:26:21 +09001387 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
Xiao Ma09b71022018-12-11 17:56:32 +09001388 size_t found = GetNumQueries(dns3, kHelloExampleCom);
Mike Yu0a1c53d2018-11-26 13:26:21 +09001389 EXPECT_LE(1U, found);
1390 std::string result_str = ToString(result);
1391 EXPECT_TRUE(result_str == "1.2.3.4") << ", result_str='" << result_str << "'";
1392
1393 std::vector<std::string> res_servers;
1394 std::vector<std::string> res_domains;
1395 std::vector<std::string> res_tls_servers;
Bernie Innocenti758005f2019-02-19 18:08:36 +09001396 res_params res_params;
Mike Yu0a1c53d2018-11-26 13:26:21 +09001397 std::vector<ResolverStats> res_stats;
Ken Chen92bed612018-12-22 21:46:55 +08001398 int wait_for_pending_req_timeout_count;
Luke Huangf8215372019-11-22 11:53:41 +08001399 ASSERT_TRUE(DnsResponderClient::GetResolverInfo(
1400 mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers,
1401 &res_params, &res_stats, &wait_for_pending_req_timeout_count));
Mike Yu0a1c53d2018-11-26 13:26:21 +09001402
1403 EXPECT_EQ(1, res_stats[0].timeouts);
1404 EXPECT_EQ(1, res_stats[1].errors);
1405 EXPECT_EQ(1, res_stats[2].successes);
Mike Yu0a1c53d2018-11-26 13:26:21 +09001406}
1407
Ken Chenb9fa2062018-11-13 21:51:13 +08001408// Test what happens if the specified TLS server is nonexistent.
1409TEST_F(ResolverTest, GetHostByName_TlsMissing) {
Xiao Ma09b71022018-12-11 17:56:32 +09001410 constexpr char listen_addr[] = "127.0.0.3";
1411 constexpr char host_name[] = "tlsmissing.example.com.";
1412
1413 test::DNSResponder dns;
1414 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.3"}});
Luke Huangf8215372019-11-22 11:53:41 +08001415 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001416
1417 // There's nothing listening on this address, so validation will either fail or
1418 /// hang. Either way, queries will continue to flow to the DNSResponder.
waynema0e73c2e2019-07-31 15:04:08 +08001419 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Ken Chenb9fa2062018-11-13 21:51:13 +08001420
1421 const hostent* result;
1422
1423 result = gethostbyname("tlsmissing");
1424 ASSERT_FALSE(result == nullptr);
1425 EXPECT_EQ("1.2.3.3", ToString(result));
1426
1427 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001428 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001429}
1430
1431// Test what happens if the specified TLS server replies with garbage.
1432TEST_F(ResolverTest, GetHostByName_TlsBroken) {
Xiao Ma09b71022018-12-11 17:56:32 +09001433 constexpr char listen_addr[] = "127.0.0.3";
1434 constexpr char host_name1[] = "tlsbroken1.example.com.";
1435 constexpr char host_name2[] = "tlsbroken2.example.com.";
1436 const std::vector<DnsRecord> records = {
1437 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1438 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1439 };
1440
1441 test::DNSResponder dns;
1442 StartDns(dns, records);
Luke Huangf8215372019-11-22 11:53:41 +08001443 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001444
1445 // Bind the specified private DNS socket but don't respond to any client sockets yet.
1446 int s = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
1447 ASSERT_TRUE(s >= 0);
1448 struct sockaddr_in tlsServer = {
Luke Huangf8215372019-11-22 11:53:41 +08001449 .sin_family = AF_INET,
1450 .sin_port = htons(853),
Ken Chenb9fa2062018-11-13 21:51:13 +08001451 };
1452 ASSERT_TRUE(inet_pton(AF_INET, listen_addr, &tlsServer.sin_addr));
1453 ASSERT_TRUE(enableSockopt(s, SOL_SOCKET, SO_REUSEPORT).ok());
1454 ASSERT_TRUE(enableSockopt(s, SOL_SOCKET, SO_REUSEADDR).ok());
1455 ASSERT_FALSE(bind(s, reinterpret_cast<struct sockaddr*>(&tlsServer), sizeof(tlsServer)));
1456 ASSERT_FALSE(listen(s, 1));
1457
1458 // Trigger TLS validation.
waynema0e73c2e2019-07-31 15:04:08 +08001459 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Ken Chenb9fa2062018-11-13 21:51:13 +08001460
1461 struct sockaddr_storage cliaddr;
1462 socklen_t sin_size = sizeof(cliaddr);
Luke Huangf8215372019-11-22 11:53:41 +08001463 int new_fd = accept4(s, reinterpret_cast<struct sockaddr*>(&cliaddr), &sin_size, SOCK_CLOEXEC);
Ken Chenb9fa2062018-11-13 21:51:13 +08001464 ASSERT_TRUE(new_fd > 0);
1465
1466 // We've received the new file descriptor but not written to it or closed, so the
1467 // validation is still pending. Queries should still flow correctly because the
1468 // server is not used until validation succeeds.
1469 const hostent* result;
1470 result = gethostbyname("tlsbroken1");
1471 ASSERT_FALSE(result == nullptr);
1472 EXPECT_EQ("1.2.3.1", ToString(result));
1473
1474 // Now we cause the validation to fail.
1475 std::string garbage = "definitely not a valid TLS ServerHello";
1476 write(new_fd, garbage.data(), garbage.size());
1477 close(new_fd);
1478
1479 // Validation failure shouldn't interfere with lookups, because lookups won't be sent
1480 // to the TLS server unless validation succeeds.
1481 result = gethostbyname("tlsbroken2");
1482 ASSERT_FALSE(result == nullptr);
1483 EXPECT_EQ("1.2.3.2", ToString(result));
1484
1485 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001486 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001487 close(s);
1488}
1489
1490TEST_F(ResolverTest, GetHostByName_Tls) {
Xiao Ma09b71022018-12-11 17:56:32 +09001491 constexpr char listen_addr[] = "127.0.0.3";
1492 constexpr char listen_udp[] = "53";
1493 constexpr char listen_tls[] = "853";
1494 constexpr char host_name1[] = "tls1.example.com.";
1495 constexpr char host_name2[] = "tls2.example.com.";
1496 constexpr char host_name3[] = "tls3.example.com.";
1497 const std::vector<DnsRecord> records = {
1498 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1499 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1500 {host_name3, ns_type::ns_t_a, "1.2.3.3"},
1501 };
1502
1503 test::DNSResponder dns;
1504 StartDns(dns, records);
Luke Huangf8215372019-11-22 11:53:41 +08001505 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001506
1507 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1508 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08001509 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08001510 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Ken Chenb9fa2062018-11-13 21:51:13 +08001511
Mike Yu724f77d2019-08-16 11:14:50 +08001512 const hostent* result = gethostbyname("tls1");
Ken Chenb9fa2062018-11-13 21:51:13 +08001513 ASSERT_FALSE(result == nullptr);
1514 EXPECT_EQ("1.2.3.1", ToString(result));
1515
1516 // Wait for query to get counted.
1517 EXPECT_TRUE(tls.waitForQueries(2, 5000));
1518
1519 // Stop the TLS server. Since we're in opportunistic mode, queries will
1520 // fall back to the locally-assigned (clear text) nameservers.
1521 tls.stopServer();
1522
1523 dns.clearQueries();
1524 result = gethostbyname("tls2");
1525 EXPECT_FALSE(result == nullptr);
1526 EXPECT_EQ("1.2.3.2", ToString(result));
1527 const auto queries = dns.queries();
1528 EXPECT_EQ(1U, queries.size());
waynema29253052019-08-20 11:26:08 +08001529 EXPECT_EQ("tls2.example.com.", queries[0].name);
1530 EXPECT_EQ(ns_t_a, queries[0].type);
Ken Chenb9fa2062018-11-13 21:51:13 +08001531
1532 // Reset the resolvers without enabling TLS. Queries should still be routed
1533 // to the UDP endpoint.
Xiao Ma09b71022018-12-11 17:56:32 +09001534 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001535
1536 result = gethostbyname("tls3");
1537 ASSERT_FALSE(result == nullptr);
1538 EXPECT_EQ("1.2.3.3", ToString(result));
Ken Chenb9fa2062018-11-13 21:51:13 +08001539}
1540
Ken Chenb9fa2062018-11-13 21:51:13 +08001541TEST_F(ResolverTest, GetHostByName_TlsFailover) {
Xiao Ma09b71022018-12-11 17:56:32 +09001542 constexpr char listen_addr1[] = "127.0.0.3";
1543 constexpr char listen_addr2[] = "127.0.0.4";
1544 constexpr char listen_udp[] = "53";
1545 constexpr char listen_tls[] = "853";
1546 constexpr char host_name1[] = "tlsfailover1.example.com.";
1547 constexpr char host_name2[] = "tlsfailover2.example.com.";
1548 const std::vector<DnsRecord> records1 = {
1549 {host_name1, ns_type::ns_t_a, "1.2.3.1"},
1550 {host_name2, ns_type::ns_t_a, "1.2.3.2"},
1551 };
1552 const std::vector<DnsRecord> records2 = {
1553 {host_name1, ns_type::ns_t_a, "1.2.3.3"},
1554 {host_name2, ns_type::ns_t_a, "1.2.3.4"},
1555 };
1556
1557 test::DNSResponder dns1(listen_addr1);
1558 test::DNSResponder dns2(listen_addr2);
1559 StartDns(dns1, records1);
1560 StartDns(dns2, records2);
1561
Luke Huangf8215372019-11-22 11:53:41 +08001562 std::vector<std::string> servers = {listen_addr1, listen_addr2};
Ken Chenb9fa2062018-11-13 21:51:13 +08001563
1564 test::DnsTlsFrontend tls1(listen_addr1, listen_tls, listen_addr1, listen_udp);
1565 test::DnsTlsFrontend tls2(listen_addr2, listen_tls, listen_addr2, listen_udp);
1566 ASSERT_TRUE(tls1.startServer());
1567 ASSERT_TRUE(tls2.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08001568 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
1569 kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08001570 EXPECT_TRUE(WaitForPrivateDnsValidation(tls1.listen_address(), true));
1571 EXPECT_TRUE(WaitForPrivateDnsValidation(tls2.listen_address(), true));
Ken Chenb9fa2062018-11-13 21:51:13 +08001572
Mike Yu724f77d2019-08-16 11:14:50 +08001573 const hostent* result = gethostbyname("tlsfailover1");
Ken Chenb9fa2062018-11-13 21:51:13 +08001574 ASSERT_FALSE(result == nullptr);
1575 EXPECT_EQ("1.2.3.1", ToString(result));
1576
1577 // Wait for query to get counted.
1578 EXPECT_TRUE(tls1.waitForQueries(2, 5000));
1579 // No new queries should have reached tls2.
1580 EXPECT_EQ(1, tls2.queries());
1581
1582 // Stop tls1. Subsequent queries should attempt to reach tls1, fail, and retry to tls2.
1583 tls1.stopServer();
1584
1585 result = gethostbyname("tlsfailover2");
1586 EXPECT_EQ("1.2.3.4", ToString(result));
1587
1588 // Wait for query to get counted.
1589 EXPECT_TRUE(tls2.waitForQueries(2, 5000));
1590
1591 // No additional queries should have reached the insecure servers.
1592 EXPECT_EQ(2U, dns1.queries().size());
1593 EXPECT_EQ(2U, dns2.queries().size());
1594
1595 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001596 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Ken Chenb9fa2062018-11-13 21:51:13 +08001597}
1598
1599TEST_F(ResolverTest, GetHostByName_BadTlsName) {
Xiao Ma09b71022018-12-11 17:56:32 +09001600 constexpr char listen_addr[] = "127.0.0.3";
1601 constexpr char listen_udp[] = "53";
1602 constexpr char listen_tls[] = "853";
1603 constexpr char host_name[] = "badtlsname.example.com.";
1604
1605 test::DNSResponder dns;
1606 StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.1"}});
Luke Huangf8215372019-11-22 11:53:41 +08001607 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001608
1609 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1610 ASSERT_TRUE(tls.startServer());
Xiao Ma09b71022018-12-11 17:56:32 +09001611 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
waynema0e73c2e2019-07-31 15:04:08 +08001612 kDefaultIncorrectPrivateDnsHostName));
Ken Chenb9fa2062018-11-13 21:51:13 +08001613
waynema0e73c2e2019-07-31 15:04:08 +08001614 // The TLS handshake would fail because the name of TLS server doesn't
1615 // match with TLS server's certificate.
Mike Yu724f77d2019-08-16 11:14:50 +08001616 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), false));
Ken Chenb9fa2062018-11-13 21:51:13 +08001617
1618 // The query should fail hard, because a name was specified.
1619 EXPECT_EQ(nullptr, gethostbyname("badtlsname"));
1620
1621 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001622 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001623}
1624
1625TEST_F(ResolverTest, GetAddrInfo_Tls) {
Xiao Ma09b71022018-12-11 17:56:32 +09001626 constexpr char listen_addr[] = "127.0.0.3";
1627 constexpr char listen_udp[] = "53";
1628 constexpr char listen_tls[] = "853";
1629 constexpr char host_name[] = "addrinfotls.example.com.";
1630 const std::vector<DnsRecord> records = {
1631 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1632 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1633 };
1634
1635 test::DNSResponder dns;
1636 StartDns(dns, records);
Luke Huangf8215372019-11-22 11:53:41 +08001637 std::vector<std::string> servers = {listen_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001638
1639 test::DnsTlsFrontend tls(listen_addr, listen_tls, listen_addr, listen_udp);
1640 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08001641 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
1642 kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08001643 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Ken Chenb9fa2062018-11-13 21:51:13 +08001644
1645 dns.clearQueries();
1646 ScopedAddrinfo result = safe_getaddrinfo("addrinfotls", nullptr, nullptr);
1647 EXPECT_TRUE(result != nullptr);
1648 size_t found = GetNumQueries(dns, host_name);
1649 EXPECT_LE(1U, found);
1650 // Could be A or AAAA
1651 std::string result_str = ToString(result);
1652 EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
Luke Huangf8215372019-11-22 11:53:41 +08001653 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +08001654 // Wait for both A and AAAA queries to get counted.
1655 EXPECT_TRUE(tls.waitForQueries(3, 5000));
1656
1657 // Clear TLS bit.
Xiao Ma09b71022018-12-11 17:56:32 +09001658 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
Ken Chenb9fa2062018-11-13 21:51:13 +08001659}
1660
1661TEST_F(ResolverTest, TlsBypass) {
1662 const char OFF[] = "off";
1663 const char OPPORTUNISTIC[] = "opportunistic";
1664 const char STRICT[] = "strict";
1665
1666 const char GETHOSTBYNAME[] = "gethostbyname";
1667 const char GETADDRINFO[] = "getaddrinfo";
1668 const char GETADDRINFOFORNET[] = "getaddrinfofornet";
1669
1670 const unsigned BYPASS_NETID = NETID_USE_LOCAL_NAMESERVERS | TEST_NETID;
1671
Ken Chenb9fa2062018-11-13 21:51:13 +08001672 const char ADDR4[] = "192.0.2.1";
1673 const char ADDR6[] = "2001:db8::1";
1674
1675 const char cleartext_addr[] = "127.0.0.53";
1676 const char cleartext_port[] = "53";
1677 const char tls_port[] = "853";
Luke Huangf8215372019-11-22 11:53:41 +08001678 const std::vector<std::string> servers = {cleartext_addr};
Ken Chenb9fa2062018-11-13 21:51:13 +08001679
Xiao Ma09b71022018-12-11 17:56:32 +09001680 test::DNSResponder dns(cleartext_addr);
Ken Chenb9fa2062018-11-13 21:51:13 +08001681 ASSERT_TRUE(dns.startServer());
1682
1683 test::DnsTlsFrontend tls(cleartext_addr, tls_port, cleartext_addr, cleartext_port);
Mike Yudd4ac2d2019-05-31 16:52:11 +08001684 ASSERT_TRUE(tls.startServer());
Ken Chenb9fa2062018-11-13 21:51:13 +08001685
Luke Huangf8215372019-11-22 11:53:41 +08001686 // clang-format off
Ken Chenb9fa2062018-11-13 21:51:13 +08001687 struct TestConfig {
1688 const std::string mode;
1689 const bool withWorkingTLS;
1690 const std::string method;
1691
1692 std::string asHostName() const {
Luke Huangf8215372019-11-22 11:53:41 +08001693 return StringPrintf("%s.%s.%s.", mode.c_str(), withWorkingTLS ? "tlsOn" : "tlsOff",
Ken Chenb9fa2062018-11-13 21:51:13 +08001694 method.c_str());
1695 }
1696 } testConfigs[]{
Ken Chenb9fa2062018-11-13 21:51:13 +08001697 {OFF, true, GETHOSTBYNAME},
1698 {OPPORTUNISTIC, true, GETHOSTBYNAME},
1699 {STRICT, true, GETHOSTBYNAME},
Ken Chenb9fa2062018-11-13 21:51:13 +08001700 {OFF, true, GETADDRINFO},
1701 {OPPORTUNISTIC, true, GETADDRINFO},
1702 {STRICT, true, GETADDRINFO},
Ken Chenb9fa2062018-11-13 21:51:13 +08001703 {OFF, true, GETADDRINFOFORNET},
1704 {OPPORTUNISTIC, true, GETADDRINFOFORNET},
1705 {STRICT, true, GETADDRINFOFORNET},
Mike Yudd4ac2d2019-05-31 16:52:11 +08001706 {OFF, false, GETHOSTBYNAME},
1707 {OPPORTUNISTIC, false, GETHOSTBYNAME},
1708 {STRICT, false, GETHOSTBYNAME},
1709 {OFF, false, GETADDRINFO},
1710 {OPPORTUNISTIC, false, GETADDRINFO},
1711 {STRICT, false, GETADDRINFO},
1712 {OFF, false, GETADDRINFOFORNET},
1713 {OPPORTUNISTIC, false, GETADDRINFOFORNET},
1714 {STRICT, false, GETADDRINFOFORNET},
Ken Chenb9fa2062018-11-13 21:51:13 +08001715 };
Luke Huangf8215372019-11-22 11:53:41 +08001716 // clang-format on
Ken Chenb9fa2062018-11-13 21:51:13 +08001717
1718 for (const auto& config : testConfigs) {
1719 const std::string testHostName = config.asHostName();
1720 SCOPED_TRACE(testHostName);
1721
1722 // Don't tempt test bugs due to caching.
1723 const char* host_name = testHostName.c_str();
1724 dns.addMapping(host_name, ns_type::ns_t_a, ADDR4);
1725 dns.addMapping(host_name, ns_type::ns_t_aaaa, ADDR6);
1726
Mike Yudd4ac2d2019-05-31 16:52:11 +08001727 if (config.withWorkingTLS) {
1728 if (!tls.running()) {
1729 ASSERT_TRUE(tls.startServer());
1730 }
1731 } else {
1732 if (tls.running()) {
1733 ASSERT_TRUE(tls.stopServer());
1734 }
1735 }
Ken Chenb9fa2062018-11-13 21:51:13 +08001736
1737 if (config.mode == OFF) {
Xiao Ma09b71022018-12-11 17:56:32 +09001738 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers, kDefaultSearchDomains,
1739 kDefaultParams));
Ken Chenb9fa2062018-11-13 21:51:13 +08001740 } else if (config.mode == OPPORTUNISTIC) {
Xiao Ma09b71022018-12-11 17:56:32 +09001741 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08001742 kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08001743
1744 // Wait for the validation event. If the server is running, the validation should
1745 // be successful; otherwise, the validation should be failed.
1746 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), config.withWorkingTLS));
Ken Chenb9fa2062018-11-13 21:51:13 +08001747 } else if (config.mode == STRICT) {
Xiao Ma09b71022018-12-11 17:56:32 +09001748 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08001749 kDefaultParams, kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08001750
1751 // Wait for the validation event.
1752 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), config.withWorkingTLS));
Ken Chenb9fa2062018-11-13 21:51:13 +08001753 }
Mike Yudd4ac2d2019-05-31 16:52:11 +08001754 tls.clearQueries();
Ken Chenb9fa2062018-11-13 21:51:13 +08001755
1756 const hostent* h_result = nullptr;
1757 ScopedAddrinfo ai_result;
1758
1759 if (config.method == GETHOSTBYNAME) {
1760 ASSERT_EQ(0, setNetworkForResolv(BYPASS_NETID));
1761 h_result = gethostbyname(host_name);
1762
1763 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
1764 ASSERT_FALSE(h_result == nullptr);
1765 ASSERT_EQ(4, h_result->h_length);
1766 ASSERT_FALSE(h_result->h_addr_list[0] == nullptr);
1767 EXPECT_EQ(ADDR4, ToString(h_result));
1768 EXPECT_TRUE(h_result->h_addr_list[1] == nullptr);
1769 } else if (config.method == GETADDRINFO) {
1770 ASSERT_EQ(0, setNetworkForResolv(BYPASS_NETID));
1771 ai_result = safe_getaddrinfo(host_name, nullptr, nullptr);
1772 EXPECT_TRUE(ai_result != nullptr);
1773
1774 EXPECT_LE(1U, GetNumQueries(dns, host_name));
1775 // Could be A or AAAA
1776 const std::string result_str = ToString(ai_result);
1777 EXPECT_TRUE(result_str == ADDR4 || result_str == ADDR6)
Luke Huangf8215372019-11-22 11:53:41 +08001778 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +08001779 } else if (config.method == GETADDRINFOFORNET) {
1780 addrinfo* raw_ai_result = nullptr;
1781 EXPECT_EQ(0, android_getaddrinfofornet(host_name, /*servname=*/nullptr,
1782 /*hints=*/nullptr, BYPASS_NETID, MARK_UNSET,
1783 &raw_ai_result));
1784 ai_result.reset(raw_ai_result);
1785
1786 EXPECT_LE(1U, GetNumQueries(dns, host_name));
1787 // Could be A or AAAA
1788 const std::string result_str = ToString(ai_result);
1789 EXPECT_TRUE(result_str == ADDR4 || result_str == ADDR6)
Luke Huangf8215372019-11-22 11:53:41 +08001790 << ", result_str='" << result_str << "'";
Ken Chenb9fa2062018-11-13 21:51:13 +08001791 }
1792
Mike Yudd4ac2d2019-05-31 16:52:11 +08001793 EXPECT_EQ(0, tls.queries());
Ken Chenb9fa2062018-11-13 21:51:13 +08001794
1795 // Clear per-process resolv netid.
1796 ASSERT_EQ(0, setNetworkForResolv(NETID_UNSET));
Ken Chenb9fa2062018-11-13 21:51:13 +08001797 dns.clearQueries();
1798 }
Ken Chenb9fa2062018-11-13 21:51:13 +08001799}
1800
1801TEST_F(ResolverTest, StrictMode_NoTlsServers) {
Xiao Ma09b71022018-12-11 17:56:32 +09001802 constexpr char cleartext_addr[] = "127.0.0.53";
Luke Huangf8215372019-11-22 11:53:41 +08001803 const std::vector<std::string> servers = {cleartext_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001804 constexpr char host_name[] = "strictmode.notlsips.example.com.";
1805 const std::vector<DnsRecord> records = {
1806 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1807 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1808 };
Ken Chenb9fa2062018-11-13 21:51:13 +08001809
Xiao Ma09b71022018-12-11 17:56:32 +09001810 test::DNSResponder dns(cleartext_addr);
1811 StartDns(dns, records);
Ken Chenb9fa2062018-11-13 21:51:13 +08001812
waynema0e73c2e2019-07-31 15:04:08 +08001813 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
1814 kDefaultIncorrectPrivateDnsHostName));
Ken Chenb9fa2062018-11-13 21:51:13 +08001815
1816 addrinfo* ai_result = nullptr;
1817 EXPECT_NE(0, getaddrinfo(host_name, nullptr, nullptr, &ai_result));
1818 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
1819}
Luke Huang94b10b92018-11-21 20:13:38 +08001820
1821namespace {
1822
Luke Huang70931aa2019-01-31 11:57:41 +08001823int getAsyncResponse(int fd, int* rcode, uint8_t* buf, int bufLen) {
Luke Huang94b10b92018-11-21 20:13:38 +08001824 struct pollfd wait_fd[1];
1825 wait_fd[0].fd = fd;
1826 wait_fd[0].events = POLLIN;
1827 short revents;
1828 int ret;
1829
1830 ret = poll(wait_fd, 1, -1);
1831 revents = wait_fd[0].revents;
1832 if (revents & POLLIN) {
1833 int n = resNetworkResult(fd, rcode, buf, bufLen);
Luke Huangba7bef92018-12-26 16:53:03 +08001834 // Verify that resNetworkResult() closed the fd
1835 char dummy;
1836 EXPECT_EQ(-1, read(fd, &dummy, sizeof dummy));
1837 EXPECT_EQ(EBADF, errno);
Luke Huang94b10b92018-11-21 20:13:38 +08001838 return n;
1839 }
1840 return -1;
1841}
1842
Luke Huang70931aa2019-01-31 11:57:41 +08001843std::string toString(uint8_t* buf, int bufLen, int ipType) {
Luke Huang94b10b92018-11-21 20:13:38 +08001844 ns_msg handle;
1845 int ancount, n = 0;
1846 ns_rr rr;
1847
Luke Huangf8215372019-11-22 11:53:41 +08001848 if (ns_initparse((const uint8_t*)buf, bufLen, &handle) >= 0) {
Luke Huang94b10b92018-11-21 20:13:38 +08001849 ancount = ns_msg_count(handle, ns_s_an);
1850 if (ns_parserr(&handle, ns_s_an, n, &rr) == 0) {
Luke Huang70931aa2019-01-31 11:57:41 +08001851 const uint8_t* rdata = ns_rr_rdata(rr);
Luke Huang94b10b92018-11-21 20:13:38 +08001852 char buffer[INET6_ADDRSTRLEN];
Luke Huangf8215372019-11-22 11:53:41 +08001853 if (inet_ntop(ipType, (const char*)rdata, buffer, sizeof(buffer))) {
Luke Huang94b10b92018-11-21 20:13:38 +08001854 return buffer;
1855 }
1856 }
1857 }
1858 return "";
1859}
1860
1861int dns_open_proxy() {
1862 int s = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
1863 if (s == -1) {
1864 return -1;
1865 }
1866 const int one = 1;
1867 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1868
1869 static const struct sockaddr_un proxy_addr = {
1870 .sun_family = AF_UNIX,
1871 .sun_path = "/dev/socket/dnsproxyd",
1872 };
1873
Luke Huangf8215372019-11-22 11:53:41 +08001874 if (TEMP_FAILURE_RETRY(connect(s, (const struct sockaddr*)&proxy_addr, sizeof(proxy_addr))) !=
Luke Huang94b10b92018-11-21 20:13:38 +08001875 0) {
1876 close(s);
1877 return -1;
1878 }
1879
1880 return s;
1881}
1882
Luke Huangba7bef92018-12-26 16:53:03 +08001883void expectAnswersValid(int fd, int ipType, const std::string& expectedAnswer) {
1884 int rcode = -1;
1885 uint8_t buf[MAXPACKET] = {};
1886
1887 int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
1888 EXPECT_GT(res, 0);
1889 EXPECT_EQ(expectedAnswer, toString(buf, res, ipType));
1890}
1891
1892void expectAnswersNotValid(int fd, int expectedErrno) {
1893 int rcode = -1;
1894 uint8_t buf[MAXPACKET] = {};
1895
1896 int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
1897 EXPECT_EQ(expectedErrno, res);
1898}
1899
Luke Huang94b10b92018-11-21 20:13:38 +08001900} // namespace
1901
1902TEST_F(ResolverTest, Async_NormalQueryV4V6) {
Xiao Ma09b71022018-12-11 17:56:32 +09001903 constexpr char listen_addr[] = "127.0.0.4";
1904 constexpr char host_name[] = "howdy.example.com.";
1905 const std::vector<DnsRecord> records = {
1906 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1907 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1908 };
1909
1910 test::DNSResponder dns(listen_addr);
1911 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08001912 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001913 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08001914
Luke Huangba7bef92018-12-26 16:53:03 +08001915 int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
1916 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001917 EXPECT_TRUE(fd1 != -1);
1918 EXPECT_TRUE(fd2 != -1);
1919
Luke Huang70931aa2019-01-31 11:57:41 +08001920 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001921 int rcode;
1922 int res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
1923 EXPECT_GT(res, 0);
1924 EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
1925
1926 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
1927 EXPECT_GT(res, 0);
1928 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
1929
1930 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
1931
1932 // Re-query verify cache works
Luke Huangba7bef92018-12-26 16:53:03 +08001933 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
1934 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001935
1936 EXPECT_TRUE(fd1 != -1);
1937 EXPECT_TRUE(fd2 != -1);
1938
1939 res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
1940 EXPECT_GT(res, 0);
1941 EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
1942
1943 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
1944 EXPECT_GT(res, 0);
1945 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
1946
1947 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
1948}
1949
1950TEST_F(ResolverTest, Async_BadQuery) {
Xiao Ma09b71022018-12-11 17:56:32 +09001951 constexpr char listen_addr[] = "127.0.0.4";
1952 constexpr char host_name[] = "howdy.example.com.";
1953 const std::vector<DnsRecord> records = {
1954 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1955 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1956 };
1957
1958 test::DNSResponder dns(listen_addr);
1959 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08001960 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09001961 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08001962
1963 static struct {
1964 int fd;
1965 const char* dname;
1966 const int queryType;
1967 const int expectRcode;
1968 } kTestData[] = {
Luke Huangba7bef92018-12-26 16:53:03 +08001969 {-1, "", ns_t_aaaa, 0},
1970 {-1, "as65ass46", ns_t_aaaa, 0},
1971 {-1, "454564564564", ns_t_aaaa, 0},
1972 {-1, "h645235", ns_t_a, 0},
1973 {-1, "www.google.com", ns_t_a, 0},
Luke Huang94b10b92018-11-21 20:13:38 +08001974 };
1975
1976 for (auto& td : kTestData) {
1977 SCOPED_TRACE(td.dname);
Luke Huangba7bef92018-12-26 16:53:03 +08001978 td.fd = resNetworkQuery(TEST_NETID, td.dname, ns_c_in, td.queryType, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08001979 EXPECT_TRUE(td.fd != -1);
1980 }
1981
1982 // dns_responder return empty resp(packet only contains query part) with no error currently
1983 for (const auto& td : kTestData) {
Luke Huang70931aa2019-01-31 11:57:41 +08001984 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08001985 int rcode;
1986 SCOPED_TRACE(td.dname);
1987 int res = getAsyncResponse(td.fd, &rcode, buf, MAXPACKET);
1988 EXPECT_GT(res, 0);
1989 EXPECT_EQ(rcode, td.expectRcode);
1990 }
1991}
1992
1993TEST_F(ResolverTest, Async_EmptyAnswer) {
Xiao Ma09b71022018-12-11 17:56:32 +09001994 constexpr char listen_addr[] = "127.0.0.4";
1995 constexpr char host_name[] = "howdy.example.com.";
1996 const std::vector<DnsRecord> records = {
1997 {host_name, ns_type::ns_t_a, "1.2.3.4"},
1998 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
1999 };
2000
2001 test::DNSResponder dns(listen_addr);
2002 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08002003 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002004 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08002005
Luke Huang9c264bb2018-12-18 16:44:41 +08002006 // TODO: Disable retry to make this test explicit.
2007 auto& cv = dns.getCv();
2008 auto& cvMutex = dns.getCvMutex();
2009 int fd1;
2010 // Wait on the condition variable to ensure that the DNS server has handled our first query.
2011 {
2012 std::unique_lock lk(cvMutex);
Luke Huangba7bef92018-12-26 16:53:03 +08002013 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
Luke Huang9c264bb2018-12-18 16:44:41 +08002014 EXPECT_TRUE(fd1 != -1);
2015 EXPECT_EQ(std::cv_status::no_timeout, cv.wait_for(lk, std::chrono::seconds(1)));
2016 }
Luke Huang94b10b92018-11-21 20:13:38 +08002017
Luke Huang94b10b92018-11-21 20:13:38 +08002018 dns.setResponseProbability(0.0);
Luke Huang94b10b92018-11-21 20:13:38 +08002019
Luke Huangba7bef92018-12-26 16:53:03 +08002020 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08002021 EXPECT_TRUE(fd2 != -1);
2022
Luke Huangba7bef92018-12-26 16:53:03 +08002023 int fd3 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08002024 EXPECT_TRUE(fd3 != -1);
2025
Luke Huang9c264bb2018-12-18 16:44:41 +08002026 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08002027 int rcode;
2028
Luke Huang9c264bb2018-12-18 16:44:41 +08002029 // expect no response
2030 int res = getAsyncResponse(fd3, &rcode, buf, MAXPACKET);
2031 EXPECT_EQ(-ETIMEDOUT, res);
Luke Huang94b10b92018-11-21 20:13:38 +08002032
Luke Huang9c264bb2018-12-18 16:44:41 +08002033 // expect no response
Luke Huang94b10b92018-11-21 20:13:38 +08002034 memset(buf, 0, MAXPACKET);
Luke Huang9c264bb2018-12-18 16:44:41 +08002035 res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
2036 EXPECT_EQ(-ETIMEDOUT, res);
Luke Huang94b10b92018-11-21 20:13:38 +08002037
Luke Huang94b10b92018-11-21 20:13:38 +08002038 dns.setResponseProbability(1.0);
Luke Huang94b10b92018-11-21 20:13:38 +08002039
Luke Huangba7bef92018-12-26 16:53:03 +08002040 int fd4 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
Luke Huang94b10b92018-11-21 20:13:38 +08002041 EXPECT_TRUE(fd4 != -1);
2042
2043 memset(buf, 0, MAXPACKET);
2044 res = getAsyncResponse(fd4, &rcode, buf, MAXPACKET);
2045 EXPECT_GT(res, 0);
2046 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
2047
2048 memset(buf, 0, MAXPACKET);
2049 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
2050 EXPECT_GT(res, 0);
2051 EXPECT_EQ("::1.2.3.4", toString(buf, res, AF_INET6));
2052}
2053
2054TEST_F(ResolverTest, Async_MalformedQuery) {
Xiao Ma09b71022018-12-11 17:56:32 +09002055 constexpr char listen_addr[] = "127.0.0.4";
2056 constexpr char host_name[] = "howdy.example.com.";
2057 const std::vector<DnsRecord> records = {
2058 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2059 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
2060 };
2061
2062 test::DNSResponder dns(listen_addr);
2063 StartDns(dns, records);
Luke Huang94b10b92018-11-21 20:13:38 +08002064 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002065 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huang94b10b92018-11-21 20:13:38 +08002066
2067 int fd = dns_open_proxy();
2068 EXPECT_TRUE(fd > 0);
2069
2070 const std::string badMsg = "16-52512#";
Xiao Ma09b71022018-12-11 17:56:32 +09002071 static const struct {
Luke Huang94b10b92018-11-21 20:13:38 +08002072 const std::string cmd;
2073 const int expectErr;
2074 } kTestData[] = {
Luke Huangba7bef92018-12-26 16:53:03 +08002075 // Too few arguments
Luke Huang94b10b92018-11-21 20:13:38 +08002076 {"resnsend " + badMsg + '\0', -EINVAL},
2077 // Bad netId
Luke Huangba7bef92018-12-26 16:53:03 +08002078 {"resnsend badnetId 0 " + badMsg + '\0', -EINVAL},
Luke Huang94b10b92018-11-21 20:13:38 +08002079 // Bad raw data
Luke Huangba7bef92018-12-26 16:53:03 +08002080 {"resnsend " + std::to_string(TEST_NETID) + " 0 " + badMsg + '\0', -EILSEQ},
Luke Huang94b10b92018-11-21 20:13:38 +08002081 };
2082
2083 for (unsigned int i = 0; i < std::size(kTestData); i++) {
2084 auto& td = kTestData[i];
2085 SCOPED_TRACE(td.cmd);
2086 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, td.cmd.c_str(), td.cmd.size()));
2087 EXPECT_EQ(rc, static_cast<ssize_t>(td.cmd.size()));
2088
2089 int32_t tmp;
2090 rc = TEMP_FAILURE_RETRY(read(fd, &tmp, sizeof(tmp)));
2091 EXPECT_TRUE(rc > 0);
2092 EXPECT_EQ(static_cast<int>(ntohl(tmp)), td.expectErr);
2093 }
2094 // Normal query with answer buffer
2095 // This is raw data of query "howdy.example.com" type 1 class 1
2096 std::string query = "81sBAAABAAAAAAAABWhvd2R5B2V4YW1wbGUDY29tAAABAAE=";
Luke Huangba7bef92018-12-26 16:53:03 +08002097 std::string cmd = "resnsend " + std::to_string(TEST_NETID) + " 0 " + query + '\0';
Luke Huang94b10b92018-11-21 20:13:38 +08002098 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size()));
2099 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size()));
2100
Luke Huang70931aa2019-01-31 11:57:41 +08002101 uint8_t smallBuf[1] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08002102 int rcode;
2103 rc = getAsyncResponse(fd, &rcode, smallBuf, 1);
Luke Huangba7bef92018-12-26 16:53:03 +08002104 EXPECT_EQ(-EMSGSIZE, rc);
Luke Huang94b10b92018-11-21 20:13:38 +08002105
2106 // Do the normal test with large buffer again
2107 fd = dns_open_proxy();
2108 EXPECT_TRUE(fd > 0);
2109 rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size()));
2110 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size()));
Luke Huang70931aa2019-01-31 11:57:41 +08002111 uint8_t buf[MAXPACKET] = {};
Luke Huang94b10b92018-11-21 20:13:38 +08002112 rc = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
2113 EXPECT_EQ("1.2.3.4", toString(buf, rc, AF_INET));
Mike Yu4f3747b2018-12-02 17:54:29 +09002114}
2115
Luke Huangba7bef92018-12-26 16:53:03 +08002116TEST_F(ResolverTest, Async_CacheFlags) {
Xiao Ma09b71022018-12-11 17:56:32 +09002117 constexpr char listen_addr[] = "127.0.0.4";
2118 constexpr char host_name[] = "howdy.example.com.";
Luke Huang40f5f492019-05-09 19:37:35 +08002119 constexpr char another_host_name[] = "howdy.example2.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002120 const std::vector<DnsRecord> records = {
2121 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2122 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
Luke Huang40f5f492019-05-09 19:37:35 +08002123 {another_host_name, ns_type::ns_t_a, "1.2.3.5"},
2124 {another_host_name, ns_type::ns_t_aaaa, "::1.2.3.5"},
Xiao Ma09b71022018-12-11 17:56:32 +09002125 };
2126
2127 test::DNSResponder dns(listen_addr);
2128 StartDns(dns, records);
Luke Huangba7bef92018-12-26 16:53:03 +08002129 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002130 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Luke Huangba7bef92018-12-26 16:53:03 +08002131
2132 // ANDROID_RESOLV_NO_CACHE_STORE
2133 int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
2134 ANDROID_RESOLV_NO_CACHE_STORE);
2135 EXPECT_TRUE(fd1 != -1);
2136 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
2137 ANDROID_RESOLV_NO_CACHE_STORE);
2138 EXPECT_TRUE(fd2 != -1);
2139 int fd3 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
2140 ANDROID_RESOLV_NO_CACHE_STORE);
2141 EXPECT_TRUE(fd3 != -1);
2142
2143 expectAnswersValid(fd3, AF_INET, "1.2.3.4");
2144 expectAnswersValid(fd2, AF_INET, "1.2.3.4");
2145 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
2146
2147 // No cache exists, expect 3 queries
2148 EXPECT_EQ(3U, GetNumQueries(dns, host_name));
2149
2150 // Re-query and cache
2151 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
2152
2153 EXPECT_TRUE(fd1 != -1);
2154
2155 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
2156
2157 // Now we have cache, expect 4 queries
2158 EXPECT_EQ(4U, GetNumQueries(dns, host_name));
2159
2160 // ANDROID_RESOLV_NO_CACHE_LOOKUP
2161 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
2162 ANDROID_RESOLV_NO_CACHE_LOOKUP);
2163 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
2164 ANDROID_RESOLV_NO_CACHE_LOOKUP);
2165
2166 EXPECT_TRUE(fd1 != -1);
2167 EXPECT_TRUE(fd2 != -1);
2168
2169 expectAnswersValid(fd2, AF_INET, "1.2.3.4");
2170 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
2171
2172 // Skip cache, expect 6 queries
2173 EXPECT_EQ(6U, GetNumQueries(dns, host_name));
2174
2175 // Re-query verify cache works
2176 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
2177 ANDROID_RESOLV_NO_CACHE_STORE);
2178 EXPECT_TRUE(fd1 != -1);
2179 expectAnswersValid(fd1, AF_INET, "1.2.3.4");
2180
2181 // Cache hits, expect still 6 queries
2182 EXPECT_EQ(6U, GetNumQueries(dns, host_name));
Luke Huanga1d74182019-03-19 17:30:36 +08002183
2184 // Start to verify if ANDROID_RESOLV_NO_CACHE_LOOKUP does write response into cache
2185 dns.clearQueries();
2186
2187 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
2188 ANDROID_RESOLV_NO_CACHE_LOOKUP);
2189 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
2190 ANDROID_RESOLV_NO_CACHE_LOOKUP);
2191
2192 EXPECT_TRUE(fd1 != -1);
2193 EXPECT_TRUE(fd2 != -1);
2194
2195 expectAnswersValid(fd2, AF_INET6, "::1.2.3.4");
2196 expectAnswersValid(fd1, AF_INET6, "::1.2.3.4");
2197
2198 // Skip cache, expect 2 queries
2199 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
2200
2201 // Re-query without flags
2202 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
2203 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
2204
2205 EXPECT_TRUE(fd1 != -1);
2206 EXPECT_TRUE(fd2 != -1);
2207
2208 expectAnswersValid(fd2, AF_INET6, "::1.2.3.4");
2209 expectAnswersValid(fd1, AF_INET6, "::1.2.3.4");
2210
2211 // Cache hits, expect still 2 queries
2212 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
Luke Huang40f5f492019-05-09 19:37:35 +08002213
2214 // Test both ANDROID_RESOLV_NO_CACHE_STORE and ANDROID_RESOLV_NO_CACHE_LOOKUP are set
2215 dns.clearQueries();
2216
2217 // Make sure that the cache of "howdy.example2.com" exists.
2218 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_aaaa, 0);
2219 EXPECT_TRUE(fd1 != -1);
2220 expectAnswersValid(fd1, AF_INET6, "::1.2.3.5");
2221 EXPECT_EQ(1U, GetNumQueries(dns, another_host_name));
2222
2223 // Re-query with testFlags
2224 const int testFlag = ANDROID_RESOLV_NO_CACHE_STORE | ANDROID_RESOLV_NO_CACHE_LOOKUP;
2225 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_aaaa, testFlag);
2226 EXPECT_TRUE(fd1 != -1);
2227 expectAnswersValid(fd1, AF_INET6, "::1.2.3.5");
2228 // Expect cache lookup is skipped.
2229 EXPECT_EQ(2U, GetNumQueries(dns, another_host_name));
2230
2231 // Do another query with testFlags
2232 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_a, testFlag);
2233 EXPECT_TRUE(fd1 != -1);
2234 expectAnswersValid(fd1, AF_INET, "1.2.3.5");
2235 // Expect cache lookup is skipped.
2236 EXPECT_EQ(3U, GetNumQueries(dns, another_host_name));
2237
2238 // Re-query with no flags
2239 fd1 = resNetworkQuery(TEST_NETID, "howdy.example2.com", ns_c_in, ns_t_a, 0);
2240 EXPECT_TRUE(fd1 != -1);
2241 expectAnswersValid(fd1, AF_INET, "1.2.3.5");
2242 // Expect no cache hit because cache storing is also skipped in previous query.
2243 EXPECT_EQ(4U, GetNumQueries(dns, another_host_name));
Luke Huangba7bef92018-12-26 16:53:03 +08002244}
2245
2246TEST_F(ResolverTest, Async_NoRetryFlag) {
Luke Huang70931aa2019-01-31 11:57:41 +08002247 constexpr char listen_addr0[] = "127.0.0.4";
2248 constexpr char listen_addr1[] = "127.0.0.6";
Xiao Ma09b71022018-12-11 17:56:32 +09002249 constexpr char host_name[] = "howdy.example.com.";
2250 const std::vector<DnsRecord> records = {
2251 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2252 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
2253 };
2254
Luke Huang70931aa2019-01-31 11:57:41 +08002255 test::DNSResponder dns0(listen_addr0);
2256 test::DNSResponder dns1(listen_addr1);
2257 StartDns(dns0, records);
2258 StartDns(dns1, records);
2259 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr0, listen_addr1}));
Luke Huangba7bef92018-12-26 16:53:03 +08002260
Luke Huang70931aa2019-01-31 11:57:41 +08002261 dns0.clearQueries();
2262 dns1.clearQueries();
2263
2264 dns0.setResponseProbability(0.0);
2265 dns1.setResponseProbability(0.0);
Luke Huangba7bef92018-12-26 16:53:03 +08002266
2267 int fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a,
2268 ANDROID_RESOLV_NO_RETRY);
2269 EXPECT_TRUE(fd1 != -1);
2270
2271 int fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa,
2272 ANDROID_RESOLV_NO_RETRY);
2273 EXPECT_TRUE(fd2 != -1);
2274
2275 // expect no response
2276 expectAnswersNotValid(fd1, -ETIMEDOUT);
2277 expectAnswersNotValid(fd2, -ETIMEDOUT);
2278
Luke Huang70931aa2019-01-31 11:57:41 +08002279 // No retry case, expect total 2 queries. The server is selected randomly.
2280 EXPECT_EQ(2U, GetNumQueries(dns0, host_name) + GetNumQueries(dns1, host_name));
Luke Huangba7bef92018-12-26 16:53:03 +08002281
Luke Huang70931aa2019-01-31 11:57:41 +08002282 dns0.clearQueries();
2283 dns1.clearQueries();
Luke Huangba7bef92018-12-26 16:53:03 +08002284
2285 fd1 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
2286 EXPECT_TRUE(fd1 != -1);
2287
2288 fd2 = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_aaaa, 0);
2289 EXPECT_TRUE(fd2 != -1);
2290
2291 // expect no response
2292 expectAnswersNotValid(fd1, -ETIMEDOUT);
2293 expectAnswersNotValid(fd2, -ETIMEDOUT);
2294
2295 // Retry case, expect 4 queries
Luke Huang70931aa2019-01-31 11:57:41 +08002296 EXPECT_EQ(4U, GetNumQueries(dns0, host_name));
2297 EXPECT_EQ(4U, GetNumQueries(dns1, host_name));
2298}
2299
2300TEST_F(ResolverTest, Async_VerifyQueryID) {
2301 constexpr char listen_addr[] = "127.0.0.4";
2302 constexpr char host_name[] = "howdy.example.com.";
2303 const std::vector<DnsRecord> records = {
2304 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2305 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
2306 };
2307
2308 test::DNSResponder dns(listen_addr);
2309 StartDns(dns, records);
2310 std::vector<std::string> servers = {listen_addr};
2311 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
2312
2313 const uint8_t queryBuf1[] = {
2314 /* Header */
2315 0x55, 0x66, /* Transaction ID */
2316 0x01, 0x00, /* Flags */
2317 0x00, 0x01, /* Questions */
2318 0x00, 0x00, /* Answer RRs */
2319 0x00, 0x00, /* Authority RRs */
2320 0x00, 0x00, /* Additional RRs */
2321 /* Queries */
2322 0x05, 0x68, 0x6f, 0x77, 0x64, 0x79, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
2323 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */
2324 0x00, 0x01, /* Type */
2325 0x00, 0x01 /* Class */
2326 };
2327
2328 int fd = resNetworkSend(TEST_NETID, queryBuf1, sizeof(queryBuf1), 0);
2329 EXPECT_TRUE(fd != -1);
2330
2331 uint8_t buf[MAXPACKET] = {};
2332 int rcode;
2333
2334 int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
2335 EXPECT_GT(res, 0);
2336 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
2337
2338 auto hp = reinterpret_cast<HEADER*>(buf);
2339 EXPECT_EQ(21862U, htons(hp->id));
2340
2341 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
2342
2343 const uint8_t queryBuf2[] = {
2344 /* Header */
2345 0x00, 0x53, /* Transaction ID */
2346 0x01, 0x00, /* Flags */
2347 0x00, 0x01, /* Questions */
2348 0x00, 0x00, /* Answer RRs */
2349 0x00, 0x00, /* Authority RRs */
2350 0x00, 0x00, /* Additional RRs */
2351 /* Queries */
2352 0x05, 0x68, 0x6f, 0x77, 0x64, 0x79, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
2353 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */
2354 0x00, 0x01, /* Type */
2355 0x00, 0x01 /* Class */
2356 };
2357
2358 // Re-query verify cache works and query id is correct
2359 fd = resNetworkSend(TEST_NETID, queryBuf2, sizeof(queryBuf2), 0);
2360
2361 EXPECT_TRUE(fd != -1);
2362
2363 res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
2364 EXPECT_GT(res, 0);
2365 EXPECT_EQ("1.2.3.4", toString(buf, res, AF_INET));
2366
2367 EXPECT_EQ(0x0053U, htons(hp->id));
2368
2369 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
Luke Huangba7bef92018-12-26 16:53:03 +08002370}
2371
Mike Yu4f3747b2018-12-02 17:54:29 +09002372// This test checks that the resolver should not generate the request containing OPT RR when using
Ken Chen0a015532019-01-02 14:59:38 +08002373// cleartext DNS. If we query the DNS server not supporting EDNS0 and it reponds with
2374// FORMERR_ON_EDNS, we will fallback to no EDNS0 and try again. If the server does no response, we
2375// won't retry so that we get no answer.
Mike Yu4f3747b2018-12-02 17:54:29 +09002376TEST_F(ResolverTest, BrokenEdns) {
2377 typedef test::DNSResponder::Edns Edns;
2378 enum ExpectResult { EXPECT_FAILURE, EXPECT_SUCCESS };
2379
2380 const char OFF[] = "off";
2381 const char OPPORTUNISTIC_UDP[] = "opportunistic_udp";
2382 const char OPPORTUNISTIC_TLS[] = "opportunistic_tls";
2383 const char STRICT[] = "strict";
2384 const char GETHOSTBYNAME[] = "gethostbyname";
2385 const char GETADDRINFO[] = "getaddrinfo";
Mike Yu4f3747b2018-12-02 17:54:29 +09002386 const char ADDR4[] = "192.0.2.1";
2387 const char CLEARTEXT_ADDR[] = "127.0.0.53";
2388 const char CLEARTEXT_PORT[] = "53";
2389 const char TLS_PORT[] = "853";
Luke Huangf8215372019-11-22 11:53:41 +08002390 const std::vector<std::string> servers = {CLEARTEXT_ADDR};
Mike Yu4f3747b2018-12-02 17:54:29 +09002391
Mike Yufc125e42019-05-15 20:41:28 +08002392 test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, ns_rcode::ns_r_servfail);
Mike Yu4f3747b2018-12-02 17:54:29 +09002393 ASSERT_TRUE(dns.startServer());
2394
2395 test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
2396
Luke Huangf8215372019-11-22 11:53:41 +08002397 // clang-format off
Mike Yu4f3747b2018-12-02 17:54:29 +09002398 static const struct TestConfig {
2399 std::string mode;
2400 std::string method;
2401 Edns edns;
2402 ExpectResult expectResult;
2403
2404 std::string asHostName() const {
2405 const char* ednsString;
2406 switch (edns) {
2407 case Edns::ON:
2408 ednsString = "ednsOn";
2409 break;
Ken Chen0a015532019-01-02 14:59:38 +08002410 case Edns::FORMERR_ON_EDNS:
Mike Yu4f3747b2018-12-02 17:54:29 +09002411 ednsString = "ednsFormerr";
2412 break;
2413 case Edns::DROP:
2414 ednsString = "ednsDrop";
2415 break;
2416 default:
2417 ednsString = "";
2418 break;
2419 }
2420 return StringPrintf("%s.%s.%s.", mode.c_str(), method.c_str(), ednsString);
2421 }
2422 } testConfigs[] = {
2423 // In OPPORTUNISTIC_TLS, we get no answer if the DNS server supports TLS but not EDNS0.
2424 // Could such server exist? if so, we might need to fallback to query cleartext DNS.
2425 // Another thing is that {OPPORTUNISTIC_TLS, Edns::DROP} and {STRICT, Edns::DROP} are
2426 // commented out since TLS timeout is not configurable.
2427 // TODO: Uncomment them after TLS timeout is configurable.
2428 {OFF, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
2429 {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
2430 {OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
2431 {STRICT, GETHOSTBYNAME, Edns::ON, EXPECT_SUCCESS},
Ken Chen0a015532019-01-02 14:59:38 +08002432 {OFF, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2433 {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2434 {OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
2435 {STRICT, GETHOSTBYNAME, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
Mike Yu4f3747b2018-12-02 17:54:29 +09002436 {OFF, GETHOSTBYNAME, Edns::DROP, EXPECT_SUCCESS},
2437 {OPPORTUNISTIC_UDP, GETHOSTBYNAME, Edns::DROP, EXPECT_SUCCESS},
2438 //{OPPORTUNISTIC_TLS, GETHOSTBYNAME, Edns::DROP, EXPECT_FAILURE},
2439 //{STRICT, GETHOSTBYNAME, Edns::DROP, EXPECT_FAILURE},
2440 {OFF, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
2441 {OPPORTUNISTIC_UDP, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
2442 {OPPORTUNISTIC_TLS, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
2443 {STRICT, GETADDRINFO, Edns::ON, EXPECT_SUCCESS},
Ken Chen0a015532019-01-02 14:59:38 +08002444 {OFF, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2445 {OPPORTUNISTIC_UDP, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_SUCCESS},
2446 {OPPORTUNISTIC_TLS, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
2447 {STRICT, GETADDRINFO, Edns::FORMERR_ON_EDNS, EXPECT_FAILURE},
Mike Yu4f3747b2018-12-02 17:54:29 +09002448 {OFF, GETADDRINFO, Edns::DROP, EXPECT_SUCCESS},
2449 {OPPORTUNISTIC_UDP, GETADDRINFO, Edns::DROP, EXPECT_SUCCESS},
2450 //{OPPORTUNISTIC_TLS, GETADDRINFO, Edns::DROP, EXPECT_FAILURE},
2451 //{STRICT, GETADDRINFO, Edns::DROP, EXPECT_FAILURE},
2452 };
Luke Huangf8215372019-11-22 11:53:41 +08002453 // clang-format on
Mike Yu4f3747b2018-12-02 17:54:29 +09002454
2455 for (const auto& config : testConfigs) {
2456 const std::string testHostName = config.asHostName();
2457 SCOPED_TRACE(testHostName);
2458
2459 const char* host_name = testHostName.c_str();
2460 dns.addMapping(host_name, ns_type::ns_t_a, ADDR4);
2461 dns.setEdns(config.edns);
2462
2463 if (config.mode == OFF) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002464 if (tls.running()) {
2465 ASSERT_TRUE(tls.stopServer());
2466 }
Xiao Ma09b71022018-12-11 17:56:32 +09002467 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
Mike Yu4f3747b2018-12-02 17:54:29 +09002468 } else if (config.mode == OPPORTUNISTIC_UDP) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002469 if (tls.running()) {
2470 ASSERT_TRUE(tls.stopServer());
2471 }
Xiao Ma09b71022018-12-11 17:56:32 +09002472 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08002473 kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002474 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), false));
Mike Yu4f3747b2018-12-02 17:54:29 +09002475 } else if (config.mode == OPPORTUNISTIC_TLS) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002476 if (!tls.running()) {
2477 ASSERT_TRUE(tls.startServer());
2478 }
Xiao Ma09b71022018-12-11 17:56:32 +09002479 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08002480 kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002481 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yu4f3747b2018-12-02 17:54:29 +09002482 } else if (config.mode == STRICT) {
Mike Yu0f20cdd2019-06-11 11:52:37 +08002483 if (!tls.running()) {
2484 ASSERT_TRUE(tls.startServer());
2485 }
Xiao Ma09b71022018-12-11 17:56:32 +09002486 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains,
waynema0e73c2e2019-07-31 15:04:08 +08002487 kDefaultParams, kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08002488 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yu4f3747b2018-12-02 17:54:29 +09002489 }
2490
2491 if (config.method == GETHOSTBYNAME) {
2492 const hostent* h_result = gethostbyname(host_name);
2493 if (config.expectResult == EXPECT_SUCCESS) {
2494 EXPECT_LE(1U, GetNumQueries(dns, host_name));
2495 ASSERT_TRUE(h_result != nullptr);
2496 ASSERT_EQ(4, h_result->h_length);
2497 ASSERT_FALSE(h_result->h_addr_list[0] == nullptr);
2498 EXPECT_EQ(ADDR4, ToString(h_result));
2499 EXPECT_TRUE(h_result->h_addr_list[1] == nullptr);
2500 } else {
2501 EXPECT_EQ(0U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
2502 ASSERT_TRUE(h_result == nullptr);
2503 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
2504 }
2505 } else if (config.method == GETADDRINFO) {
2506 ScopedAddrinfo ai_result;
2507 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
2508 ai_result = safe_getaddrinfo(host_name, nullptr, &hints);
2509 if (config.expectResult == EXPECT_SUCCESS) {
2510 EXPECT_TRUE(ai_result != nullptr);
2511 EXPECT_EQ(1U, GetNumQueries(dns, host_name));
2512 const std::string result_str = ToString(ai_result);
2513 EXPECT_EQ(ADDR4, result_str);
2514 } else {
2515 EXPECT_TRUE(ai_result == nullptr);
2516 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
2517 }
2518 } else {
2519 FAIL() << "Unsupported query method: " << config.method;
2520 }
2521
Mike Yudd4ac2d2019-05-31 16:52:11 +08002522 tls.clearQueries();
Mike Yu4f3747b2018-12-02 17:54:29 +09002523 dns.clearQueries();
2524 }
Mike Yu4f3747b2018-12-02 17:54:29 +09002525}
nuccachena26cc2a2018-07-17 18:07:23 +08002526
Ken Chen0a015532019-01-02 14:59:38 +08002527// DNS-over-TLS validation success, but server does not respond to TLS query after a while.
2528// Resolver should have a reasonable number of retries instead of spinning forever. We don't have
2529// an efficient way to know if resolver is stuck in an infinite loop. However, test case will be
2530// failed due to timeout.
2531TEST_F(ResolverTest, UnstableTls) {
2532 const char CLEARTEXT_ADDR[] = "127.0.0.53";
2533 const char CLEARTEXT_PORT[] = "53";
2534 const char TLS_PORT[] = "853";
2535 const char* host_name1 = "nonexistent1.example.com.";
2536 const char* host_name2 = "nonexistent2.example.com.";
2537 const std::vector<std::string> servers = {CLEARTEXT_ADDR};
2538
Mike Yufc125e42019-05-15 20:41:28 +08002539 test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, ns_rcode::ns_r_servfail);
Ken Chen0a015532019-01-02 14:59:38 +08002540 ASSERT_TRUE(dns.startServer());
2541 dns.setEdns(test::DNSResponder::Edns::FORMERR_ON_EDNS);
2542 test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
2543 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08002544 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002545 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
2546
Ken Chen0a015532019-01-02 14:59:38 +08002547 // Shutdown TLS server to get an error. It's similar to no response case but without waiting.
2548 tls.stopServer();
2549
2550 const hostent* h_result = gethostbyname(host_name1);
2551 EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
2552 ASSERT_TRUE(h_result == nullptr);
2553 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
2554
2555 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
2556 ScopedAddrinfo ai_result = safe_getaddrinfo(host_name2, nullptr, &hints);
2557 EXPECT_TRUE(ai_result == nullptr);
2558 EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
2559}
2560
2561// DNS-over-TLS validation success, but server does not respond to TLS query after a while.
2562// Moreover, server responds RCODE=FORMERR even on non-EDNS query.
2563TEST_F(ResolverTest, BogusDnsServer) {
2564 const char CLEARTEXT_ADDR[] = "127.0.0.53";
2565 const char CLEARTEXT_PORT[] = "53";
2566 const char TLS_PORT[] = "853";
2567 const char* host_name1 = "nonexistent1.example.com.";
2568 const char* host_name2 = "nonexistent2.example.com.";
2569 const std::vector<std::string> servers = {CLEARTEXT_ADDR};
2570
Mike Yufc125e42019-05-15 20:41:28 +08002571 test::DNSResponder dns(CLEARTEXT_ADDR, CLEARTEXT_PORT, ns_rcode::ns_r_servfail);
Ken Chen0a015532019-01-02 14:59:38 +08002572 ASSERT_TRUE(dns.startServer());
2573 test::DnsTlsFrontend tls(CLEARTEXT_ADDR, TLS_PORT, CLEARTEXT_ADDR, CLEARTEXT_PORT);
2574 ASSERT_TRUE(tls.startServer());
waynema0e73c2e2019-07-31 15:04:08 +08002575 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08002576 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
2577
Ken Chen0a015532019-01-02 14:59:38 +08002578 // Shutdown TLS server to get an error. It's similar to no response case but without waiting.
2579 tls.stopServer();
2580 dns.setEdns(test::DNSResponder::Edns::FORMERR_UNCOND);
2581
2582 const hostent* h_result = gethostbyname(host_name1);
2583 EXPECT_EQ(0U, GetNumQueries(dns, host_name1));
2584 ASSERT_TRUE(h_result == nullptr);
2585 ASSERT_EQ(HOST_NOT_FOUND, h_errno);
2586
2587 addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
2588 ScopedAddrinfo ai_result = safe_getaddrinfo(host_name2, nullptr, &hints);
2589 EXPECT_TRUE(ai_result == nullptr);
2590 EXPECT_EQ(0U, GetNumQueries(dns, host_name2));
2591}
2592
nuccachena26cc2a2018-07-17 18:07:23 +08002593TEST_F(ResolverTest, GetAddrInfo_Dns64Synthesize) {
2594 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002595 constexpr char dns64_name[] = "ipv4only.arpa.";
2596 constexpr char host_name[] = "v4only.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002597 const std::vector<DnsRecord> records = {
2598 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2599 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2600 };
nuccachena26cc2a2018-07-17 18:07:23 +08002601
Xiao Ma09b71022018-12-11 17:56:32 +09002602 test::DNSResponder dns(listen_addr);
Xiao Ma09b71022018-12-11 17:56:32 +09002603 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002604
2605 std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002606 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002607
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002608 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002609 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002610 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002611
2612 // hints are necessary in order to let netd know which type of addresses the caller is
2613 // interested in.
Xiao Ma09b71022018-12-11 17:56:32 +09002614 const addrinfo hints = {.ai_family = AF_UNSPEC};
nuccachena26cc2a2018-07-17 18:07:23 +08002615 ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, &hints);
2616 EXPECT_TRUE(result != nullptr);
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002617 // TODO: BUG: there should only be two queries, one AAAA (which returns no records) and one A
2618 // (which returns 1.2.3.4). But there is an extra AAAA.
2619 EXPECT_EQ(3U, GetNumQueries(dns, host_name));
nuccachena26cc2a2018-07-17 18:07:23 +08002620
2621 std::string result_str = ToString(result);
2622 EXPECT_EQ(result_str, "64:ff9b::102:304");
2623
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002624 // Stopping NAT64 prefix discovery disables synthesis.
Luke Huang5bd827c2019-03-14 16:10:04 +08002625 EXPECT_TRUE(mDnsClient.resolvService()->stopPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002626 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_NOT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002627
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002628 dns.clearQueries();
nuccachena26cc2a2018-07-17 18:07:23 +08002629
2630 result = safe_getaddrinfo("v4only", nullptr, &hints);
2631 EXPECT_TRUE(result != nullptr);
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002632 // TODO: BUG: there should only be one query, an AAAA (which returns no records), because the
2633 // A is already cached. But there is an extra AAAA.
2634 EXPECT_EQ(2U, GetNumQueries(dns, host_name));
nuccachena26cc2a2018-07-17 18:07:23 +08002635
2636 result_str = ToString(result);
2637 EXPECT_EQ(result_str, "1.2.3.4");
2638}
2639
nuccachena26cc2a2018-07-17 18:07:23 +08002640TEST_F(ResolverTest, GetAddrInfo_Dns64QuerySpecified) {
2641 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002642 constexpr char dns64_name[] = "ipv4only.arpa.";
2643 constexpr char host_name[] = "v4only.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002644 const std::vector<DnsRecord> records = {
2645 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2646 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2647 };
nuccachena26cc2a2018-07-17 18:07:23 +08002648
Xiao Ma09b71022018-12-11 17:56:32 +09002649 test::DNSResponder dns(listen_addr);
2650 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002651 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002652 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002653
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002654 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002655 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002656 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002657
2658 // Ensure to synthesize AAAA if AF_INET6 is specified, and not to synthesize AAAA
2659 // in AF_INET case.
2660 addrinfo hints;
2661 memset(&hints, 0, sizeof(hints));
2662 hints.ai_family = AF_INET6;
2663 ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, &hints);
2664 EXPECT_TRUE(result != nullptr);
2665 std::string result_str = ToString(result);
2666 EXPECT_EQ(result_str, "64:ff9b::102:304");
2667
2668 hints.ai_family = AF_INET;
2669 result = safe_getaddrinfo("v4only", nullptr, &hints);
2670 EXPECT_TRUE(result != nullptr);
2671 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2672 result_str = ToString(result);
2673 EXPECT_EQ(result_str, "1.2.3.4");
2674}
nuccachena26cc2a2018-07-17 18:07:23 +08002675
2676TEST_F(ResolverTest, GetAddrInfo_Dns64QueryUnspecifiedV6) {
2677 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002678 constexpr char dns64_name[] = "ipv4only.arpa.";
2679 constexpr char host_name[] = "v4v6.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002680 const std::vector<DnsRecord> records = {
2681 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2682 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2683 {host_name, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
2684 };
nuccachena26cc2a2018-07-17 18:07:23 +08002685
Xiao Ma09b71022018-12-11 17:56:32 +09002686 test::DNSResponder dns(listen_addr);
2687 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002688 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002689 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002690
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002691 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002692 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002693 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002694
Xiao Ma09b71022018-12-11 17:56:32 +09002695 const addrinfo hints = {.ai_family = AF_UNSPEC};
nuccachena26cc2a2018-07-17 18:07:23 +08002696 ScopedAddrinfo result = safe_getaddrinfo("v4v6", nullptr, &hints);
2697 EXPECT_TRUE(result != nullptr);
2698 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2699
2700 // In AF_UNSPEC case, do not synthesize AAAA if there's at least one AAAA answer.
Xiao Ma09b71022018-12-11 17:56:32 +09002701 const std::vector<std::string> result_strs = ToStrings(result);
nuccachena26cc2a2018-07-17 18:07:23 +08002702 for (const auto& str : result_strs) {
2703 EXPECT_TRUE(str == "1.2.3.4" || str == "2001:db8::102:304")
2704 << ", result_str='" << str << "'";
2705 }
2706}
2707
2708TEST_F(ResolverTest, GetAddrInfo_Dns64QueryUnspecifiedNoV6) {
2709 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002710 constexpr char dns64_name[] = "ipv4only.arpa.";
2711 constexpr char host_name[] = "v4v6.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002712 const std::vector<DnsRecord> records = {
2713 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2714 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2715 };
nuccachena26cc2a2018-07-17 18:07:23 +08002716
Xiao Ma09b71022018-12-11 17:56:32 +09002717 test::DNSResponder dns(listen_addr);
2718 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002719 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002720 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002721
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002722 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002723 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002724 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002725
Xiao Ma09b71022018-12-11 17:56:32 +09002726 const addrinfo hints = {.ai_family = AF_UNSPEC};
nuccachena26cc2a2018-07-17 18:07:23 +08002727 ScopedAddrinfo result = safe_getaddrinfo("v4v6", nullptr, &hints);
2728 EXPECT_TRUE(result != nullptr);
2729 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2730
2731 // In AF_UNSPEC case, synthesize AAAA if there's no AAAA answer.
2732 std::string result_str = ToString(result);
2733 EXPECT_EQ(result_str, "64:ff9b::102:304");
2734}
2735
2736TEST_F(ResolverTest, GetAddrInfo_Dns64QuerySpecialUseIPv4Addresses) {
2737 constexpr char THIS_NETWORK[] = "this_network";
2738 constexpr char LOOPBACK[] = "loopback";
2739 constexpr char LINK_LOCAL[] = "link_local";
2740 constexpr char MULTICAST[] = "multicast";
2741 constexpr char LIMITED_BROADCAST[] = "limited_broadcast";
2742
2743 constexpr char ADDR_THIS_NETWORK[] = "0.0.0.1";
2744 constexpr char ADDR_LOOPBACK[] = "127.0.0.1";
2745 constexpr char ADDR_LINK_LOCAL[] = "169.254.0.1";
2746 constexpr char ADDR_MULTICAST[] = "224.0.0.1";
2747 constexpr char ADDR_LIMITED_BROADCAST[] = "255.255.255.255";
2748
2749 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002750 constexpr char dns64_name[] = "ipv4only.arpa.";
2751
Xiao Ma09b71022018-12-11 17:56:32 +09002752 test::DNSResponder dns(listen_addr);
2753 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
nuccachena26cc2a2018-07-17 18:07:23 +08002754 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002755 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002756
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002757 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002758 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002759 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002760
Luke Huangf8215372019-11-22 11:53:41 +08002761 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08002762 static const struct TestConfig {
2763 std::string name;
2764 std::string addr;
2765
2766 std::string asHostName() const { return StringPrintf("%s.example.com.", name.c_str()); }
2767 } testConfigs[]{
2768 {THIS_NETWORK, ADDR_THIS_NETWORK},
2769 {LOOPBACK, ADDR_LOOPBACK},
2770 {LINK_LOCAL, ADDR_LINK_LOCAL},
2771 {MULTICAST, ADDR_MULTICAST},
2772 {LIMITED_BROADCAST, ADDR_LIMITED_BROADCAST}
2773 };
Luke Huangf8215372019-11-22 11:53:41 +08002774 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08002775
2776 for (const auto& config : testConfigs) {
2777 const std::string testHostName = config.asHostName();
2778 SCOPED_TRACE(testHostName);
2779
2780 const char* host_name = testHostName.c_str();
2781 dns.addMapping(host_name, ns_type::ns_t_a, config.addr.c_str());
2782
2783 addrinfo hints;
2784 memset(&hints, 0, sizeof(hints));
2785 hints.ai_family = AF_INET6;
2786 ScopedAddrinfo result = safe_getaddrinfo(config.name.c_str(), nullptr, &hints);
2787 // In AF_INET6 case, don't return IPv4 answers
2788 EXPECT_TRUE(result == nullptr);
2789 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2790 dns.clearQueries();
2791
2792 memset(&hints, 0, sizeof(hints));
2793 hints.ai_family = AF_UNSPEC;
2794 result = safe_getaddrinfo(config.name.c_str(), nullptr, &hints);
2795 EXPECT_TRUE(result != nullptr);
2796 // Expect IPv6 query only. IPv4 answer has been cached in previous query.
2797 EXPECT_LE(1U, GetNumQueries(dns, host_name));
2798 // In AF_UNSPEC case, don't synthesize special use IPv4 address.
2799 std::string result_str = ToString(result);
2800 EXPECT_EQ(result_str, config.addr.c_str());
2801 dns.clearQueries();
2802 }
2803}
2804
2805TEST_F(ResolverTest, GetAddrInfo_Dns64QueryWithNullArgumentHints) {
2806 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002807 constexpr char dns64_name[] = "ipv4only.arpa.";
2808 constexpr char host_name[] = "v4only.example.com.";
2809 constexpr char host_name2[] = "v4v6.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09002810 const std::vector<DnsRecord> records = {
2811 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2812 {host_name, ns_type::ns_t_a, "1.2.3.4"},
2813 {host_name2, ns_type::ns_t_a, "1.2.3.4"},
2814 {host_name2, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
2815 };
nuccachena26cc2a2018-07-17 18:07:23 +08002816
Xiao Ma09b71022018-12-11 17:56:32 +09002817 test::DNSResponder dns(listen_addr);
2818 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002819 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002820 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002821
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002822 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002823 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002824 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002825
2826 // Assign argument hints of getaddrinfo() as null is equivalent to set ai_family AF_UNSPEC.
2827 // In AF_UNSPEC case, synthesize AAAA if there has A answer only.
2828 ScopedAddrinfo result = safe_getaddrinfo("v4only", nullptr, nullptr);
2829 EXPECT_TRUE(result != nullptr);
2830 EXPECT_LE(2U, GetNumQueries(dns, host_name));
2831 std::string result_str = ToString(result);
2832 EXPECT_EQ(result_str, "64:ff9b::102:304");
2833 dns.clearQueries();
2834
2835 // In AF_UNSPEC case, do not synthesize AAAA if there's at least one AAAA answer.
2836 result = safe_getaddrinfo("v4v6", nullptr, nullptr);
2837 EXPECT_TRUE(result != nullptr);
2838 EXPECT_LE(2U, GetNumQueries(dns, host_name2));
2839 std::vector<std::string> result_strs = ToStrings(result);
2840 for (const auto& str : result_strs) {
2841 EXPECT_TRUE(str == "1.2.3.4" || str == "2001:db8::102:304")
2842 << ", result_str='" << str << "'";
2843 }
2844}
2845
2846TEST_F(ResolverTest, GetAddrInfo_Dns64QueryNullArgumentNode) {
2847 constexpr char ADDR_ANYADDR_V4[] = "0.0.0.0";
2848 constexpr char ADDR_ANYADDR_V6[] = "::";
2849 constexpr char ADDR_LOCALHOST_V4[] = "127.0.0.1";
2850 constexpr char ADDR_LOCALHOST_V6[] = "::1";
2851
2852 constexpr char PORT_NAME_HTTP[] = "http";
2853 constexpr char PORT_NUMBER_HTTP[] = "80";
2854
2855 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002856 constexpr char dns64_name[] = "ipv4only.arpa.";
2857
Xiao Ma09b71022018-12-11 17:56:32 +09002858 test::DNSResponder dns(listen_addr);
2859 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
nuccachena26cc2a2018-07-17 18:07:23 +08002860 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002861 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002862
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002863 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002864 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002865 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002866
Luke Huangf8215372019-11-22 11:53:41 +08002867 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08002868 // If node is null, return address is listed by libc/getaddrinfo.c as follows.
2869 // - passive socket -> anyaddr (0.0.0.0 or ::)
2870 // - non-passive socket -> localhost (127.0.0.1 or ::1)
2871 static const struct TestConfig {
2872 int flag;
2873 std::string addr_v4;
2874 std::string addr_v6;
2875
2876 std::string asParameters() const {
2877 return StringPrintf("flag=%d, addr_v4=%s, addr_v6=%s", flag, addr_v4.c_str(),
2878 addr_v6.c_str());
2879 }
2880 } testConfigs[]{
2881 {0 /* non-passive */, ADDR_LOCALHOST_V4, ADDR_LOCALHOST_V6},
2882 {AI_PASSIVE, ADDR_ANYADDR_V4, ADDR_ANYADDR_V6}
2883 };
Luke Huangf8215372019-11-22 11:53:41 +08002884 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08002885
2886 for (const auto& config : testConfigs) {
2887 SCOPED_TRACE(config.asParameters());
2888
Xiao Ma09b71022018-12-11 17:56:32 +09002889 addrinfo hints = {
Nick Desaulnierscd6395a2019-10-11 09:15:24 -07002890 .ai_flags = config.flag,
Xiao Ma09b71022018-12-11 17:56:32 +09002891 .ai_family = AF_UNSPEC, // any address family
2892 .ai_socktype = 0, // any type
2893 .ai_protocol = 0, // any protocol
Xiao Ma09b71022018-12-11 17:56:32 +09002894 };
nuccachena26cc2a2018-07-17 18:07:23 +08002895
2896 // Assign hostname as null and service as port name.
2897 ScopedAddrinfo result = safe_getaddrinfo(nullptr, PORT_NAME_HTTP, &hints);
2898 ASSERT_TRUE(result != nullptr);
2899
2900 // Can't be synthesized because it should not get into Netd.
2901 std::vector<std::string> result_strs = ToStrings(result);
2902 for (const auto& str : result_strs) {
2903 EXPECT_TRUE(str == config.addr_v4 || str == config.addr_v6)
2904 << ", result_str='" << str << "'";
2905 }
2906
2907 // Assign hostname as null and service as numeric port number.
2908 hints.ai_flags = config.flag | AI_NUMERICSERV;
2909 result = safe_getaddrinfo(nullptr, PORT_NUMBER_HTTP, &hints);
2910 ASSERT_TRUE(result != nullptr);
2911
2912 // Can't be synthesized because it should not get into Netd.
2913 result_strs = ToStrings(result);
2914 for (const auto& str : result_strs) {
2915 EXPECT_TRUE(str == config.addr_v4 || str == config.addr_v6)
2916 << ", result_str='" << str << "'";
2917 }
2918 }
2919}
2920
2921TEST_F(ResolverTest, GetHostByAddr_ReverseDnsQueryWithHavingNat64Prefix) {
2922 struct hostent* result = nullptr;
2923 struct in_addr v4addr;
2924 struct in6_addr v6addr;
2925
2926 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002927 constexpr char dns64_name[] = "ipv4only.arpa.";
2928 constexpr char ptr_name[] = "v4v6.example.com.";
2929 // PTR record for IPv4 address 1.2.3.4
2930 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2931 // PTR record for IPv6 address 2001:db8::102:304
2932 constexpr char ptr_addr_v6[] =
2933 "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 +09002934 const std::vector<DnsRecord> records = {
2935 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2936 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2937 {ptr_addr_v6, ns_type::ns_t_ptr, ptr_name},
2938 };
nuccachena26cc2a2018-07-17 18:07:23 +08002939
Xiao Ma09b71022018-12-11 17:56:32 +09002940 test::DNSResponder dns(listen_addr);
2941 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002942 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002943 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002944
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002945 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002946 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002947 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002948
2949 // Reverse IPv4 DNS query. Prefix should have no effect on it.
2950 inet_pton(AF_INET, "1.2.3.4", &v4addr);
2951 result = gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET);
2952 ASSERT_TRUE(result != nullptr);
2953 std::string result_str = result->h_name ? result->h_name : "null";
2954 EXPECT_EQ(result_str, "v4v6.example.com");
2955
2956 // Reverse IPv6 DNS query. Prefix should have no effect on it.
2957 inet_pton(AF_INET6, "2001:db8::102:304", &v6addr);
2958 result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
2959 ASSERT_TRUE(result != nullptr);
2960 result_str = result->h_name ? result->h_name : "null";
2961 EXPECT_EQ(result_str, "v4v6.example.com");
2962}
2963
2964TEST_F(ResolverTest, GetHostByAddr_ReverseDns64Query) {
2965 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08002966 constexpr char dns64_name[] = "ipv4only.arpa.";
2967 constexpr char ptr_name[] = "v4only.example.com.";
2968 // PTR record for IPv4 address 1.2.3.4
2969 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
2970 // PTR record for IPv6 address 64:ff9b::1.2.3.4
2971 constexpr char ptr_addr_v6_nomapping[] =
2972 "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.";
2973 constexpr char ptr_name_v6_synthesis[] = "v6synthesis.example.com.";
2974 // PTR record for IPv6 address 64:ff9b::5.6.7.8
2975 constexpr char ptr_addr_v6_synthesis[] =
2976 "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 +09002977 const std::vector<DnsRecord> records = {
2978 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
2979 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
2980 {ptr_addr_v6_synthesis, ns_type::ns_t_ptr, ptr_name_v6_synthesis},
2981 };
nuccachena26cc2a2018-07-17 18:07:23 +08002982
Xiao Ma09b71022018-12-11 17:56:32 +09002983 test::DNSResponder dns(listen_addr);
2984 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08002985 // "ptr_addr_v6_nomapping" is not mapped in DNS server
nuccachena26cc2a2018-07-17 18:07:23 +08002986 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09002987 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08002988
Lorenzo Colittid39345c2019-02-18 10:59:29 +09002989 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08002990 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08002991 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08002992
2993 // Synthesized PTR record doesn't exist on DNS server
2994 // Reverse IPv6 DNS64 query while DNS server doesn't have an answer for synthesized address.
2995 // After querying synthesized address failed, expect that prefix is removed from IPv6
2996 // synthesized address and do reverse IPv4 query instead.
2997 struct in6_addr v6addr;
2998 inet_pton(AF_INET6, "64:ff9b::1.2.3.4", &v6addr);
2999 struct hostent* result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
3000 ASSERT_TRUE(result != nullptr);
3001 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_nomapping)); // PTR record not exist
3002 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4)); // PTR record exist
3003 std::string result_str = result->h_name ? result->h_name : "null";
3004 EXPECT_EQ(result_str, "v4only.example.com");
3005 // Check that return address has been mapped from IPv4 to IPv6 address because Netd
3006 // removes NAT64 prefix and does IPv4 DNS reverse lookup in this case. Then, Netd
3007 // fakes the return IPv4 address as original queried IPv6 address.
3008 result_str = ToString(result);
3009 EXPECT_EQ(result_str, "64:ff9b::102:304");
3010 dns.clearQueries();
3011
3012 // Synthesized PTR record exists on DNS server
3013 // Reverse IPv6 DNS64 query while DNS server has an answer for synthesized address.
3014 // Expect to Netd pass through synthesized address for DNS queries.
3015 inet_pton(AF_INET6, "64:ff9b::5.6.7.8", &v6addr);
3016 result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
3017 ASSERT_TRUE(result != nullptr);
3018 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_synthesis));
3019 result_str = result->h_name ? result->h_name : "null";
3020 EXPECT_EQ(result_str, "v6synthesis.example.com");
3021}
3022
3023TEST_F(ResolverTest, GetHostByAddr_ReverseDns64QueryFromHostFile) {
3024 constexpr char dns64_name[] = "ipv4only.arpa.";
3025 constexpr char host_name[] = "localhost";
3026 // The address is synthesized by prefix64:localhost.
3027 constexpr char host_addr[] = "64:ff9b::7f00:1";
nuccachena26cc2a2018-07-17 18:07:23 +08003028 constexpr char listen_addr[] = "::1";
Xiao Ma09b71022018-12-11 17:56:32 +09003029
3030 test::DNSResponder dns(listen_addr);
3031 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
nuccachena26cc2a2018-07-17 18:07:23 +08003032 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003033 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003034
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003035 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003036 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003037 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003038
3039 // Using synthesized "localhost" address to be a trick for resolving host name
3040 // from host file /etc/hosts and "localhost" is the only name in /etc/hosts. Note that this is
3041 // not realistic: the code never synthesizes AAAA records for addresses in 127.0.0.0/8.
3042 struct in6_addr v6addr;
3043 inet_pton(AF_INET6, host_addr, &v6addr);
3044 struct hostent* result = gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6);
3045 ASSERT_TRUE(result != nullptr);
3046 // Expect no DNS queries; localhost is resolved via /etc/hosts.
3047 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
3048
Luke Huangf8215372019-11-22 11:53:41 +08003049 ASSERT_EQ(sizeof(in6_addr), (unsigned)result->h_length);
nuccachena26cc2a2018-07-17 18:07:23 +08003050 ASSERT_EQ(AF_INET6, result->h_addrtype);
3051 std::string result_str = ToString(result);
3052 EXPECT_EQ(result_str, host_addr);
3053 result_str = result->h_name ? result->h_name : "null";
3054 EXPECT_EQ(result_str, host_name);
3055}
3056
Hungming Chen9e6185a2019-06-04 16:09:19 +08003057TEST_F(ResolverTest, GetHostByAddr_cnamesClasslessReverseDelegation) {
3058 // IPv4 addresses in the subnet with notation '/' or '-'.
3059 constexpr char addr_slash[] = "192.0.2.1";
3060 constexpr char addr_hyphen[] = "192.0.3.1";
3061
3062 // Used to verify DNS reverse query for classless reverse lookup zone. See detail in RFC 2317
3063 // section 4.
3064 const static std::vector<DnsRecord> records = {
3065 // The records for reverse querying "192.0.2.1" in the subnet with notation '/'.
3066 {"1.2.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0/25.2.0.192.in-addr.arpa."},
3067 {"1.0/25.2.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
3068
3069 // The records for reverse querying "192.0.3.1" in the subnet with notation '-'.
3070 {"1.3.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0-127.3.0.192.in-addr.arpa."},
3071 {"1.0-127.3.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
3072 };
3073
3074 test::DNSResponder dns;
3075 StartDns(dns, records);
3076 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3077
3078 for (const auto& address : {addr_slash, addr_hyphen}) {
3079 SCOPED_TRACE(address);
3080
3081 in_addr v4addr;
3082 ASSERT_TRUE(inet_pton(AF_INET, address, &v4addr));
3083 hostent* result = gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET);
3084 ASSERT_TRUE(result != nullptr);
3085 EXPECT_STREQ("hello.example.com", result->h_name);
3086 }
3087}
3088
nuccachena26cc2a2018-07-17 18:07:23 +08003089TEST_F(ResolverTest, GetNameInfo_ReverseDnsQueryWithHavingNat64Prefix) {
3090 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08003091 constexpr char dns64_name[] = "ipv4only.arpa.";
3092 constexpr char ptr_name[] = "v4v6.example.com.";
3093 // PTR record for IPv4 address 1.2.3.4
3094 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
3095 // PTR record for IPv6 address 2001:db8::102:304
3096 constexpr char ptr_addr_v6[] =
3097 "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 +09003098 const std::vector<DnsRecord> records = {
3099 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
3100 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
3101 {ptr_addr_v6, ns_type::ns_t_ptr, ptr_name},
3102 };
nuccachena26cc2a2018-07-17 18:07:23 +08003103
Xiao Ma09b71022018-12-11 17:56:32 +09003104 test::DNSResponder dns(listen_addr);
3105 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08003106 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003107 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003108
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003109 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003110 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003111 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003112
Luke Huangf8215372019-11-22 11:53:41 +08003113 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08003114 static const struct TestConfig {
3115 int flag;
3116 int family;
3117 std::string addr;
3118 std::string host;
3119
3120 std::string asParameters() const {
3121 return StringPrintf("flag=%d, family=%d, addr=%s, host=%s", flag, family, addr.c_str(),
3122 host.c_str());
3123 }
3124 } testConfigs[]{
3125 {NI_NAMEREQD, AF_INET, "1.2.3.4", "v4v6.example.com"},
3126 {NI_NUMERICHOST, AF_INET, "1.2.3.4", "1.2.3.4"},
3127 {0, AF_INET, "1.2.3.4", "v4v6.example.com"},
3128 {0, AF_INET, "5.6.7.8", "5.6.7.8"}, // unmapped
3129 {NI_NAMEREQD, AF_INET6, "2001:db8::102:304", "v4v6.example.com"},
3130 {NI_NUMERICHOST, AF_INET6, "2001:db8::102:304", "2001:db8::102:304"},
3131 {0, AF_INET6, "2001:db8::102:304", "v4v6.example.com"},
3132 {0, AF_INET6, "2001:db8::506:708", "2001:db8::506:708"}, // unmapped
3133 };
Luke Huangf8215372019-11-22 11:53:41 +08003134 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08003135
3136 // Reverse IPv4/IPv6 DNS query. Prefix should have no effect on it.
3137 for (const auto& config : testConfigs) {
3138 SCOPED_TRACE(config.asParameters());
3139
3140 int rv;
3141 char host[NI_MAXHOST];
3142 struct sockaddr_in sin;
3143 struct sockaddr_in6 sin6;
3144 if (config.family == AF_INET) {
3145 memset(&sin, 0, sizeof(sin));
3146 sin.sin_family = AF_INET;
3147 inet_pton(AF_INET, config.addr.c_str(), &sin.sin_addr);
Luke Huangf8215372019-11-22 11:53:41 +08003148 rv = getnameinfo((const struct sockaddr*)&sin, sizeof(sin), host, sizeof(host), nullptr,
3149 0, config.flag);
nuccachena26cc2a2018-07-17 18:07:23 +08003150 if (config.flag == NI_NAMEREQD) EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4));
3151 } else if (config.family == AF_INET6) {
3152 memset(&sin6, 0, sizeof(sin6));
3153 sin6.sin6_family = AF_INET6;
3154 inet_pton(AF_INET6, config.addr.c_str(), &sin6.sin6_addr);
Luke Huangf8215372019-11-22 11:53:41 +08003155 rv = getnameinfo((const struct sockaddr*)&sin6, sizeof(sin6), host, sizeof(host),
nuccachena26cc2a2018-07-17 18:07:23 +08003156 nullptr, 0, config.flag);
3157 if (config.flag == NI_NAMEREQD) EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6));
3158 }
3159 ASSERT_EQ(0, rv);
3160 std::string result_str = host;
3161 EXPECT_EQ(result_str, config.host);
3162 dns.clearQueries();
3163 }
3164}
3165
3166TEST_F(ResolverTest, GetNameInfo_ReverseDns64Query) {
3167 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08003168 constexpr char dns64_name[] = "ipv4only.arpa.";
3169 constexpr char ptr_name[] = "v4only.example.com.";
3170 // PTR record for IPv4 address 1.2.3.4
3171 constexpr char ptr_addr_v4[] = "4.3.2.1.in-addr.arpa.";
3172 // PTR record for IPv6 address 64:ff9b::1.2.3.4
3173 constexpr char ptr_addr_v6_nomapping[] =
3174 "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.";
3175 constexpr char ptr_name_v6_synthesis[] = "v6synthesis.example.com.";
3176 // PTR record for IPv6 address 64:ff9b::5.6.7.8
3177 constexpr char ptr_addr_v6_synthesis[] =
3178 "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 +09003179 const std::vector<DnsRecord> records = {
3180 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
3181 {ptr_addr_v4, ns_type::ns_t_ptr, ptr_name},
3182 {ptr_addr_v6_synthesis, ns_type::ns_t_ptr, ptr_name_v6_synthesis},
3183 };
nuccachena26cc2a2018-07-17 18:07:23 +08003184
Xiao Ma09b71022018-12-11 17:56:32 +09003185 test::DNSResponder dns(listen_addr);
3186 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08003187 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003188 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003189
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003190 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003191 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003192 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003193
Luke Huangf8215372019-11-22 11:53:41 +08003194 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08003195 static const struct TestConfig {
3196 bool hasSynthesizedPtrRecord;
3197 int flag;
3198 std::string addr;
3199 std::string host;
3200
3201 std::string asParameters() const {
3202 return StringPrintf("hasSynthesizedPtrRecord=%d, flag=%d, addr=%s, host=%s",
3203 hasSynthesizedPtrRecord, flag, addr.c_str(), host.c_str());
3204 }
3205 } testConfigs[]{
3206 {false, NI_NAMEREQD, "64:ff9b::102:304", "v4only.example.com"},
3207 {false, NI_NUMERICHOST, "64:ff9b::102:304", "64:ff9b::102:304"},
3208 {false, 0, "64:ff9b::102:304", "v4only.example.com"},
3209 {true, NI_NAMEREQD, "64:ff9b::506:708", "v6synthesis.example.com"},
3210 {true, NI_NUMERICHOST, "64:ff9b::506:708", "64:ff9b::506:708"},
3211 {true, 0, "64:ff9b::506:708", "v6synthesis.example.com"}
3212 };
Luke Huangf8215372019-11-22 11:53:41 +08003213 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08003214
3215 // hasSynthesizedPtrRecord = false
3216 // Synthesized PTR record doesn't exist on DNS server
3217 // Reverse IPv6 DNS64 query while DNS server doesn't have an answer for synthesized address.
3218 // After querying synthesized address failed, expect that prefix is removed from IPv6
3219 // synthesized address and do reverse IPv4 query instead.
3220 //
3221 // hasSynthesizedPtrRecord = true
3222 // Synthesized PTR record exists on DNS server
3223 // Reverse IPv6 DNS64 query while DNS server has an answer for synthesized address.
3224 // Expect to just pass through synthesized address for DNS queries.
3225 for (const auto& config : testConfigs) {
3226 SCOPED_TRACE(config.asParameters());
3227
3228 char host[NI_MAXHOST];
3229 struct sockaddr_in6 sin6;
3230 memset(&sin6, 0, sizeof(sin6));
3231 sin6.sin6_family = AF_INET6;
3232 inet_pton(AF_INET6, config.addr.c_str(), &sin6.sin6_addr);
Luke Huangf8215372019-11-22 11:53:41 +08003233 int rv = getnameinfo((const struct sockaddr*)&sin6, sizeof(sin6), host, sizeof(host),
nuccachena26cc2a2018-07-17 18:07:23 +08003234 nullptr, 0, config.flag);
3235 ASSERT_EQ(0, rv);
3236 if (config.flag == NI_NAMEREQD) {
3237 if (config.hasSynthesizedPtrRecord) {
3238 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_synthesis));
3239 } else {
3240 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v6_nomapping)); // PTR record not exist.
3241 EXPECT_LE(1U, GetNumQueries(dns, ptr_addr_v4)); // PTR record exist.
3242 }
3243 }
3244 std::string result_str = host;
3245 EXPECT_EQ(result_str, config.host);
3246 dns.clearQueries();
3247 }
3248}
3249
3250TEST_F(ResolverTest, GetNameInfo_ReverseDns64QueryFromHostFile) {
3251 constexpr char dns64_name[] = "ipv4only.arpa.";
3252 constexpr char host_name[] = "localhost";
3253 // The address is synthesized by prefix64:localhost.
3254 constexpr char host_addr[] = "64:ff9b::7f00:1";
nuccachena26cc2a2018-07-17 18:07:23 +08003255 constexpr char listen_addr[] = "::1";
Xiao Ma09b71022018-12-11 17:56:32 +09003256
3257 test::DNSResponder dns(listen_addr);
3258 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
nuccachena26cc2a2018-07-17 18:07:23 +08003259 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003260 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003261
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003262 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003263 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003264 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003265
3266 // Using synthesized "localhost" address to be a trick for resolving host name
3267 // from host file /etc/hosts and "localhost" is the only name in /etc/hosts. Note that this is
3268 // not realistic: the code never synthesizes AAAA records for addresses in 127.0.0.0/8.
3269 char host[NI_MAXHOST];
Xiao Ma09b71022018-12-11 17:56:32 +09003270 struct sockaddr_in6 sin6 = {.sin6_family = AF_INET6};
nuccachena26cc2a2018-07-17 18:07:23 +08003271 inet_pton(AF_INET6, host_addr, &sin6.sin6_addr);
Luke Huangf8215372019-11-22 11:53:41 +08003272 int rv = getnameinfo((const struct sockaddr*)&sin6, sizeof(sin6), host, sizeof(host), nullptr,
nuccachena26cc2a2018-07-17 18:07:23 +08003273 0, NI_NAMEREQD);
3274 ASSERT_EQ(0, rv);
3275 // Expect no DNS queries; localhost is resolved via /etc/hosts.
3276 EXPECT_EQ(0U, GetNumQueries(dns, host_name));
3277
3278 std::string result_str = host;
3279 EXPECT_EQ(result_str, host_name);
3280}
3281
Hungming Chen9e6185a2019-06-04 16:09:19 +08003282TEST_F(ResolverTest, GetNameInfo_cnamesClasslessReverseDelegation) {
3283 // IPv4 addresses in the subnet with notation '/' or '-'.
3284 constexpr char addr_slash[] = "192.0.2.1";
3285 constexpr char addr_hyphen[] = "192.0.3.1";
3286
3287 // Used to verify DNS reverse query for classless reverse lookup zone. See detail in RFC 2317
3288 // section 4.
3289 const static std::vector<DnsRecord> records = {
3290 // The records for reverse querying "192.0.2.1" in the subnet with notation '/'.
3291 {"1.2.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0/25.2.0.192.in-addr.arpa."},
3292 {"1.0/25.2.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
3293
3294 // The records for reverse querying "192.0.3.1" in the subnet with notation '-'.
3295 {"1.3.0.192.in-addr.arpa.", ns_type::ns_t_cname, "1.0-127.3.0.192.in-addr.arpa."},
3296 {"1.0-127.3.0.192.in-addr.arpa.", ns_type::ns_t_ptr, kHelloExampleCom},
3297 };
3298
3299 test::DNSResponder dns;
3300 StartDns(dns, records);
3301 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3302
3303 for (const auto& address : {addr_slash, addr_hyphen}) {
3304 SCOPED_TRACE(address);
3305
3306 char host[NI_MAXHOST];
3307 sockaddr_in sin = {.sin_family = AF_INET};
3308 ASSERT_TRUE(inet_pton(AF_INET, address, &sin.sin_addr));
3309 int rv = getnameinfo((const sockaddr*)&sin, sizeof(sin), host, sizeof(host), nullptr, 0,
3310 NI_NAMEREQD);
3311 ASSERT_EQ(0, rv);
3312 EXPECT_STREQ("hello.example.com", host);
3313 }
3314}
3315
nuccachena26cc2a2018-07-17 18:07:23 +08003316TEST_F(ResolverTest, GetHostByName2_Dns64Synthesize) {
Xiao Ma09b71022018-12-11 17:56:32 +09003317 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08003318 constexpr char dns64_name[] = "ipv4only.arpa.";
3319 constexpr char host_name[] = "ipv4only.example.com.";
Xiao Ma09b71022018-12-11 17:56:32 +09003320 const std::vector<DnsRecord> records = {
3321 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
3322 {host_name, ns_type::ns_t_a, "1.2.3.4"},
3323 };
nuccachena26cc2a2018-07-17 18:07:23 +08003324
Xiao Ma09b71022018-12-11 17:56:32 +09003325 test::DNSResponder dns(listen_addr);
3326 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08003327 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003328 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003329
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003330 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003331 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003332 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003333
3334 // Query an IPv4-only hostname. Expect that gets a synthesized address.
3335 struct hostent* result = gethostbyname2("ipv4only", AF_INET6);
3336 ASSERT_TRUE(result != nullptr);
3337 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3338 std::string result_str = ToString(result);
3339 EXPECT_EQ(result_str, "64:ff9b::102:304");
3340}
nuccachena26cc2a2018-07-17 18:07:23 +08003341
3342TEST_F(ResolverTest, GetHostByName2_DnsQueryWithHavingNat64Prefix) {
3343 constexpr char dns64_name[] = "ipv4only.arpa.";
3344 constexpr char host_name[] = "v4v6.example.com.";
nuccachena26cc2a2018-07-17 18:07:23 +08003345 constexpr char listen_addr[] = "::1";
Xiao Ma09b71022018-12-11 17:56:32 +09003346 const std::vector<DnsRecord> records = {
3347 {dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"},
3348 {host_name, ns_type::ns_t_a, "1.2.3.4"},
3349 {host_name, ns_type::ns_t_aaaa, "2001:db8::1.2.3.4"},
3350 };
3351
3352 test::DNSResponder dns(listen_addr);
3353 StartDns(dns, records);
nuccachena26cc2a2018-07-17 18:07:23 +08003354 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003355 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003356
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003357 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003358 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003359 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003360
3361 // IPv4 DNS query. Prefix should have no effect on it.
3362 struct hostent* result = gethostbyname2("v4v6", AF_INET);
3363 ASSERT_TRUE(result != nullptr);
3364 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3365 std::string result_str = ToString(result);
3366 EXPECT_EQ(result_str, "1.2.3.4");
3367 dns.clearQueries();
3368
3369 // IPv6 DNS query. Prefix should have no effect on it.
3370 result = gethostbyname2("v4v6", AF_INET6);
3371 ASSERT_TRUE(result != nullptr);
3372 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3373 result_str = ToString(result);
3374 EXPECT_EQ(result_str, "2001:db8::102:304");
3375}
3376
3377TEST_F(ResolverTest, GetHostByName2_Dns64QuerySpecialUseIPv4Addresses) {
3378 constexpr char THIS_NETWORK[] = "this_network";
3379 constexpr char LOOPBACK[] = "loopback";
3380 constexpr char LINK_LOCAL[] = "link_local";
3381 constexpr char MULTICAST[] = "multicast";
3382 constexpr char LIMITED_BROADCAST[] = "limited_broadcast";
3383
3384 constexpr char ADDR_THIS_NETWORK[] = "0.0.0.1";
3385 constexpr char ADDR_LOOPBACK[] = "127.0.0.1";
3386 constexpr char ADDR_LINK_LOCAL[] = "169.254.0.1";
3387 constexpr char ADDR_MULTICAST[] = "224.0.0.1";
3388 constexpr char ADDR_LIMITED_BROADCAST[] = "255.255.255.255";
3389
3390 constexpr char listen_addr[] = "::1";
nuccachena26cc2a2018-07-17 18:07:23 +08003391 constexpr char dns64_name[] = "ipv4only.arpa.";
3392
Xiao Ma09b71022018-12-11 17:56:32 +09003393 test::DNSResponder dns(listen_addr);
3394 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::"}});
nuccachena26cc2a2018-07-17 18:07:23 +08003395 const std::vector<std::string> servers = {listen_addr};
Xiao Ma09b71022018-12-11 17:56:32 +09003396 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
nuccachena26cc2a2018-07-17 18:07:23 +08003397
Lorenzo Colittid39345c2019-02-18 10:59:29 +09003398 // Start NAT64 prefix discovery and wait for it to complete.
Luke Huang5bd827c2019-03-14 16:10:04 +08003399 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003400 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
nuccachena26cc2a2018-07-17 18:07:23 +08003401
Luke Huangf8215372019-11-22 11:53:41 +08003402 // clang-format off
nuccachena26cc2a2018-07-17 18:07:23 +08003403 static const struct TestConfig {
3404 std::string name;
3405 std::string addr;
3406
3407 std::string asHostName() const {
Luke Huangf8215372019-11-22 11:53:41 +08003408 return StringPrintf("%s.example.com.", name.c_str());
nuccachena26cc2a2018-07-17 18:07:23 +08003409 }
3410 } testConfigs[]{
3411 {THIS_NETWORK, ADDR_THIS_NETWORK},
3412 {LOOPBACK, ADDR_LOOPBACK},
3413 {LINK_LOCAL, ADDR_LINK_LOCAL},
3414 {MULTICAST, ADDR_MULTICAST},
3415 {LIMITED_BROADCAST, ADDR_LIMITED_BROADCAST}
3416 };
Luke Huangf8215372019-11-22 11:53:41 +08003417 // clang-format on
nuccachena26cc2a2018-07-17 18:07:23 +08003418
3419 for (const auto& config : testConfigs) {
3420 const std::string testHostName = config.asHostName();
3421 SCOPED_TRACE(testHostName);
3422
3423 const char* host_name = testHostName.c_str();
3424 dns.addMapping(host_name, ns_type::ns_t_a, config.addr.c_str());
3425
3426 struct hostent* result = gethostbyname2(config.name.c_str(), AF_INET6);
3427 EXPECT_LE(1U, GetNumQueries(dns, host_name));
3428
3429 // In AF_INET6 case, don't synthesize special use IPv4 address.
3430 // Expect to have no answer
3431 EXPECT_EQ(nullptr, result);
3432
3433 dns.clearQueries();
3434 }
Bernie Innocenti2fef2b82018-12-20 15:56:40 +09003435}
Mike Yuf14e1a92019-05-10 13:54:58 +08003436
3437TEST_F(ResolverTest, PrefixDiscoveryBypassTls) {
3438 constexpr char listen_addr[] = "::1";
3439 constexpr char cleartext_port[] = "53";
3440 constexpr char tls_port[] = "853";
3441 constexpr char dns64_name[] = "ipv4only.arpa.";
3442 const std::vector<std::string> servers = {listen_addr};
3443
3444 test::DNSResponder dns(listen_addr);
3445 StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}});
3446 test::DnsTlsFrontend tls(listen_addr, tls_port, listen_addr, cleartext_port);
3447 ASSERT_TRUE(tls.startServer());
3448
3449 // Setup OPPORTUNISTIC mode and wait for the validation complete.
waynema0e73c2e2019-07-31 15:04:08 +08003450 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams, ""));
Mike Yu724f77d2019-08-16 11:14:50 +08003451 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yuf14e1a92019-05-10 13:54:58 +08003452 tls.clearQueries();
3453
3454 // Start NAT64 prefix discovery and wait for it complete.
3455 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003456 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
Mike Yuf14e1a92019-05-10 13:54:58 +08003457
3458 // Verify it bypassed TLS even though there's a TLS server available.
3459 EXPECT_EQ(0, tls.queries());
3460 EXPECT_EQ(1U, GetNumQueries(dns, dns64_name));
3461
3462 // Restart the testing network to reset the cache.
3463 mDnsClient.TearDown();
3464 mDnsClient.SetUp();
3465 dns.clearQueries();
3466
3467 // Setup STRICT mode and wait for the validation complete.
waynema0e73c2e2019-07-31 15:04:08 +08003468 ASSERT_TRUE(mDnsClient.SetResolversWithTls(servers, kDefaultSearchDomains, kDefaultParams,
3469 kDefaultPrivateDnsHostName));
Mike Yu724f77d2019-08-16 11:14:50 +08003470 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
Mike Yuf14e1a92019-05-10 13:54:58 +08003471 tls.clearQueries();
3472
3473 // Start NAT64 prefix discovery and wait for it to complete.
3474 EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk());
Hungming Chene8f970c2019-04-10 17:34:06 +08003475 EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND));
Mike Yuf14e1a92019-05-10 13:54:58 +08003476
3477 // Verify it bypassed TLS despite STRICT mode.
3478 EXPECT_EQ(0, tls.queries());
3479 EXPECT_EQ(1U, GetNumQueries(dns, dns64_name));
3480}
Luke Huang9807e6b2019-05-20 16:17:12 +08003481
3482namespace {
3483
Luke Huang0d592bc2019-05-25 18:24:03 +08003484class ScopedSetNetworkForProcess {
3485 public:
3486 explicit ScopedSetNetworkForProcess(unsigned netId) {
3487 mStoredNetId = getNetworkForProcess();
3488 if (netId == mStoredNetId) return;
3489 EXPECT_EQ(0, setNetworkForProcess(netId));
3490 }
3491 ~ScopedSetNetworkForProcess() { EXPECT_EQ(0, setNetworkForProcess(mStoredNetId)); }
3492
3493 private:
3494 unsigned mStoredNetId;
3495};
3496
3497class ScopedSetNetworkForResolv {
3498 public:
3499 explicit ScopedSetNetworkForResolv(unsigned netId) { EXPECT_EQ(0, setNetworkForResolv(netId)); }
3500 ~ScopedSetNetworkForResolv() { EXPECT_EQ(0, setNetworkForResolv(NETID_UNSET)); }
3501};
3502
Luke Huang9807e6b2019-05-20 16:17:12 +08003503void sendCommand(int fd, const std::string& cmd) {
3504 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size() + 1));
3505 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size() + 1));
3506}
3507
3508int32_t readBE32(int fd) {
3509 int32_t tmp;
3510 int n = TEMP_FAILURE_RETRY(read(fd, &tmp, sizeof(tmp)));
3511 EXPECT_TRUE(n > 0);
3512 return ntohl(tmp);
3513}
3514
Luke Huang0d592bc2019-05-25 18:24:03 +08003515int readResponseCode(int fd) {
Luke Huang9807e6b2019-05-20 16:17:12 +08003516 char buf[4];
3517 int n = TEMP_FAILURE_RETRY(read(fd, &buf, sizeof(buf)));
3518 EXPECT_TRUE(n > 0);
3519 // The format of response code is that 4 bytes for the code & null.
3520 buf[3] = '\0';
3521 int result;
3522 EXPECT_TRUE(ParseInt(buf, &result));
3523 return result;
3524}
3525
Luke Huang0d592bc2019-05-25 18:24:03 +08003526bool checkAndClearUseLocalNameserversFlag(unsigned* netid) {
3527 if (netid == nullptr || ((*netid) & NETID_USE_LOCAL_NAMESERVERS) == 0) {
3528 return false;
3529 }
3530 *netid = (*netid) & ~NETID_USE_LOCAL_NAMESERVERS;
3531 return true;
3532}
3533
Luke Huangf8215372019-11-22 11:53:41 +08003534aidl::android::net::UidRangeParcel makeUidRangeParcel(int start, int stop) {
3535 aidl::android::net::UidRangeParcel res;
Luke Huang0d592bc2019-05-25 18:24:03 +08003536 res.start = start;
3537 res.stop = stop;
3538
3539 return res;
3540}
3541
3542void expectNetIdWithLocalNameserversFlag(unsigned netId) {
3543 unsigned dnsNetId = 0;
3544 EXPECT_EQ(0, getNetworkForDns(&dnsNetId));
3545 EXPECT_TRUE(checkAndClearUseLocalNameserversFlag(&dnsNetId));
3546 EXPECT_EQ(netId, static_cast<unsigned>(dnsNetId));
3547}
3548
3549void expectDnsNetIdEquals(unsigned netId) {
3550 unsigned dnsNetId = 0;
3551 EXPECT_EQ(0, getNetworkForDns(&dnsNetId));
3552 EXPECT_EQ(netId, static_cast<unsigned>(dnsNetId));
3553}
3554
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003555void expectDnsNetIdIsDefaultNetwork(INetd* netdService) {
Luke Huang0d592bc2019-05-25 18:24:03 +08003556 int currentNetid;
3557 EXPECT_TRUE(netdService->networkGetDefault(&currentNetid).isOk());
3558 expectDnsNetIdEquals(currentNetid);
3559}
3560
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003561void expectDnsNetIdWithVpn(INetd* netdService, unsigned vpnNetId, unsigned expectedNetId) {
Luke Huang0d592bc2019-05-25 18:24:03 +08003562 EXPECT_TRUE(netdService->networkCreateVpn(vpnNetId, false /* secure */).isOk());
3563 uid_t uid = getuid();
3564 // Add uid to VPN
3565 EXPECT_TRUE(netdService->networkAddUidRanges(vpnNetId, {makeUidRangeParcel(uid, uid)}).isOk());
3566 expectDnsNetIdEquals(expectedNetId);
3567 EXPECT_TRUE(netdService->networkDestroy(vpnNetId).isOk());
3568}
3569
Luke Huang9807e6b2019-05-20 16:17:12 +08003570} // namespace
3571
3572TEST_F(ResolverTest, getDnsNetId) {
3573 // We've called setNetworkForProcess in SetupOemNetwork, so reset to default first.
3574 setNetworkForProcess(NETID_UNSET);
Luke Huang0d592bc2019-05-25 18:24:03 +08003575
3576 expectDnsNetIdIsDefaultNetwork(mDnsClient.netdService());
3577 expectDnsNetIdWithVpn(mDnsClient.netdService(), TEST_VPN_NETID, TEST_VPN_NETID);
Luke Huang9807e6b2019-05-20 16:17:12 +08003578
3579 // Test with setNetworkForProcess
Luke Huang0d592bc2019-05-25 18:24:03 +08003580 {
3581 ScopedSetNetworkForProcess scopedSetNetworkForProcess(TEST_NETID);
3582 expectDnsNetIdEquals(TEST_NETID);
3583 }
3584
3585 // Test with setNetworkForProcess with NETID_USE_LOCAL_NAMESERVERS
3586 {
3587 ScopedSetNetworkForProcess scopedSetNetworkForProcess(TEST_NETID |
3588 NETID_USE_LOCAL_NAMESERVERS);
3589 expectNetIdWithLocalNameserversFlag(TEST_NETID);
3590 }
Luke Huang9807e6b2019-05-20 16:17:12 +08003591
3592 // Test with setNetworkForResolv
Luke Huang0d592bc2019-05-25 18:24:03 +08003593 {
3594 ScopedSetNetworkForResolv scopedSetNetworkForResolv(TEST_NETID);
3595 expectDnsNetIdEquals(TEST_NETID);
3596 }
3597
3598 // Test with setNetworkForResolv with NETID_USE_LOCAL_NAMESERVERS
3599 {
3600 ScopedSetNetworkForResolv scopedSetNetworkForResolv(TEST_NETID |
3601 NETID_USE_LOCAL_NAMESERVERS);
3602 expectNetIdWithLocalNameserversFlag(TEST_NETID);
3603 }
3604
3605 // Test with setNetworkForResolv under bypassable vpn
3606 {
3607 ScopedSetNetworkForResolv scopedSetNetworkForResolv(TEST_NETID);
3608 expectDnsNetIdWithVpn(mDnsClient.netdService(), TEST_VPN_NETID, TEST_NETID);
3609 }
Luke Huang9807e6b2019-05-20 16:17:12 +08003610
3611 // Create socket connected to DnsProxyListener
3612 int fd = dns_open_proxy();
3613 EXPECT_TRUE(fd > 0);
3614 unique_fd ufd(fd);
3615
3616 // Test command with wrong netId
3617 sendCommand(fd, "getdnsnetid abc");
Luke Huang0d592bc2019-05-25 18:24:03 +08003618 EXPECT_EQ(ResponseCode::DnsProxyQueryResult, readResponseCode(fd));
Luke Huang9807e6b2019-05-20 16:17:12 +08003619 EXPECT_EQ(-EINVAL, readBE32(fd));
3620
3621 // Test unsupported command
3622 sendCommand(fd, "getdnsnetidNotSupported");
3623 // Keep in sync with FrameworkListener.cpp (500, "Command not recognized")
Luke Huang0d592bc2019-05-25 18:24:03 +08003624 EXPECT_EQ(500, readResponseCode(fd));
Luke Huang9807e6b2019-05-20 16:17:12 +08003625}
Sehee Park2c118782019-05-07 13:02:45 +09003626
3627TEST_F(ResolverTest, BlockDnsQueryWithUidRule) {
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003628 // This test relies on blocking traffic on loopback, which xt_qtaguid does not do.
3629 // See aosp/358413 and b/34444781 for why.
3630 SKIP_IF_BPF_NOT_SUPPORTED;
3631
Sehee Park2c118782019-05-07 13:02:45 +09003632 constexpr char listen_addr1[] = "127.0.0.4";
3633 constexpr char listen_addr2[] = "::1";
3634 constexpr char host_name[] = "howdy.example.com.";
3635 const std::vector<DnsRecord> records = {
3636 {host_name, ns_type::ns_t_a, "1.2.3.4"},
3637 {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
3638 };
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003639 INetd* netdService = mDnsClient.netdService();
Sehee Park2c118782019-05-07 13:02:45 +09003640
3641 test::DNSResponder dns1(listen_addr1);
3642 test::DNSResponder dns2(listen_addr2);
3643 StartDns(dns1, records);
3644 StartDns(dns2, records);
3645
3646 std::vector<std::string> servers = {listen_addr1, listen_addr2};
3647 ASSERT_TRUE(mDnsClient.SetResolversForNetwork(servers));
3648 dns1.clearQueries();
3649 dns2.clearQueries();
3650
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003651 // Add drop rule for TEST_UID. Also enable the standby chain because it might not be enabled.
3652 // Unfortunately we cannot use FIREWALL_CHAIN_NONE, or custom iptables rules, for this purpose
3653 // because netd calls fchown() on the DNS query sockets, and "iptables -m owner" matches the
3654 // UID of the socket creator, not the UID set by fchown().
3655 //
3656 // TODO: migrate FIREWALL_CHAIN_NONE to eBPF as well.
3657 EXPECT_TRUE(netdService->firewallEnableChildChain(INetd::FIREWALL_CHAIN_STANDBY, true).isOk());
3658 EXPECT_TRUE(netdService
Sehee Park2c118782019-05-07 13:02:45 +09003659 ->firewallSetUidRule(INetd::FIREWALL_CHAIN_STANDBY, TEST_UID,
3660 INetd::FIREWALL_RULE_DENY)
3661 .isOk());
3662
3663 // Save uid
3664 int suid = getuid();
3665
3666 // Switch to TEST_UID
3667 EXPECT_TRUE(seteuid(TEST_UID) == 0);
3668
3669 // Dns Query
3670 int fd1 = resNetworkQuery(TEST_NETID, host_name, ns_c_in, ns_t_a, 0);
3671 int fd2 = resNetworkQuery(TEST_NETID, host_name, ns_c_in, ns_t_aaaa, 0);
3672 EXPECT_TRUE(fd1 != -1);
3673 EXPECT_TRUE(fd2 != -1);
3674
3675 uint8_t buf[MAXPACKET] = {};
3676 int rcode;
3677 int res = getAsyncResponse(fd2, &rcode, buf, MAXPACKET);
3678 EXPECT_EQ(-ECONNREFUSED, res);
3679
3680 memset(buf, 0, MAXPACKET);
3681 res = getAsyncResponse(fd1, &rcode, buf, MAXPACKET);
3682 EXPECT_EQ(-ECONNREFUSED, res);
3683
3684 // Restore uid
3685 EXPECT_TRUE(seteuid(suid) == 0);
3686
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003687 // Remove drop rule for TEST_UID, and disable the standby chain.
3688 EXPECT_TRUE(netdService
Sehee Park2c118782019-05-07 13:02:45 +09003689 ->firewallSetUidRule(INetd::FIREWALL_CHAIN_STANDBY, TEST_UID,
3690 INetd::FIREWALL_RULE_ALLOW)
3691 .isOk());
Lorenzo Colittieb9aeec2019-06-26 19:53:55 +09003692 EXPECT_TRUE(netdService->firewallEnableChildChain(INetd::FIREWALL_CHAIN_STANDBY, false).isOk());
Sehee Park2c118782019-05-07 13:02:45 +09003693}
Mike Yua772c202019-09-23 17:47:21 +08003694
Mike Yu40e67072019-10-09 21:14:09 +08003695namespace {
3696
3697const std::string kDotConnectTimeoutMsFlag(
3698 "persist.device_config.netd_native.dot_connect_timeout_ms");
3699
3700class ScopedSystemProperties {
3701 public:
3702 explicit ScopedSystemProperties(const std::string& key, const std::string& value)
3703 : mStoredKey(key) {
3704 mStoredValue = android::base::GetProperty(key, "");
3705 android::base::SetProperty(key, value);
3706 }
3707 ~ScopedSystemProperties() { android::base::SetProperty(mStoredKey, mStoredValue); }
3708
3709 private:
3710 std::string mStoredKey;
3711 std::string mStoredValue;
3712};
3713
3714} // namespace
3715
Mike Yua772c202019-09-23 17:47:21 +08003716TEST_F(ResolverTest, ConnectTlsServerTimeout) {
Mike Yu40e67072019-10-09 21:14:09 +08003717 constexpr int expectedTimeout = 1000;
3718 constexpr char hostname1[] = "query1.example.com.";
3719 constexpr char hostname2[] = "query2.example.com.";
Mike Yua772c202019-09-23 17:47:21 +08003720 const std::vector<DnsRecord> records = {
Mike Yu40e67072019-10-09 21:14:09 +08003721 {hostname1, ns_type::ns_t_a, "1.2.3.4"},
3722 {hostname2, ns_type::ns_t_a, "1.2.3.5"},
Mike Yua772c202019-09-23 17:47:21 +08003723 };
3724
3725 test::DNSResponder dns;
3726 StartDns(dns, records);
Mike Yu40e67072019-10-09 21:14:09 +08003727 test::DnsTlsFrontend tls;
Mike Yua772c202019-09-23 17:47:21 +08003728 ASSERT_TRUE(tls.startServer());
3729
Mike Yu40e67072019-10-09 21:14:09 +08003730 // The resolver will adjust the timeout value to 1000ms since the value is too small.
3731 ScopedSystemProperties scopedSystemProperties(kDotConnectTimeoutMsFlag, "100");
Mike Yua772c202019-09-23 17:47:21 +08003732
Mike Yu40e67072019-10-09 21:14:09 +08003733 // Set up resolver to opportunistic mode with the default configuration.
Mike Yu8ac63402019-12-02 15:28:38 +08003734 const ResolverParamsParcel parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
Mike Yu40e67072019-10-09 21:14:09 +08003735 ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
Mike Yua772c202019-09-23 17:47:21 +08003736 EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true));
3737 dns.clearQueries();
3738 tls.clearQueries();
3739
3740 // The server becomes unresponsive to the handshake request.
3741 tls.setHangOnHandshakeForTesting(true);
3742
3743 // Expect the things happening in getaddrinfo():
3744 // 1. Connect to the private DNS server.
3745 // 2. SSL handshake times out.
3746 // 3. Fallback to UDP transport, and then get the answer.
Mike Yu40e67072019-10-09 21:14:09 +08003747 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
3748 auto [result, timeTakenMs] = safe_getaddrinfo_time_taken(hostname1, nullptr, hints);
Mike Yua772c202019-09-23 17:47:21 +08003749
Mike Yu40e67072019-10-09 21:14:09 +08003750 EXPECT_NE(nullptr, result);
Mike Yua772c202019-09-23 17:47:21 +08003751 EXPECT_EQ(0, tls.queries());
Mike Yu40e67072019-10-09 21:14:09 +08003752 EXPECT_EQ(1U, GetNumQueries(dns, hostname1));
3753 EXPECT_EQ(records.at(0).addr, ToString(result));
Mike Yua772c202019-09-23 17:47:21 +08003754
Mike Yu40e67072019-10-09 21:14:09 +08003755 // A loose upper bound is set by adding 2000ms buffer time. Theoretically, getaddrinfo()
3756 // should just take a bit more than expetTimeout milliseconds.
3757 EXPECT_GE(timeTakenMs, expectedTimeout);
3758 EXPECT_LE(timeTakenMs, expectedTimeout + 2000);
3759
3760 // Set the server to be responsive. Verify that the resolver will attempt to reconnect
3761 // to the server and then get the result within the timeout.
3762 tls.setHangOnHandshakeForTesting(false);
3763 std::tie(result, timeTakenMs) = safe_getaddrinfo_time_taken(hostname2, nullptr, hints);
3764
3765 EXPECT_NE(nullptr, result);
3766 EXPECT_EQ(1, tls.queries());
3767 EXPECT_EQ(1U, GetNumQueries(dns, hostname2));
3768 EXPECT_EQ(records.at(1).addr, ToString(result));
3769
3770 EXPECT_LE(timeTakenMs, expectedTimeout);
Mike Yua772c202019-09-23 17:47:21 +08003771}
Hungming Chenbb90ab32019-10-28 18:20:31 +08003772
Ken Chen766feae2019-10-30 15:13:44 +08003773TEST_F(ResolverTest, FlushNetworkCache) {
Luke Huang0b5a76c2019-11-23 03:00:00 +08003774 SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsClient.resolvService(), 4);
Ken Chen766feae2019-10-30 15:13:44 +08003775 test::DNSResponder dns;
3776 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3777 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3778
3779 const hostent* result = gethostbyname("hello");
3780 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
3781
3782 // get result from cache
3783 result = gethostbyname("hello");
3784 EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
3785
3786 EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk());
3787
3788 result = gethostbyname("hello");
3789 EXPECT_EQ(2U, GetNumQueriesForType(dns, ns_type::ns_t_a, kHelloExampleCom));
3790}
3791
3792TEST_F(ResolverTest, FlushNetworkCache_random) {
Luke Huang0b5a76c2019-11-23 03:00:00 +08003793 SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsClient.resolvService(), 4);
Ken Chen766feae2019-10-30 15:13:44 +08003794 constexpr int num_flush = 10;
3795 constexpr int num_queries = 20;
3796 test::DNSResponder dns;
3797 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3798 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3799 const addrinfo hints = {.ai_family = AF_INET};
3800
3801 std::thread t([this]() {
3802 for (int i = 0; i < num_flush; ++i) {
3803 unsigned delay = arc4random_uniform(10 * 1000); // 10ms
3804 usleep(delay);
3805 EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk());
3806 }
3807 });
3808
3809 for (int i = 0; i < num_queries; ++i) {
3810 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3811 EXPECT_TRUE(result != nullptr);
3812 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3813 }
3814 t.join();
3815}
3816
3817// flush cache while one query is wait-for-response, another is pending.
3818TEST_F(ResolverTest, FlushNetworkCache_concurrent) {
Luke Huang0b5a76c2019-11-23 03:00:00 +08003819 SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsClient.resolvService(), 4);
Ken Chen766feae2019-10-30 15:13:44 +08003820 const char* listen_addr1 = "127.0.0.9";
3821 const char* listen_addr2 = "127.0.0.10";
3822 test::DNSResponder dns1(listen_addr1);
3823 test::DNSResponder dns2(listen_addr2);
3824 StartDns(dns1, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3825 StartDns(dns2, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3826 addrinfo hints = {.ai_family = AF_INET};
3827
3828 // step 1: set server#1 into deferred responding mode
3829 dns1.setDeferredResp(true);
3830 std::thread t1([&listen_addr1, &hints, this]() {
3831 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr1}));
3832 // step 3: query
3833 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3834 // step 9: check result
3835 EXPECT_TRUE(result != nullptr);
3836 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3837 });
3838
3839 // step 2: wait for the query to reach the server
3840 while (GetNumQueries(dns1, kHelloExampleCom) == 0) {
3841 usleep(1000); // 1ms
3842 }
3843
3844 std::thread t2([&listen_addr2, &hints, &dns2, this]() {
3845 ASSERT_TRUE(mDnsClient.SetResolversForNetwork({listen_addr2}));
3846 // step 5: query (should be blocked in resolver)
3847 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3848 // step 7: check result
3849 EXPECT_TRUE(result != nullptr);
3850 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3851 EXPECT_EQ(1U, GetNumQueriesForType(dns2, ns_type::ns_t_a, kHelloExampleCom));
3852 });
3853
3854 // step 4: wait a bit for the 2nd query to enter pending state
3855 usleep(100 * 1000); // 100ms
3856 // step 6: flush cache (will unblock pending queries)
3857 EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk());
3858 t2.join();
3859
3860 // step 8: resume server#1
3861 dns1.setDeferredResp(false);
3862 t1.join();
3863
3864 // step 10: verify if result is correctly cached
3865 dns2.clearQueries();
3866 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3867 EXPECT_EQ(0U, GetNumQueries(dns2, kHelloExampleCom));
3868 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3869}
3870
waynema29253052019-08-20 11:26:08 +08003871// TODO: Perhaps to have a boundary conditions test for TCP and UDP.
3872TEST_F(ResolverTest, TcpQueryWithOversizePayload) {
3873 test::DNSResponder dns;
3874 StartDns(dns, {{kHelloExampleCom, ns_type::ns_t_a, kHelloExampleComAddrV4}});
3875 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
3876
3877 int fd = dns_open_proxy();
3878 ASSERT_TRUE(fd > 0);
3879
3880 // Sending DNS query over TCP once the packet sizes exceed 512 bytes.
3881 // The raw data is combined with Question section and Additional section
3882 // Question section : query "hello.example.com", type A, class IN
3883 // Additional section : type OPT (41), Option PADDING, Option Length 546
3884 // Padding option which allows DNS clients and servers to artificially
3885 // increase the size of a DNS message by a variable number of bytes.
3886 // See also RFC7830, section 3
3887 const std::string query =
3888 "+c0BAAABAAAAAAABBWhlbGxvB2V4YW1wbGUDY29tAAABAAEAACkgAAAAgAACJgAMAiIAAAAAAAAAAAAAAAAAA"
3889 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
3890 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
3891 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
3892 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
3893 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
3894 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
3895 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
3896 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
3897 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
3898 const std::string cmd =
3899 "resnsend " + std::to_string(TEST_NETID) + " 0 " /* ResNsendFlags */ + query + '\0';
3900 ssize_t rc = TEMP_FAILURE_RETRY(write(fd, cmd.c_str(), cmd.size()));
3901 EXPECT_EQ(rc, static_cast<ssize_t>(cmd.size()));
3902 expectAnswersValid(fd, AF_INET, kHelloExampleComAddrV4);
3903 EXPECT_EQ(1U, GetNumQueriesForProtocol(dns, IPPROTO_TCP, kHelloExampleCom));
3904 EXPECT_EQ(0U, GetNumQueriesForProtocol(dns, IPPROTO_UDP, kHelloExampleCom));
3905}
3906
Hungming Chenbb90ab32019-10-28 18:20:31 +08003907// Parameterized tests.
3908// TODO: Merge the existing tests as parameterized test if possible.
3909// TODO: Perhaps move parameterized tests to an independent file.
3910enum class CallType { GETADDRINFO, GETHOSTBYNAME };
3911class ResolverParameterizedTest : public ResolverTest,
Hungming Chen63779052019-10-30 15:06:13 +08003912 public testing::WithParamInterface<CallType> {
3913 protected:
Hungming Chen22617fd2019-12-06 12:15:45 +08003914 void VerifyQueryHelloExampleComV4(const test::DNSResponder& dns, const CallType calltype,
3915 const bool verifyNumQueries = true) {
Hungming Chen63779052019-10-30 15:06:13 +08003916 if (calltype == CallType::GETADDRINFO) {
3917 const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
3918 ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
3919 ASSERT_TRUE(result != nullptr);
3920 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3921 } else if (calltype == CallType::GETHOSTBYNAME) {
3922 const hostent* result = gethostbyname("hello");
3923 ASSERT_TRUE(result != nullptr);
3924 ASSERT_EQ(4, result->h_length);
3925 ASSERT_FALSE(result->h_addr_list[0] == nullptr);
3926 EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
3927 EXPECT_TRUE(result->h_addr_list[1] == nullptr);
3928 } else {
3929 FAIL() << "Unsupported call type: " << static_cast<uint32_t>(calltype);
3930 }
Hungming Chen22617fd2019-12-06 12:15:45 +08003931 if (verifyNumQueries) EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom));
Hungming Chen63779052019-10-30 15:06:13 +08003932 }
3933};
Hungming Chenbb90ab32019-10-28 18:20:31 +08003934
Hungming Chen63779052019-10-30 15:06:13 +08003935INSTANTIATE_TEST_SUITE_P(QueryCallTest, ResolverParameterizedTest,
Hungming Chenbb90ab32019-10-28 18:20:31 +08003936 testing::Values(CallType::GETADDRINFO, CallType::GETHOSTBYNAME),
3937 [](const testing::TestParamInfo<CallType>& info) {
Hungming Chenbb90ab32019-10-28 18:20:31 +08003938 switch (info.param) {
3939 case CallType::GETADDRINFO:
Hungming Chen63779052019-10-30 15:06:13 +08003940 return "GetAddrInfo";
Hungming Chenbb90ab32019-10-28 18:20:31 +08003941 case CallType::GETHOSTBYNAME:
Hungming Chen63779052019-10-30 15:06:13 +08003942 return "GetHostByName";
Hungming Chenbb90ab32019-10-28 18:20:31 +08003943 default:
Hungming Chen63779052019-10-30 15:06:13 +08003944 return "InvalidParameter"; // Should not happen.
Hungming Chenbb90ab32019-10-28 18:20:31 +08003945 }
Hungming Chenbb90ab32019-10-28 18:20:31 +08003946 });
3947
3948TEST_P(ResolverParameterizedTest, AuthoritySectionAndAdditionalSection) {
3949 // DNS response may have more information in authority section and additional section.
3950 // Currently, getanswer() of packages/modules/DnsResolver/getaddrinfo.cpp doesn't parse the
3951 // content of authority section and additional section. Test these sections if they crash
3952 // the resolver, just in case. See also RFC 1035 section 4.1.
3953 const auto& calltype = GetParam();
3954 test::DNSHeader header(kDefaultDnsHeader);
3955
3956 // Create a DNS response which has a authoritative nameserver record in authority
3957 // section and its relevant address record in additional section.
3958 //
3959 // Question
3960 // hello.example.com. IN A
3961 // Answer
3962 // hello.example.com. IN A 1.2.3.4
3963 // Authority:
3964 // hello.example.com. IN NS ns1.example.com.
3965 // Additional:
3966 // ns1.example.com. IN A 5.6.7.8
3967 //
3968 // A response may have only question, answer, and authority section. Current testing response
3969 // should be able to cover this condition.
3970
3971 // Question section.
3972 test::DNSQuestion question{
3973 .qname = {.name = kHelloExampleCom},
3974 .qtype = ns_type::ns_t_a,
3975 .qclass = ns_c_in,
3976 };
3977 header.questions.push_back(std::move(question));
3978
3979 // Answer section.
3980 test::DNSRecord recordAnswer{
3981 .name = {.name = kHelloExampleCom},
3982 .rtype = ns_type::ns_t_a,
3983 .rclass = ns_c_in,
3984 .ttl = 0, // no cache
3985 };
Hungming Chen63779052019-10-30 15:06:13 +08003986 EXPECT_TRUE(test::DNSResponder::fillRdata(kHelloExampleComAddrV4, recordAnswer));
Hungming Chenbb90ab32019-10-28 18:20:31 +08003987 header.answers.push_back(std::move(recordAnswer));
3988
3989 // Authority section.
3990 test::DNSRecord recordAuthority{
3991 .name = {.name = kHelloExampleCom},
3992 .rtype = ns_type::ns_t_ns,
3993 .rclass = ns_c_in,
3994 .ttl = 0, // no cache
3995 };
3996 EXPECT_TRUE(test::DNSResponder::fillRdata("ns1.example.com.", recordAuthority));
3997 header.authorities.push_back(std::move(recordAuthority));
3998
3999 // Additional section.
4000 test::DNSRecord recordAdditional{
4001 .name = {.name = "ns1.example.com."},
4002 .rtype = ns_type::ns_t_a,
4003 .rclass = ns_c_in,
4004 .ttl = 0, // no cache
4005 };
4006 EXPECT_TRUE(test::DNSResponder::fillRdata("5.6.7.8", recordAdditional));
4007 header.additionals.push_back(std::move(recordAdditional));
4008
4009 // Start DNS server.
4010 test::DNSResponder dns(test::DNSResponder::MappingType::DNS_HEADER);
4011 dns.addMappingDnsHeader(kHelloExampleCom, ns_type::ns_t_a, header);
4012 ASSERT_TRUE(dns.startServer());
4013 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
4014 dns.clearQueries();
4015
4016 // Expect that get the address and the resolver doesn't crash.
Hungming Chen63779052019-10-30 15:06:13 +08004017 VerifyQueryHelloExampleComV4(dns, calltype);
4018}
4019
4020TEST_P(ResolverParameterizedTest, MessageCompression) {
4021 const auto& calltype = GetParam();
4022
4023 // The response with compressed domain name by a pointer. See RFC 1035 section 4.1.4.
4024 //
4025 // Ignoring the other fields of the message, the domain name of question section and answer
4026 // section are presented as:
4027 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4028 // 12 | 5 | h |
4029 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4030 // 14 | e | l |
4031 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4032 // 16 | l | o |
4033 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4034 // 18 | 7 | e |
4035 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4036 // 20 | x | a |
4037 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4038 // 22 | m | p |
4039 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4040 // 24 | l | e |
4041 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4042 // 26 | 3 | c |
4043 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4044 // 28 | o | m |
4045 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4046 // 30 | 0 | ... |
4047 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4048 //
4049 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4050 // 35 | 1 1| 12 |
4051 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4052 const std::vector<uint8_t> kResponseAPointer = {
4053 /* Header */
4054 0x00, 0x00, /* Transaction ID: 0x0000 */
4055 0x81, 0x80, /* Flags: qr rd ra */
4056 0x00, 0x01, /* Questions: 1 */
4057 0x00, 0x01, /* Answer RRs: 1 */
4058 0x00, 0x00, /* Authority RRs: 0 */
4059 0x00, 0x00, /* Additional RRs: 0 */
4060 /* Queries */
4061 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
4062 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */
4063 0x00, 0x01, /* Type: A */
4064 0x00, 0x01, /* Class: IN */
4065 /* Answers */
4066 0xc0, 0x0c, /* Name: hello.example.com (a pointer) */
4067 0x00, 0x01, /* Type: A */
4068 0x00, 0x01, /* Class: IN */
4069 0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */
4070 0x00, 0x04, /* Data length: 4 */
4071 0x01, 0x02, 0x03, 0x04 /* Address: 1.2.3.4 */
4072 };
4073
4074 // The response with compressed domain name by a sequence of labels ending with a pointer. See
4075 // RFC 1035 section 4.1.4.
4076 //
4077 // Ignoring the other fields of the message, the domain name of question section and answer
4078 // section are presented as:
4079 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4080 // 12 | 5 | h |
4081 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4082 // 14 | e | l |
4083 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4084 // 16 | l | o |
4085 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4086 // 18 | 7 | e |
4087 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4088 // 20 | x | a |
4089 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4090 // 22 | m | p |
4091 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4092 // 24 | l | e |
4093 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4094 // 26 | 3 | c |
4095 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4096 // 28 | o | m |
4097 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4098 // 30 | 0 | ... |
4099 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4100 //
4101 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4102 // 35 | 5 | h |
4103 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4104 // 37 | e | l |
4105 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4106 // 39 | l | o |
4107 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4108 // 41 | 1 1| 18 |
4109 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4110 const std::vector<uint8_t> kResponseLabelEndingWithAPointer = {
4111 /* Header */
4112 0x00, 0x00, /* Transaction ID: 0x0000 */
4113 0x81, 0x80, /* Flags: qr rd ra */
4114 0x00, 0x01, /* Questions: 1 */
4115 0x00, 0x01, /* Answer RRs: 1 */
4116 0x00, 0x00, /* Authority RRs: 0 */
4117 0x00, 0x00, /* Additional RRs: 0 */
4118 /* Queries */
4119 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
4120 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */
4121 0x00, 0x01, /* Type: A */
4122 0x00, 0x01, /* Class: IN */
4123 /* Answers */
4124 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0xc0,
4125 0x12, /* Name: hello.example.com (a label ending with a pointer) */
4126 0x00, 0x01, /* Type: A */
4127 0x00, 0x01, /* Class: IN */
4128 0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */
4129 0x00, 0x04, /* Data length: 4 */
4130 0x01, 0x02, 0x03, 0x04 /* Address: 1.2.3.4 */
4131 };
4132
4133 for (const auto& response : {kResponseAPointer, kResponseLabelEndingWithAPointer}) {
4134 SCOPED_TRACE(StringPrintf("Hex dump: %s", toHex(makeSlice(response)).c_str()));
4135
4136 test::DNSResponder dns(test::DNSResponder::MappingType::BINARY_PACKET);
4137 dns.addMappingBinaryPacket(kHelloExampleComQueryV4, response);
4138 StartDns(dns, {});
4139 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
4140
4141 // Expect no cache because the TTL of testing responses are 0.
4142 VerifyQueryHelloExampleComV4(dns, calltype);
Hungming Chenbb90ab32019-10-28 18:20:31 +08004143 }
Mike Yu40e67072019-10-09 21:14:09 +08004144}
Hungming Chen22617fd2019-12-06 12:15:45 +08004145
4146TEST_P(ResolverParameterizedTest, TruncatedResponse) {
4147 const auto& calltype = GetParam();
4148
4149 const size_t kMaxmiumLabelSize = 63; // see RFC 1035 section 2.3.4.
4150 const std::string kDomainName = ".example.com.";
4151 const std::string kCnameA = std::string(kMaxmiumLabelSize, 'a') + kDomainName;
4152 const std::string kCnameB = std::string(kMaxmiumLabelSize, 'b') + kDomainName;
4153 const std::string kCnameC = std::string(kMaxmiumLabelSize, 'c') + kDomainName;
4154 const std::string kCnameD = std::string(kMaxmiumLabelSize, 'd') + kDomainName;
4155
4156 // Build a response message which exceeds 512 bytes by CNAME chain.
4157 //
4158 // Ignoring the other fields of the message, the response message has 8 CNAMEs in 5 answer RRs
4159 // and each CNAME has 77 bytes as the follows. The response message at least has 616 bytes in
4160 // answer section and has already exceeded 512 bytes totally.
4161 //
4162 // The CNAME is presented as:
4163 // 0 1 64 65 72 73 76 77
4164 // +---+--........--+---+---+---+---+---+---+---+---+---+---+---+---+---+
4165 // | 63| {x, .., x} | 7 | e | x | a | m | p | l | e | 3 | c | o | m | 0 |
4166 // +---+--........--+---+---+---+---+---+---+---+---+---+---+---+---+---+
4167 // ^-- x = {a, b, c, d}
4168 //
4169 const std::vector<DnsRecord> records = {
4170 {kHelloExampleCom, ns_type::ns_t_cname, kCnameA},
4171 {kCnameA, ns_type::ns_t_cname, kCnameB},
4172 {kCnameB, ns_type::ns_t_cname, kCnameC},
4173 {kCnameC, ns_type::ns_t_cname, kCnameD},
4174 {kCnameD, ns_type::ns_t_a, kHelloExampleComAddrV4},
4175 };
4176 test::DNSResponder dns;
4177 StartDns(dns, records);
4178 ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
4179
4180 // Expect UDP response is truncated. The resolver retries over TCP. See RFC 1035 section 4.2.1.
4181 VerifyQueryHelloExampleComV4(dns, calltype, false);
4182 EXPECT_EQ(1U, GetNumQueriesForProtocol(dns, IPPROTO_UDP, kHelloExampleCom));
4183 EXPECT_EQ(1U, GetNumQueriesForProtocol(dns, IPPROTO_TCP, kHelloExampleCom));
4184}