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 "ResolverController"
18 
19 #include "ResolverController.h"
20 
21 #include <set>
22 #include <string>
23 #include <vector>
24 
25 #include <netdb.h>
26 
27 #include <aidl/android/net/IDnsResolver.h>
28 #include <android-base/logging.h>
29 #include <android-base/strings.h>
30 
31 #include "Dns64Configuration.h"
32 #include "DnsResolver.h"
33 #include "PrivateDnsConfiguration.h"
34 #include "ResolverEventReporter.h"
35 #include "ResolverStats.h"
36 #include "resolv_cache.h"
37 #include "stats.h"
38 
39 using aidl::android::net::ResolverParamsParcel;
40 
41 namespace android {
42 
43 using netdutils::DumpWriter;
44 
45 namespace net {
46 
47 namespace {
48 
addrToString(const sockaddr_storage * addr)49 std::string addrToString(const sockaddr_storage* addr) {
50     char out[INET6_ADDRSTRLEN] = {0};
51     getnameinfo((const sockaddr*)addr, sizeof(sockaddr_storage), out, INET6_ADDRSTRLEN, nullptr, 0,
52                 NI_NUMERICHOST);
53     return std::string(out);
54 }
55 
getPrivateDnsModeString(PrivateDnsMode mode)56 const char* getPrivateDnsModeString(PrivateDnsMode mode) {
57     switch (mode) {
58         case PrivateDnsMode::OFF:
59             return "OFF";
60         case PrivateDnsMode::OPPORTUNISTIC:
61             return "OPPORTUNISTIC";
62         case PrivateDnsMode::STRICT:
63             return "STRICT";
64     }
65 }
66 
validationStatusToString(Validation value)67 constexpr const char* validationStatusToString(Validation value) {
68     switch (value) {
69         case Validation::in_process:
70             return "in_process";
71         case Validation::success:
72             return "success";
73         case Validation::fail:
74             return "fail";
75         case Validation::unknown_server:
76             return "unknown_server";
77         case Validation::unknown_netid:
78             return "unknown_netid";
79         default:
80             return "unknown_status";
81     }
82 }
83 
sendNat64PrefixEvent(const Dns64Configuration::Nat64PrefixInfo & args)84 void sendNat64PrefixEvent(const Dns64Configuration::Nat64PrefixInfo& args) {
85     const auto& listeners = ResolverEventReporter::getInstance().getListeners();
86     if (listeners.size() == 0) {
87         LOG(ERROR) << __func__ << ": No available listener. dropping NAT64 prefix event";
88         return;
89     }
90     for (const auto& it : listeners) {
91         it->onNat64PrefixEvent(args.netId, args.added, args.prefixString, args.prefixLength);
92     }
93 }
94 
getDnsInfo(unsigned netId,std::vector<std::string> * servers,std::vector<std::string> * domains,res_params * params,std::vector<android::net::ResolverStats> * stats,std::vector<int32_t> * wait_for_pending_req_timeout_count)95 int getDnsInfo(unsigned netId, std::vector<std::string>* servers, std::vector<std::string>* domains,
96                res_params* params, std::vector<android::net::ResolverStats>* stats,
97                std::vector<int32_t>* wait_for_pending_req_timeout_count) {
98     using aidl::android::net::IDnsResolver;
99     using android::net::ResolverStats;
100     static_assert(ResolverStats::STATS_SUCCESSES == IDnsResolver::RESOLVER_STATS_SUCCESSES &&
101                           ResolverStats::STATS_ERRORS == IDnsResolver::RESOLVER_STATS_ERRORS &&
102                           ResolverStats::STATS_TIMEOUTS == IDnsResolver::RESOLVER_STATS_TIMEOUTS &&
103                           ResolverStats::STATS_INTERNAL_ERRORS ==
104                                   IDnsResolver::RESOLVER_STATS_INTERNAL_ERRORS &&
105                           ResolverStats::STATS_RTT_AVG == IDnsResolver::RESOLVER_STATS_RTT_AVG &&
106                           ResolverStats::STATS_LAST_SAMPLE_TIME ==
107                                   IDnsResolver::RESOLVER_STATS_LAST_SAMPLE_TIME &&
108                           ResolverStats::STATS_USABLE == IDnsResolver::RESOLVER_STATS_USABLE &&
109                           ResolverStats::STATS_COUNT == IDnsResolver::RESOLVER_STATS_COUNT,
110                   "AIDL and ResolverStats.h out of sync");
111     int nscount = -1;
112     sockaddr_storage res_servers[MAXNS];
113     int dcount = -1;
114     char res_domains[MAXDNSRCH][MAXDNSRCHPATH];
115     res_stats res_stats[MAXNS];
116     servers->clear();
117     domains->clear();
118     *params = res_params{};
119     stats->clear();
120     int res_wait_for_pending_req_timeout_count;
121     int revision_id = android_net_res_stats_get_info_for_net(
122             netId, &nscount, res_servers, &dcount, res_domains, params, res_stats,
123             &res_wait_for_pending_req_timeout_count);
124 
125     // If the netId is unknown (which can happen for valid net IDs for which no DNS servers have
126     // yet been configured), there is no revision ID. In this case there is no data to return.
127     if (revision_id < 0) {
128         return 0;
129     }
130 
131     // Verify that the returned data is sane.
132     if (nscount < 0 || nscount > MAXNS || dcount < 0 || dcount > MAXDNSRCH) {
133         LOG(ERROR) << __func__ << ": nscount = " << nscount << ", dcount = " << dcount;
134         return -ENOTRECOVERABLE;
135     }
136 
137     // Determine which servers are considered usable by the resolver.
138     bool valid_servers[MAXNS];
139     std::fill_n(valid_servers, MAXNS, false);
140     android_net_res_stats_get_usable_servers(params, res_stats, nscount, valid_servers);
141 
142     // Convert the server sockaddr structures to std::string.
143     stats->resize(nscount);
144     for (int i = 0; i < nscount; ++i) {
145         char hbuf[NI_MAXHOST];
146         int rv =
147                 getnameinfo(reinterpret_cast<const sockaddr*>(&res_servers[i]),
148                             sizeof(res_servers[i]), hbuf, sizeof(hbuf), nullptr, 0, NI_NUMERICHOST);
149         std::string server_str;
150         if (rv == 0) {
151             server_str.assign(hbuf);
152         } else {
153             LOG(ERROR) << "getnameinfo() failed for server #" << i << ": " << gai_strerror(rv);
154             server_str.assign("<invalid>");
155         }
156         servers->push_back(std::move(server_str));
157         android::net::ResolverStats& cur_stats = (*stats)[i];
158         android_net_res_stats_aggregate(&res_stats[i], &cur_stats.successes, &cur_stats.errors,
159                                         &cur_stats.timeouts, &cur_stats.internal_errors,
160                                         &cur_stats.rtt_avg, &cur_stats.last_sample_time);
161         cur_stats.usable = valid_servers[i];
162     }
163 
164     // Convert the stack-allocated search domain strings to std::string.
165     for (int i = 0; i < dcount; ++i) {
166         domains->push_back(res_domains[i]);
167     }
168 
169     (*wait_for_pending_req_timeout_count)[0] = res_wait_for_pending_req_timeout_count;
170     return 0;
171 }
172 
173 }  // namespace
174 
ResolverController()175 ResolverController::ResolverController()
176     : mDns64Configuration(
177               [](uint32_t netId, uint32_t uid, android_net_context* netcontext) {
178                   gResNetdCallbacks.get_network_context(netId, uid, netcontext);
179               },
180               std::bind(sendNat64PrefixEvent, std::placeholders::_1)) {}
181 
destroyNetworkCache(unsigned netId)182 void ResolverController::destroyNetworkCache(unsigned netId) {
183     LOG(VERBOSE) << __func__ << ": netId = " << netId;
184 
185     resolv_delete_cache_for_net(netId);
186     mDns64Configuration.stopPrefixDiscovery(netId);
187     gPrivateDnsConfiguration.clear(netId);
188 }
189 
createNetworkCache(unsigned netId)190 int ResolverController::createNetworkCache(unsigned netId) {
191     LOG(VERBOSE) << __func__ << ": netId = " << netId;
192 
193     return resolv_create_cache_for_net(netId);
194 }
195 
flushNetworkCache(unsigned netId)196 int ResolverController::flushNetworkCache(unsigned netId) {
197     LOG(VERBOSE) << __func__ << ": netId = " << netId;
198     return resolv_flush_cache_for_net(netId);
199 }
200 
setResolverConfiguration(const ResolverParamsParcel & resolverParams)201 int ResolverController::setResolverConfiguration(const ResolverParamsParcel& resolverParams) {
202     using aidl::android::net::IDnsResolver;
203 
204     // Expect to get the mark with system permission.
205     android_net_context netcontext;
206     gResNetdCallbacks.get_network_context(resolverParams.netId, 0 /* uid */, &netcontext);
207 
208     // Allow at most MAXNS private DNS servers in a network to prevent too many broken servers.
209     std::vector<std::string> tlsServers = resolverParams.tlsServers;
210     if (tlsServers.size() > MAXNS) {
211         tlsServers.resize(MAXNS);
212     }
213 
214     // Use app_mark for DoT connection. Using dns_mark might result in reaching the DoT servers
215     // through a different network. For example, on a VPN with no DNS servers (Do53), if the VPN
216     // applies to UID 0, dns_mark is assigned for default network rathan the VPN. (note that it's
217     // possible that a VPN doesn't have any DNS servers but DoT servers in DNS strict mode)
218     const int err =
219             gPrivateDnsConfiguration.set(resolverParams.netId, netcontext.app_mark, tlsServers,
220                                          resolverParams.tlsName, resolverParams.caCertificate);
221 
222     if (err != 0) {
223         return err;
224     }
225 
226     res_params res_params = {};
227     res_params.sample_validity = resolverParams.sampleValiditySeconds;
228     res_params.success_threshold = resolverParams.successThreshold;
229     res_params.min_samples = resolverParams.minSamples;
230     res_params.max_samples = resolverParams.maxSamples;
231     res_params.base_timeout_msec = resolverParams.baseTimeoutMsec;
232     res_params.retry_count = resolverParams.retryCount;
233 
234     return resolv_set_nameservers(resolverParams.netId, resolverParams.servers,
235                                   resolverParams.domains, res_params,
236                                   resolverParams.resolverOptions, resolverParams.transportTypes);
237 }
238 
getResolverInfo(int32_t netId,std::vector<std::string> * servers,std::vector<std::string> * domains,std::vector<std::string> * tlsServers,std::vector<int32_t> * params,std::vector<int32_t> * stats,std::vector<int32_t> * wait_for_pending_req_timeout_count)239 int ResolverController::getResolverInfo(int32_t netId, std::vector<std::string>* servers,
240                                         std::vector<std::string>* domains,
241                                         std::vector<std::string>* tlsServers,
242                                         std::vector<int32_t>* params, std::vector<int32_t>* stats,
243                                         std::vector<int32_t>* wait_for_pending_req_timeout_count) {
244     using aidl::android::net::IDnsResolver;
245     using android::net::ResolverStats;
246     res_params res_params;
247     std::vector<ResolverStats> res_stats;
248     int ret = getDnsInfo(netId, servers, domains, &res_params, &res_stats,
249                          wait_for_pending_req_timeout_count);
250     if (ret != 0) {
251         return ret;
252     }
253 
254     // Serialize the information for binder.
255     ResolverStats::encodeAll(res_stats, stats);
256 
257     const auto privateDnsStatus = gPrivateDnsConfiguration.getStatus(netId);
258     for (const auto& pair : privateDnsStatus.serversMap) {
259         tlsServers->push_back(addrToString(&pair.first.ss));
260     }
261 
262     params->resize(IDnsResolver::RESOLVER_PARAMS_COUNT);
263     (*params)[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY] = res_params.sample_validity;
264     (*params)[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD] = res_params.success_threshold;
265     (*params)[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES] = res_params.min_samples;
266     (*params)[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES] = res_params.max_samples;
267     (*params)[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC] = res_params.base_timeout_msec;
268     (*params)[IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT] = res_params.retry_count;
269     return 0;
270 }
271 
startPrefix64Discovery(int32_t netId)272 void ResolverController::startPrefix64Discovery(int32_t netId) {
273     mDns64Configuration.startPrefixDiscovery(netId);
274 }
275 
stopPrefix64Discovery(int32_t netId)276 void ResolverController::stopPrefix64Discovery(int32_t netId) {
277     return mDns64Configuration.stopPrefixDiscovery(netId);
278 }
279 
280 // TODO: use StatusOr<T> to wrap the result.
getPrefix64(unsigned netId,netdutils::IPPrefix * prefix)281 int ResolverController::getPrefix64(unsigned netId, netdutils::IPPrefix* prefix) {
282     netdutils::IPPrefix p = mDns64Configuration.getPrefix64(netId);
283     if (p.family() != AF_INET6 || p.length() == 0) {
284         LOG(INFO) << "No valid NAT64 prefix (" << netId << ", " << p.toString().c_str() << ")";
285 
286         return -ENOENT;
287     }
288     *prefix = p;
289     return 0;
290 }
291 
dump(DumpWriter & dw,unsigned netId)292 void ResolverController::dump(DumpWriter& dw, unsigned netId) {
293     // No lock needed since Bionic's resolver locks all accessed data structures internally.
294     using android::net::ResolverStats;
295     std::vector<std::string> servers;
296     std::vector<std::string> domains;
297     res_params params = {};
298     std::vector<ResolverStats> stats;
299     std::vector<int32_t> wait_for_pending_req_timeout_count(1, 0);
300     time_t now = time(nullptr);
301     int rv = getDnsInfo(netId, &servers, &domains, &params, &stats,
302                         &wait_for_pending_req_timeout_count);
303     dw.incIndent();
304     if (rv != 0) {
305         dw.println("getDnsInfo() failed for netid %u", netId);
306     } else {
307         if (servers.empty()) {
308             dw.println("No DNS servers defined");
309         } else {
310             dw.println("DnsEvent subsampling map: " +
311                        android::base::Join(resolv_cache_dump_subsampling_map(netId), ' '));
312             dw.println(
313                     "DNS servers: # IP (total, successes, errors, timeouts, internal errors, "
314                     "RTT avg, last sample)");
315             dw.incIndent();
316             for (size_t i = 0; i < servers.size(); ++i) {
317                 if (i < stats.size()) {
318                     const ResolverStats& s = stats[i];
319                     int total = s.successes + s.errors + s.timeouts + s.internal_errors;
320                     if (total > 0) {
321                         int time_delta = (s.last_sample_time > 0) ? now - s.last_sample_time : -1;
322                         dw.println("%s (%d, %d, %d, %d, %d, %dms, %ds)%s", servers[i].c_str(),
323                                    total, s.successes, s.errors, s.timeouts, s.internal_errors,
324                                    s.rtt_avg, time_delta, s.usable ? "" : " BROKEN");
325                     } else {
326                         dw.println("%s <no data>", servers[i].c_str());
327                     }
328                 } else {
329                     dw.println("%s <no stats>", servers[i].c_str());
330                 }
331             }
332             dw.decIndent();
333         }
334         if (domains.empty()) {
335             dw.println("No search domains defined");
336         } else {
337             std::string domains_str = android::base::Join(domains, ", ");
338             dw.println("search domains: %s", domains_str.c_str());
339         }
340         if (params.sample_validity != 0) {
341             dw.println(
342                     "DNS parameters: sample validity = %us, success threshold = %u%%, "
343                     "samples (min, max) = (%u, %u), base_timeout = %dmsec, retry count = "
344                     "%dtimes",
345                     params.sample_validity, params.success_threshold, params.min_samples,
346                     params.max_samples, params.base_timeout_msec, params.retry_count);
347         }
348 
349         mDns64Configuration.dump(dw, netId);
350         const auto privateDnsStatus = gPrivateDnsConfiguration.getStatus(netId);
351         dw.println("Private DNS mode: %s", getPrivateDnsModeString(privateDnsStatus.mode));
352         if (privateDnsStatus.serversMap.size() == 0) {
353             dw.println("No Private DNS servers configured");
354         } else {
355             dw.println("Private DNS configuration (%u entries)",
356                        static_cast<uint32_t>(privateDnsStatus.serversMap.size()));
357             dw.incIndent();
358             for (const auto& pair : privateDnsStatus.serversMap) {
359                 dw.println("%s name{%s} status{%s}", addrToString(&pair.first.ss).c_str(),
360                            pair.first.name.c_str(), validationStatusToString(pair.second));
361             }
362             dw.decIndent();
363         }
364         dw.println("Concurrent DNS query timeout: %d", wait_for_pending_req_timeout_count[0]);
365         resolv_netconfig_dump(dw, netId);
366     }
367     dw.decIndent();
368 }
369 
370 }  // namespace net
371 }  // namespace android
372