1 /*
2 * Copyright (C) 2019 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 *
10 * Unless required by applicable law or agreed to in writing, software
11 * 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 #define LOG_TAG "dns_responder_client"
18
19 #include "dns_responder_client_ndk.h"
20
21 #include <android/binder_manager.h>
22 #include "NetdClient.h"
23
24 #define TEST_NETID 30
25
26 // TODO: move this somewhere shared.
27 static const char* ANDROID_DNS_MODE = "ANDROID_DNS_MODE";
28
29 using aidl::android::net::IDnsResolver;
30 using aidl::android::net::INetd;
31 using aidl::android::net::ResolverOptionsParcel;
32 using aidl::android::net::ResolverParamsParcel;
33 using aidl::android::net::resolv::aidl::DohParamsParcel;
34 using android::base::Error;
35 using android::base::Result;
36 using android::net::ResolverStats;
37
Builder()38 ResolverParams::Builder::Builder() {
39 // Default resolver configuration for opportunistic mode.
40 mParcel.netId = TEST_NETID;
41
42 // Default Resolver params.
43 mParcel.sampleValiditySeconds = 300;
44 mParcel.successThreshold = 25;
45 mParcel.minSamples = 8;
46 mParcel.maxSamples = 8;
47 mParcel.baseTimeoutMsec = 1000;
48 mParcel.retryCount = 2;
49
50 mParcel.servers = {kDefaultServer};
51 mParcel.domains = {kDefaultSearchDomain};
52 mParcel.tlsServers = {kDefaultServer};
53 mParcel.caCertificate = kCaCert;
54 mParcel.resolverOptions = ResolverOptionsParcel{}; // optional, must be explicitly set.
55 mParcel.dohParams = std::nullopt;
56 // This is currently not configurable. Tests relying on DnsResponderClient, are currently
57 // creating a network with no interfaces. They then end up relying on local communication to
58 // receive and send DNS queries. Adding "lo" as an interface for |TEST_NETID| makes that
59 // dependency explicit, allowing mDNS multicast queries to be sent via
60 // IP_MULTICAST_IF/IPV6_MULTICAST_IF.
61 mParcel.interfaceNames = {"lo"};
62 }
63
SetupMappings(unsigned numHosts,const std::vector<std::string> & domains,std::vector<Mapping> * mappings)64 void DnsResponderClient::SetupMappings(unsigned numHosts, const std::vector<std::string>& domains,
65 std::vector<Mapping>* mappings) {
66 mappings->resize(numHosts * domains.size());
67 auto mappingsIt = mappings->begin();
68 for (unsigned i = 0; i < numHosts; ++i) {
69 for (const auto& domain : domains) {
70 mappingsIt->host = fmt::format("host{}", i);
71 mappingsIt->entry = fmt::format("{}.{}.", mappingsIt->host, domain);
72 mappingsIt->ip4 = fmt::format("192.0.2.{}", i % 253 + 1);
73 mappingsIt->ip6 = fmt::format("2001:db8::{:x}", i % 65534 + 1);
74 ++mappingsIt;
75 }
76 }
77 }
78
getResolverInfo()79 Result<ResolverInfo> DnsResponderClient::getResolverInfo() {
80 std::vector<std::string> dnsServers;
81 std::vector<std::string> domains;
82 std::vector<std::string> dotServers;
83 std::vector<int32_t> params;
84 std::vector<int32_t> stats;
85 std::vector<int32_t> waitForPendingReqTimeoutCount{0};
86 auto rv = mDnsResolvSrv->getResolverInfo(TEST_NETID, &dnsServers, &domains, &dotServers,
87 ¶ms, &stats, &waitForPendingReqTimeoutCount);
88 if (!rv.isOk()) {
89 return Error() << "getResolverInfo failed: " << rv.getMessage();
90 }
91 if (stats.size() % IDnsResolver::RESOLVER_STATS_COUNT != 0) {
92 return Error() << "Unexpected stats size: " << stats.size();
93 }
94 if (params.size() != IDnsResolver::RESOLVER_PARAMS_COUNT) {
95 return Error() << "Unexpected params size: " << params.size();
96 }
97 if (waitForPendingReqTimeoutCount.size() != 1) {
98 return Error() << "Unexpected waitForPendingReqTimeoutCount size: "
99 << waitForPendingReqTimeoutCount.size();
100 }
101
102 ResolverInfo out = {
103 .dnsServers = std::move(dnsServers),
104 .domains = std::move(domains),
105 .dotServers = std::move(dotServers),
106 .params{
107 .sample_validity = static_cast<uint16_t>(
108 params[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY]),
109 .success_threshold = static_cast<uint8_t>(
110 params[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD]),
111 .min_samples =
112 static_cast<uint8_t>(params[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES]),
113 .max_samples =
114 static_cast<uint8_t>(params[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES]),
115 .base_timeout_msec = params[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC],
116 .retry_count = params[IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT],
117 },
118 .stats = {},
119 .waitForPendingReqTimeoutCount = waitForPendingReqTimeoutCount[0],
120 };
121 ResolverStats::decodeAll(stats, &out.stats);
122
123 return std::move(out);
124 }
125
SetResolversForNetwork(const std::vector<std::string> & servers,const std::vector<std::string> & domains)126 bool DnsResponderClient::SetResolversForNetwork(const std::vector<std::string>& servers,
127 const std::vector<std::string>& domains) {
128 const auto resolverParams = ResolverParams::Builder()
129 .setDomains(domains)
130 .setDnsServers(servers)
131 .setDotServers({})
132 .build();
133 const auto rv = mDnsResolvSrv->setResolverConfiguration(resolverParams);
134 return rv.isOk();
135 }
136
SetResolversFromParcel(const ResolverParamsParcel & resolverParams)137 bool DnsResponderClient::SetResolversFromParcel(const ResolverParamsParcel& resolverParams) {
138 const auto rv = mDnsResolvSrv->setResolverConfiguration(resolverParams);
139 if (!rv.isOk()) LOG(ERROR) << "SetResolversFromParcel() -> " << rv.getMessage();
140 return rv.isOk();
141 }
142
GetDefaultResolverParamsParcel()143 ResolverParamsParcel DnsResponderClient::GetDefaultResolverParamsParcel() {
144 return ResolverParams::Builder().build();
145 }
146
SetupDNSServers(unsigned numServers,const std::vector<Mapping> & mappings,std::vector<std::unique_ptr<test::DNSResponder>> * dns,std::vector<std::string> * servers)147 void DnsResponderClient::SetupDNSServers(unsigned numServers, const std::vector<Mapping>& mappings,
148 std::vector<std::unique_ptr<test::DNSResponder>>* dns,
149 std::vector<std::string>* servers) {
150 const char* listenSrv = "53";
151 dns->resize(numServers);
152 servers->resize(numServers);
153 for (unsigned i = 0; i < numServers; ++i) {
154 auto& server = (*servers)[i];
155 auto& d = (*dns)[i];
156 server = fmt::format("127.0.0.{}", i + 100);
157 d = std::make_unique<test::DNSResponder>(server, listenSrv, ns_rcode::ns_r_servfail);
158 for (const auto& mapping : mappings) {
159 d->addMapping(mapping.entry.c_str(), ns_type::ns_t_a, mapping.ip4.c_str());
160 d->addMapping(mapping.entry.c_str(), ns_type::ns_t_aaaa, mapping.ip6.c_str());
161 }
162 d->startServer();
163 }
164 }
165
SetupOemNetwork(int oemNetId)166 int DnsResponderClient::SetupOemNetwork(int oemNetId) {
167 mNetdSrv->networkDestroy(oemNetId);
168 mDnsResolvSrv->destroyNetworkCache(oemNetId);
169
170 ::ndk::ScopedAStatus ret;
171 if (DnsResponderClient::isRemoteVersionSupported(mNetdSrv, 6)) {
172 const auto& config = DnsResponderClient::makeNativeNetworkConfig(
173 oemNetId, NativeNetworkType::PHYSICAL, INetd::PERMISSION_NONE, /*secure=*/false);
174 ret = mNetdSrv->networkCreate(config);
175 } else {
176 // Only for presubmit tests that run mainline module (and its tests) on R or earlier images.
177 #pragma clang diagnostic push
178 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
179 ret = mNetdSrv->networkCreatePhysical(oemNetId, INetd::PERMISSION_NONE);
180 #pragma clang diagnostic pop
181 }
182 if (!ret.isOk()) {
183 fprintf(stderr, "Creating physical network %d failed, %s\n", oemNetId, ret.getMessage());
184 return -1;
185 }
186 ret = mDnsResolvSrv->createNetworkCache(oemNetId);
187 if (!ret.isOk()) {
188 fprintf(stderr, "Creating network cache %d failed, %s\n", oemNetId, ret.getMessage());
189 return -1;
190 }
191 setNetworkForProcess(oemNetId);
192 if ((unsigned)oemNetId != getNetworkForProcess()) {
193 return -1;
194 }
195 return 0;
196 }
197
TearDownOemNetwork(int oemNetId)198 int DnsResponderClient::TearDownOemNetwork(int oemNetId) {
199 if (auto status = mNetdSrv->networkDestroy(oemNetId); !status.isOk()) {
200 fprintf(stderr, "Removing network %d failed, %s\n", oemNetId, status.getMessage());
201 return -1;
202 }
203 if (auto status = mDnsResolvSrv->destroyNetworkCache(oemNetId); !status.isOk()) {
204 fprintf(stderr, "Removing network cache %d failed, %s\n", oemNetId, status.getMessage());
205 return -1;
206 }
207 return 0;
208 }
209
SetUp()210 void DnsResponderClient::SetUp() {
211 // binder setup
212 ndk::SpAIBinder netdBinder = ndk::SpAIBinder(AServiceManager_getService("netd"));
213 mNetdSrv = INetd::fromBinder(netdBinder);
214 if (mNetdSrv.get() == nullptr) {
215 LOG(FATAL) << "Can't connect to service 'netd'. Missing root privileges? uid=" << getuid();
216 }
217
218 ndk::SpAIBinder resolvBinder = ndk::SpAIBinder(AServiceManager_getService("dnsresolver"));
219 mDnsResolvSrv = IDnsResolver::fromBinder(resolvBinder);
220 if (mDnsResolvSrv.get() == nullptr) {
221 LOG(FATAL) << "Can't connect to service 'dnsresolver'. Missing root privileges? uid="
222 << getuid();
223 }
224
225 // Ensure resolutions go via proxy.
226 setenv(ANDROID_DNS_MODE, "", 1);
227 SetupOemNetwork(TEST_NETID);
228 }
229
TearDown()230 void DnsResponderClient::TearDown() {
231 TearDownOemNetwork(TEST_NETID);
232 }
233
makeNativeNetworkConfig(int netId,NativeNetworkType networkType,int permission,bool secure)234 NativeNetworkConfig DnsResponderClient::makeNativeNetworkConfig(int netId,
235 NativeNetworkType networkType,
236 int permission, bool secure) {
237 NativeNetworkConfig config = {};
238 config.netId = netId;
239 config.networkType = networkType;
240 config.permission = permission;
241 config.secure = secure;
242 // The vpnType doesn't matter in AOSP. Just pick a well defined one from INetd.
243 config.vpnType = NativeVpnType::PLATFORM;
244 return config;
245 }
246