blob: f684ff2628cc8dfb8e362342a286a0e749e66b42 [file] [log] [blame]
Mike Yu19108d52018-11-15 21:58:19 +08001/*
2 * Copyright (C) 2010 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
Luke Huang36796f32019-03-13 02:54:45 +080017#include "DnsProxyListener.h"
18
Mike Yu19108d52018-11-15 21:58:19 +080019#include <arpa/inet.h>
20#include <dirent.h>
21#include <errno.h>
22#include <linux/if.h>
23#include <math.h>
24#include <net/if.h>
25#include <netdb.h>
26#include <netinet/in.h>
27#include <stdlib.h>
28#include <string.h>
29#include <sys/socket.h>
30#include <sys/types.h>
31
Ken Chen5471dca2019-04-15 15:25:35 +080032#define LOG_TAG "resolv"
Mike Yu19108d52018-11-15 21:58:19 +080033
34#include <algorithm>
Mike Yu19108d52018-11-15 21:58:19 +080035#include <vector>
36
Luke Huangf4c98f22019-06-14 01:57:00 +080037#include <NetdClient.h> // NETID_USE_LOCAL_NAMESERVERS
Mike Yu19108d52018-11-15 21:58:19 +080038#include <android-base/stringprintf.h>
Bernie Innocenti758005f2019-02-19 18:08:36 +090039#include <android/multinetwork.h> // ResNsendFlags
40#include <cutils/misc.h> // FIRST_APPLICATION_UID
Mike Yudaa29932019-03-13 14:43:39 +080041#include <netdutils/InternetAddresses.h>
Mike Yu19108d52018-11-15 21:58:19 +080042#include <netdutils/OperationLimiter.h>
Mike Yudaa29932019-03-13 14:43:39 +080043#include <netdutils/ResponseCode.h>
Mike Yu19108d52018-11-15 21:58:19 +080044#include <netdutils/Slice.h>
Mike Yu40ea2ad2019-03-13 17:15:48 +080045#include <netdutils/Stopwatch.h>
Mike Yu133f7ab2019-03-14 15:14:44 +080046#include <netdutils/ThreadUtil.h>
Mike Yu19108d52018-11-15 21:58:19 +080047#include <private/android_filesystem_config.h> // AID_SYSTEM
lifr9b87e362019-05-08 13:00:14 +080048#include <statslog_resolv.h>
Mike Yu19108d52018-11-15 21:58:19 +080049#include <sysutils/SocketClient.h>
50
Luke Huang36796f32019-03-13 02:54:45 +080051#include "DnsResolver.h"
Remi NGUYEN VAN10e0b712019-02-07 12:25:23 +090052#include "NetdPermissions.h"
Bernie Innocenti23c6e2a2019-05-16 15:18:35 +090053#include "PrivateDnsConfiguration.h"
Bernie Innocentiec4219b2019-01-30 11:16:36 +090054#include "ResolverEventReporter.h"
Bernie Innocentie71a28a2019-05-29 00:42:35 +090055#include "getaddrinfo.h"
56#include "gethnamaddr.h"
Mike Yu19108d52018-11-15 21:58:19 +080057#include "netd_resolv/stats.h" // RCODE_TIMEOUT
Bernie Innocentie71a28a2019-05-29 00:42:35 +090058#include "res_send.h"
Luke Huange126fbe2019-07-20 17:36:30 +080059#include "resolv_cache.h"
chenbruceacb832c2019-02-20 19:45:50 +080060#include "resolv_private.h"
lifr9b87e362019-05-08 13:00:14 +080061#include "stats.pb.h"
Mike Yu19108d52018-11-15 21:58:19 +080062
63using aidl::android::net::metrics::INetdEventListener;
lifr9b87e362019-05-08 13:00:14 +080064using android::net::NetworkDnsEventReported;
Mike Yu19108d52018-11-15 21:58:19 +080065
Mike Yu19108d52018-11-15 21:58:19 +080066namespace android {
Mike Yu19108d52018-11-15 21:58:19 +080067
Mike Yudaa29932019-03-13 14:43:39 +080068using netdutils::ResponseCode;
Mike Yu40ea2ad2019-03-13 17:15:48 +080069using netdutils::Stopwatch;
Mike Yudaa29932019-03-13 14:43:39 +080070
71namespace net {
Mike Yu19108d52018-11-15 21:58:19 +080072namespace {
73
Mike Yu19108d52018-11-15 21:58:19 +080074// Limits the number of outstanding DNS queries by client UID.
75constexpr int MAX_QUERIES_PER_UID = 256;
76
77// Max packet size for answer, sync with getaddrinfo.c
78constexpr int MAXPACKET = 8 * 1024;
79
80android::netdutils::OperationLimiter<uid_t> queryLimiter(MAX_QUERIES_PER_UID);
81
82void logArguments(int argc, char** argv) {
Ken Chenffc224a2019-03-19 17:41:28 +080083 if (!WOULD_LOG(VERBOSE)) return;
Mike Yu19108d52018-11-15 21:58:19 +080084 for (int i = 0; i < argc; i++) {
Ken Chenffc224a2019-03-19 17:41:28 +080085 LOG(VERBOSE) << __func__ << ": argv[" << i << "]=" << (argv[i] ? argv[i] : "null");
Mike Yu19108d52018-11-15 21:58:19 +080086 }
87}
88
89template<typename T>
90void tryThreadOrError(SocketClient* cli, T* handler) {
91 cli->incRef();
92
Mike Yu133f7ab2019-03-14 15:14:44 +080093 const int rval = netdutils::threadLaunch(handler);
Mike Yu19108d52018-11-15 21:58:19 +080094 if (rval == 0) {
95 // SocketClient decRef() happens in the handler's run() method.
96 return;
97 }
98
99 char* msg = nullptr;
100 asprintf(&msg, "%s (%d)", strerror(-rval), -rval);
101 cli->sendMsg(ResponseCode::OperationFailed, msg, false);
102 free(msg);
103
104 delete handler;
105 cli->decRef();
106}
107
108bool checkAndClearUseLocalNameserversFlag(unsigned* netid) {
109 if (netid == nullptr || ((*netid) & NETID_USE_LOCAL_NAMESERVERS) == 0) {
110 return false;
111 }
112 *netid = (*netid) & ~NETID_USE_LOCAL_NAMESERVERS;
113 return true;
114}
115
116constexpr bool requestingUseLocalNameservers(unsigned flags) {
117 return (flags & NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS) != 0;
118}
119
120inline bool queryingViaTls(unsigned dns_netid) {
Bernie Innocenti23c6e2a2019-05-16 15:18:35 +0900121 // TODO: The simpler PrivateDnsStatus should suffice here.
Mike Yu19108d52018-11-15 21:58:19 +0800122 ExternalPrivateDnsStatus privateDnsStatus = {PrivateDnsMode::OFF, 0, {}};
Bernie Innocenti23c6e2a2019-05-16 15:18:35 +0900123 gPrivateDnsConfiguration.getStatus(dns_netid, &privateDnsStatus);
Mike Yu19108d52018-11-15 21:58:19 +0800124 switch (static_cast<PrivateDnsMode>(privateDnsStatus.mode)) {
125 case PrivateDnsMode::OPPORTUNISTIC:
126 for (int i = 0; i < privateDnsStatus.numServers; i++) {
127 if (privateDnsStatus.serverStatus[i].validation == Validation::success) {
128 return true;
129 }
130 }
131 return false;
132 case PrivateDnsMode::STRICT:
133 return true;
134 default:
135 return false;
136 }
137}
138
139bool hasPermissionToBypassPrivateDns(uid_t uid) {
140 static_assert(AID_SYSTEM >= 0 && AID_SYSTEM < FIRST_APPLICATION_UID,
141 "Calls from AID_SYSTEM must not result in a permission check to avoid deadlock.");
142 if (uid >= 0 && uid < FIRST_APPLICATION_UID) {
143 return true;
144 }
145
146 for (const char* const permission :
Remi NGUYEN VAN10e0b712019-02-07 12:25:23 +0900147 {PERM_CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERM_NETWORK_BYPASS_PRIVATE_DNS,
148 PERM_MAINLINE_NETWORK_STACK}) {
Luke Huang36796f32019-03-13 02:54:45 +0800149 if (gResNetdCallbacks.check_calling_permission(permission)) {
Mike Yu19108d52018-11-15 21:58:19 +0800150 return true;
151 }
152 }
153 return false;
154}
155
156void maybeFixupNetContext(android_net_context* ctx) {
157 if (requestingUseLocalNameservers(ctx->flags) && !hasPermissionToBypassPrivateDns(ctx->uid)) {
158 // Not permitted; clear the flag.
159 ctx->flags &= ~NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
160 }
161
162 if (!requestingUseLocalNameservers(ctx->flags)) {
163 // If we're not explicitly bypassing DNS-over-TLS servers, check whether
164 // DNS-over-TLS is in use as an indicator for when to use more modern
165 // DNS resolution mechanics.
166 if (queryingViaTls(ctx->dns_netid)) {
chenbruced8cbb9b2019-06-20 18:25:28 +0800167 ctx->flags |= NET_CONTEXT_FLAG_USE_DNS_OVER_TLS | NET_CONTEXT_FLAG_USE_EDNS;
Mike Yu19108d52018-11-15 21:58:19 +0800168 }
169 }
170}
171
172void addIpAddrWithinLimit(std::vector<std::string>* ip_addrs, const sockaddr* addr,
173 socklen_t addrlen);
174
175int extractResNsendAnswers(const uint8_t* answer, size_t anslen, int ipType,
176 std::vector<std::string>* ip_addrs) {
177 int total_ip_addr_count = 0;
178 ns_msg handle;
179 if (ns_initparse((const uint8_t*) answer, anslen, &handle) < 0) {
180 return 0;
181 }
182 int ancount = ns_msg_count(handle, ns_s_an);
183 ns_rr rr;
184 for (int i = 0; i < ancount; i++) {
185 if (ns_parserr(&handle, ns_s_an, i, &rr) < 0) {
186 continue;
187 }
188 const uint8_t* rdata = ns_rr_rdata(rr);
189 if (ipType == ns_t_a) {
190 sockaddr_in sin = {.sin_family = AF_INET};
191 memcpy(&sin.sin_addr, rdata, sizeof(sin.sin_addr));
192 addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin, sizeof(sin));
193 total_ip_addr_count++;
194 } else if (ipType == ns_t_aaaa) {
195 sockaddr_in6 sin6 = {.sin6_family = AF_INET6};
196 memcpy(&sin6.sin6_addr, rdata, sizeof(sin6.sin6_addr));
197 addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin6, sizeof(sin6));
198 total_ip_addr_count++;
199 }
200 }
201
202 return total_ip_addr_count;
203}
204
205int extractGetAddrInfoAnswers(const addrinfo* result, std::vector<std::string>* ip_addrs) {
206 int total_ip_addr_count = 0;
207 if (result == nullptr) {
208 return 0;
209 }
210 for (const addrinfo* ai = result; ai; ai = ai->ai_next) {
211 sockaddr* ai_addr = ai->ai_addr;
212 if (ai_addr) {
213 addIpAddrWithinLimit(ip_addrs, ai_addr, ai->ai_addrlen);
214 total_ip_addr_count++;
215 }
216 }
217 return total_ip_addr_count;
218}
219
220int extractGetHostByNameAnswers(const hostent* hp, std::vector<std::string>* ip_addrs) {
221 int total_ip_addr_count = 0;
222 if (hp == nullptr) {
223 return 0;
224 }
225 if (hp->h_addrtype == AF_INET) {
226 in_addr** list = (in_addr**) hp->h_addr_list;
227 for (int i = 0; list[i] != nullptr; i++) {
228 sockaddr_in sin = {.sin_family = AF_INET, .sin_addr = *list[i]};
229 addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin, sizeof(sin));
230 total_ip_addr_count++;
231 }
232 } else if (hp->h_addrtype == AF_INET6) {
233 in6_addr** list = (in6_addr**) hp->h_addr_list;
234 for (int i = 0; list[i] != nullptr; i++) {
235 sockaddr_in6 sin6 = {.sin6_family = AF_INET6, .sin6_addr = *list[i]};
236 addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin6, sizeof(sin6));
237 total_ip_addr_count++;
238 }
239 }
240 return total_ip_addr_count;
241}
242
243int rcodeToAiError(int rcode) {
244 switch (rcode) {
245 case NOERROR:
246 return 0;
247 case RCODE_TIMEOUT:
248 return NETD_RESOLV_TIMEOUT;
249 default:
250 return EAI_NODATA;
251 }
252}
253
254int resNSendToAiError(int err, int rcode) {
255 if (err > 0) {
256 return rcodeToAiError(rcode);
257 }
258 if (err == -ETIMEDOUT) {
259 return NETD_RESOLV_TIMEOUT;
260 }
261 return EAI_SYSTEM;
262}
263
264template <typename IntegralType>
265bool simpleStrtoul(const char* input, IntegralType* output, int base = 10) {
266 char* endPtr;
267 errno = 0;
268 auto result = strtoul(input, &endPtr, base);
269 // Check the length in order to ensure there is no "-" sign
270 if (!*input || *endPtr || (endPtr - input) != static_cast<ptrdiff_t>(strlen(input)) ||
271 (errno == ERANGE && (result == ULONG_MAX))) {
272 return false;
273 }
274 *output = result;
275 return true;
276}
277
Luke Huang70931aa2019-01-31 11:57:41 +0800278bool setQueryId(uint8_t* msg, size_t msgLen, uint16_t query_id) {
279 if (msgLen < sizeof(HEADER)) {
280 errno = EINVAL;
281 return false;
282 }
283 auto hp = reinterpret_cast<HEADER*>(msg);
284 hp->id = htons(query_id);
285 return true;
286}
287
288bool parseQuery(const uint8_t* msg, size_t msgLen, uint16_t* query_id, int* rr_type,
289 std::string* rr_name) {
Mike Yu19108d52018-11-15 21:58:19 +0800290 ns_msg handle;
291 ns_rr rr;
Luke Huang70931aa2019-01-31 11:57:41 +0800292 if (ns_initparse((const uint8_t*)msg, msgLen, &handle) < 0 ||
Mike Yu19108d52018-11-15 21:58:19 +0800293 ns_parserr(&handle, ns_s_qd, 0, &rr) < 0) {
294 return false;
295 }
Luke Huang70931aa2019-01-31 11:57:41 +0800296 *query_id = ns_msg_id(handle);
Mike Yu19108d52018-11-15 21:58:19 +0800297 *rr_name = ns_rr_name(rr);
298 *rr_type = ns_rr_type(rr);
299 return true;
300}
301
lifr94981782019-05-17 21:15:19 +0800302void initDnsEvent(NetworkDnsEventReported* event) {
lifrd4d9fbb2019-07-31 20:18:35 +0800303 // The value 0 has the special meaning of unset/unknown in Westworld atoms. So, we set both
304 // flags to -1 as default value.
305 // 1. The hints flag is only used in resolv_getaddrinfo. When user set it to -1 in
306 // resolv_getaddrinfo, the flag will cause validation (validateHints) failure in
307 // getaddrinfo, so it will not do DNS query and will upload DNS stats log with
308 // return_code = RC_EAI_BADFLAGS.
309 // 2. The res_nsend flags are only used in resolv_res_nsend. When user set it to -1 in
310 // resolv_res_nsend,res_nsend will do nothing special by the setting.
lifr94981782019-05-17 21:15:19 +0800311 event->set_hints_ai_flags(-1);
312 event->set_res_nsend_flags(-1);
313}
314
Luke Huange126fbe2019-07-20 17:36:30 +0800315// Return 0 if the event should not be logged.
316// Otherwise, return subsampling_denom
317uint32_t getDnsEventSubsamplingRate(int netid, int returnCode) {
318 uint32_t subsampling_denom = resolv_cache_get_subsampling_denom(netid, returnCode);
319 if (subsampling_denom == 0) return 0;
320 // Sample the event with a chance of 1 / denom.
321 return (arc4random_uniform(subsampling_denom) == 0) ? subsampling_denom : 0;
322}
323
Mike Yu19108d52018-11-15 21:58:19 +0800324void reportDnsEvent(int eventType, const android_net_context& netContext, int latencyUs,
lifr94981782019-05-17 21:15:19 +0800325 int returnCode, NetworkDnsEventReported& event, const std::string& query_name,
326 const std::vector<std::string>& ip_addrs = {}, int total_ip_addr_count = 0) {
Luke Huange126fbe2019-07-20 17:36:30 +0800327 if (uint32_t rate = getDnsEventSubsamplingRate(netContext.dns_netid, returnCode)) {
328 const std::string& dnsQueryStats = event.dns_query_events().SerializeAsString();
329 stats::BytesField dnsQueryBytesField{dnsQueryStats.c_str(), dnsQueryStats.size()};
330 event.set_return_code(static_cast<ReturnCode>(returnCode));
331 android::net::stats::stats_write(android::net::stats::NETWORK_DNS_EVENT_REPORTED,
332 event.event_type(), event.return_code(),
333 event.latency_micros(), event.hints_ai_flags(),
334 event.res_nsend_flags(), event.network_type(),
335 event.private_dns_modes(), dnsQueryBytesField, rate);
336 }
Mike Yu19108d52018-11-15 21:58:19 +0800337
Hungming Chena32c8c12019-01-25 10:47:40 +0800338 const auto& listeners = ResolverEventReporter::getInstance().getListeners();
339 if (listeners.size() == 0) {
Ken Chenffc224a2019-03-19 17:41:28 +0800340 LOG(ERROR) << __func__
Hungming Chena32c8c12019-01-25 10:47:40 +0800341 << ": DNS event not sent since no INetdEventListener receiver is available.";
Mike Yu6d2c8922019-02-15 16:03:02 +0800342 return;
343 }
Mike Yu19108d52018-11-15 21:58:19 +0800344 const int latencyMs = latencyUs / 1000;
Hungming Chena32c8c12019-01-25 10:47:40 +0800345 for (const auto& it : listeners) {
346 it->onDnsEvent(netContext.dns_netid, eventType, returnCode, latencyMs, query_name, ip_addrs,
347 total_ip_addr_count, netContext.uid);
348 }
Mike Yu19108d52018-11-15 21:58:19 +0800349}
350
351bool onlyIPv4Answers(const addrinfo* res) {
352 // Null addrinfo pointer isn't checked because the caller doesn't pass null pointer.
353
354 for (const addrinfo* ai = res; ai; ai = ai->ai_next)
355 if (ai->ai_family != AF_INET) return false;
356
357 return true;
358}
359
360bool isSpecialUseIPv4Address(const struct in_addr& ia) {
361 const uint32_t addr = ntohl(ia.s_addr);
362
363 // Only check necessary IP ranges in RFC 5735 section 4
364 return ((addr & 0xff000000) == 0x00000000) || // "This" Network
365 ((addr & 0xff000000) == 0x7f000000) || // Loopback
366 ((addr & 0xffff0000) == 0xa9fe0000) || // Link Local
367 ((addr & 0xf0000000) == 0xe0000000) || // Multicast
368 (addr == INADDR_BROADCAST); // Limited Broadcast
369}
370
371bool isSpecialUseIPv4Address(const struct sockaddr* sa) {
372 if (sa->sa_family != AF_INET) return false;
373
374 return isSpecialUseIPv4Address(((struct sockaddr_in*) sa)->sin_addr);
375}
376
377bool onlyNonSpecialUseIPv4Addresses(struct hostent* hp) {
378 // Null hostent pointer isn't checked because the caller doesn't pass null pointer.
379
380 if (hp->h_addrtype != AF_INET) return false;
381
382 for (int i = 0; hp->h_addr_list[i] != nullptr; i++)
383 if (isSpecialUseIPv4Address(*(struct in_addr*) hp->h_addr_list[i])) return false;
384
385 return true;
386}
387
388bool onlyNonSpecialUseIPv4Addresses(const addrinfo* res) {
389 // Null addrinfo pointer isn't checked because the caller doesn't pass null pointer.
390
391 for (const addrinfo* ai = res; ai; ai = ai->ai_next) {
392 if (ai->ai_family != AF_INET) return false;
393 if (isSpecialUseIPv4Address(ai->ai_addr)) return false;
394 }
395
396 return true;
397}
398
399void logDnsQueryResult(const struct hostent* hp) {
Bernie Innocenti3952ccc2019-03-03 19:39:53 +0900400 if (!WOULD_LOG(DEBUG)) return;
Mike Yu19108d52018-11-15 21:58:19 +0800401 if (hp == nullptr) return;
402
Ken Chenffc224a2019-03-19 17:41:28 +0800403 LOG(DEBUG) << __func__ << ": DNS records:";
Mike Yu19108d52018-11-15 21:58:19 +0800404 for (int i = 0; hp->h_addr_list[i] != nullptr; i++) {
405 char ip_addr[INET6_ADDRSTRLEN];
406 if (inet_ntop(hp->h_addrtype, hp->h_addr_list[i], ip_addr, sizeof(ip_addr)) != nullptr) {
Ken Chenffc224a2019-03-19 17:41:28 +0800407 LOG(DEBUG) << __func__ << ": [" << i << "] " << hp->h_addrtype;
Mike Yu19108d52018-11-15 21:58:19 +0800408 } else {
Ken Chenffc224a2019-03-19 17:41:28 +0800409 PLOG(DEBUG) << __func__ << ": [" << i << "] numeric hostname translation fail";
Mike Yu19108d52018-11-15 21:58:19 +0800410 }
411 }
412}
413
414void logDnsQueryResult(const addrinfo* res) {
Bernie Innocenti3952ccc2019-03-03 19:39:53 +0900415 if (!WOULD_LOG(DEBUG)) return;
Mike Yu19108d52018-11-15 21:58:19 +0800416 if (res == nullptr) return;
417
418 int i;
419 const addrinfo* ai;
Ken Chenffc224a2019-03-19 17:41:28 +0800420 LOG(DEBUG) << __func__ << ": DNS records:";
Mike Yu19108d52018-11-15 21:58:19 +0800421 for (ai = res, i = 0; ai; ai = ai->ai_next, i++) {
422 if ((ai->ai_family != AF_INET) && (ai->ai_family != AF_INET6)) continue;
423 char ip_addr[INET6_ADDRSTRLEN];
424 int ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, ip_addr, sizeof(ip_addr), nullptr, 0,
425 NI_NUMERICHOST);
426 if (!ret) {
Ken Chenffc224a2019-03-19 17:41:28 +0800427 LOG(DEBUG) << __func__ << ": [" << i << "] " << ai->ai_flags << " " << ai->ai_family
428 << " " << ai->ai_socktype << " " << ai->ai_protocol;
Mike Yu19108d52018-11-15 21:58:19 +0800429 } else {
Ken Chenffc224a2019-03-19 17:41:28 +0800430 LOG(DEBUG) << __func__ << ": [" << i << "] numeric hostname translation fail " << ret;
Mike Yu19108d52018-11-15 21:58:19 +0800431 }
432 }
433}
434
435bool isValidNat64Prefix(const netdutils::IPPrefix prefix) {
436 if (prefix.family() != AF_INET6) {
Ken Chenffc224a2019-03-19 17:41:28 +0800437 LOG(ERROR) << __func__ << ": Only IPv6 NAT64 prefixes are supported " << prefix.family();
Mike Yu19108d52018-11-15 21:58:19 +0800438 return false;
439 }
440 if (prefix.length() != 96) {
Ken Chenffc224a2019-03-19 17:41:28 +0800441 LOG(ERROR) << __func__ << ": Only /96 NAT64 prefixes are supported " << prefix.length();
Mike Yu19108d52018-11-15 21:58:19 +0800442 return false;
443 }
444 return true;
445}
446
447bool synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix& prefix, struct hostent* hp) {
448 if (hp == nullptr) return false;
449 if (!onlyNonSpecialUseIPv4Addresses(hp)) return false;
450 if (!isValidNat64Prefix(prefix)) return false;
451
452 struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
453 struct sockaddr_in6* v6prefix = (struct sockaddr_in6*) &ss;
454 for (int i = 0; hp->h_addr_list[i] != nullptr; i++) {
455 struct in_addr iaOriginal = *(struct in_addr*) hp->h_addr_list[i];
456 struct in6_addr* ia6 = (struct in6_addr*) hp->h_addr_list[i];
457 memset(ia6, 0, sizeof(struct in6_addr));
458
459 // Synthesize /96 NAT64 prefix in place. The space has reserved by getanswer() and
460 // _hf_gethtbyname2() in system/netd/resolv/gethnamaddr.cpp and
461 // system/netd/resolv/sethostent.cpp.
462 *ia6 = v6prefix->sin6_addr;
463 ia6->s6_addr32[3] = iaOriginal.s_addr;
464
Ken Chen594fc942019-04-18 18:11:15 +0800465 if (WOULD_LOG(VERBOSE)) {
Mike Yu19108d52018-11-15 21:58:19 +0800466 char buf[INET6_ADDRSTRLEN]; // big enough for either IPv4 or IPv6
467 inet_ntop(AF_INET, &iaOriginal.s_addr, buf, sizeof(buf));
Ken Chen594fc942019-04-18 18:11:15 +0800468 LOG(VERBOSE) << __func__ << ": DNS A record: " << buf;
Mike Yu19108d52018-11-15 21:58:19 +0800469 inet_ntop(AF_INET6, &v6prefix->sin6_addr, buf, sizeof(buf));
Ken Chen594fc942019-04-18 18:11:15 +0800470 LOG(VERBOSE) << __func__ << ": NAT64 prefix: " << buf;
Mike Yu19108d52018-11-15 21:58:19 +0800471 inet_ntop(AF_INET6, ia6, buf, sizeof(buf));
Ken Chen594fc942019-04-18 18:11:15 +0800472 LOG(VERBOSE) << __func__ << ": DNS64 Synthesized AAAA record: " << buf;
Mike Yu19108d52018-11-15 21:58:19 +0800473 }
474 }
475 hp->h_addrtype = AF_INET6;
476 hp->h_length = sizeof(in6_addr);
477
Bernie Innocenti3952ccc2019-03-03 19:39:53 +0900478 logDnsQueryResult(hp);
Mike Yu19108d52018-11-15 21:58:19 +0800479 return true;
480}
481
482bool synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix& prefix, addrinfo* result) {
483 if (result == nullptr) return false;
484 if (!onlyNonSpecialUseIPv4Addresses(result)) return false;
485 if (!isValidNat64Prefix(prefix)) return false;
486
487 struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
488 struct sockaddr_in6* v6prefix = (struct sockaddr_in6*) &ss;
489 for (addrinfo* ai = result; ai; ai = ai->ai_next) {
490 struct sockaddr_in sinOriginal = *(struct sockaddr_in*) ai->ai_addr;
491 struct sockaddr_in6* sin6 = (struct sockaddr_in6*) ai->ai_addr;
492 memset(sin6, 0, sizeof(sockaddr_in6));
493
494 // Synthesize /96 NAT64 prefix in place. The space has reserved by get_ai() in
495 // system/netd/resolv/getaddrinfo.cpp.
496 sin6->sin6_addr = v6prefix->sin6_addr;
497 sin6->sin6_addr.s6_addr32[3] = sinOriginal.sin_addr.s_addr;
498 sin6->sin6_family = AF_INET6;
499 sin6->sin6_port = sinOriginal.sin_port;
500 ai->ai_addrlen = sizeof(struct sockaddr_in6);
501 ai->ai_family = AF_INET6;
502
Ken Chen594fc942019-04-18 18:11:15 +0800503 if (WOULD_LOG(VERBOSE)) {
Mike Yu19108d52018-11-15 21:58:19 +0800504 char buf[INET6_ADDRSTRLEN]; // big enough for either IPv4 or IPv6
505 inet_ntop(AF_INET, &sinOriginal.sin_addr.s_addr, buf, sizeof(buf));
Ken Chen594fc942019-04-18 18:11:15 +0800506 LOG(VERBOSE) << __func__ << ": DNS A record: " << buf;
Mike Yu19108d52018-11-15 21:58:19 +0800507 inet_ntop(AF_INET6, &v6prefix->sin6_addr, buf, sizeof(buf));
Ken Chen594fc942019-04-18 18:11:15 +0800508 LOG(VERBOSE) << __func__ << ": NAT64 prefix: " << buf;
Mike Yu19108d52018-11-15 21:58:19 +0800509 inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof(buf));
Ken Chen594fc942019-04-18 18:11:15 +0800510 LOG(VERBOSE) << __func__ << ": DNS64 Synthesized AAAA record: " << buf;
Mike Yu19108d52018-11-15 21:58:19 +0800511 }
512 }
Bernie Innocenti3952ccc2019-03-03 19:39:53 +0900513 logDnsQueryResult(result);
Mike Yu19108d52018-11-15 21:58:19 +0800514 return true;
515}
516
517bool getDns64Prefix(unsigned netId, netdutils::IPPrefix* prefix) {
Luke Huang5bd827c2019-03-14 16:10:04 +0800518 return !gDnsResolv->resolverCtrl.getPrefix64(netId, prefix);
Mike Yu19108d52018-11-15 21:58:19 +0800519}
520
521} // namespace
522
Mike Yu19108d52018-11-15 21:58:19 +0800523DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) {
524 registerCmd(new GetAddrInfoCmd());
525 registerCmd(new GetHostByAddrCmd());
526 registerCmd(new GetHostByNameCmd());
527 registerCmd(new ResNSendCommand());
Luke Huang9807e6b2019-05-20 16:17:12 +0800528 registerCmd(new GetDnsNetIdCommand());
Mike Yu19108d52018-11-15 21:58:19 +0800529}
530
531DnsProxyListener::GetAddrInfoHandler::GetAddrInfoHandler(SocketClient* c, char* host, char* service,
532 addrinfo* hints,
533 const android_net_context& netcontext)
534 : mClient(c), mHost(host), mService(service), mHints(hints), mNetContext(netcontext) {}
535
536DnsProxyListener::GetAddrInfoHandler::~GetAddrInfoHandler() {
537 free(mHost);
538 free(mService);
539 free(mHints);
540}
541
542static bool sendBE32(SocketClient* c, uint32_t data) {
543 uint32_t be_data = htonl(data);
544 return c->sendData(&be_data, sizeof(be_data)) == 0;
545}
546
547// Sends 4 bytes of big-endian length, followed by the data.
548// Returns true on success.
549static bool sendLenAndData(SocketClient* c, const int len, const void* data) {
550 return sendBE32(c, len) && (len == 0 || c->sendData(data, len) == 0);
551}
552
553// Returns true on success
554static bool sendhostent(SocketClient* c, hostent* hp) {
555 bool success = true;
556 int i;
557 if (hp->h_name != nullptr) {
558 success &= sendLenAndData(c, strlen(hp->h_name)+1, hp->h_name);
559 } else {
560 success &= sendLenAndData(c, 0, "") == 0;
561 }
562
563 for (i=0; hp->h_aliases[i] != nullptr; i++) {
564 success &= sendLenAndData(c, strlen(hp->h_aliases[i])+1, hp->h_aliases[i]);
565 }
566 success &= sendLenAndData(c, 0, ""); // null to indicate we're done
567
568 uint32_t buf = htonl(hp->h_addrtype);
569 success &= c->sendData(&buf, sizeof(buf)) == 0;
570
571 buf = htonl(hp->h_length);
572 success &= c->sendData(&buf, sizeof(buf)) == 0;
573
574 for (i=0; hp->h_addr_list[i] != nullptr; i++) {
575 success &= sendLenAndData(c, 16, hp->h_addr_list[i]);
576 }
577 success &= sendLenAndData(c, 0, ""); // null to indicate we're done
578 return success;
579}
580
581static bool sendaddrinfo(SocketClient* c, addrinfo* ai) {
582 // struct addrinfo {
583 // int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
584 // int ai_family; /* PF_xxx */
585 // int ai_socktype; /* SOCK_xxx */
586 // int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
587 // socklen_t ai_addrlen; /* length of ai_addr */
588 // char *ai_canonname; /* canonical name for hostname */
589 // struct sockaddr *ai_addr; /* binary address */
590 // struct addrinfo *ai_next; /* next structure in linked list */
591 // };
592
593 // Write the struct piece by piece because we might be a 64-bit netd
594 // talking to a 32-bit process.
595 bool success =
596 sendBE32(c, ai->ai_flags) &&
597 sendBE32(c, ai->ai_family) &&
598 sendBE32(c, ai->ai_socktype) &&
599 sendBE32(c, ai->ai_protocol);
600 if (!success) {
601 return false;
602 }
603
604 // ai_addrlen and ai_addr.
605 if (!sendLenAndData(c, ai->ai_addrlen, ai->ai_addr)) {
606 return false;
607 }
608
609 // strlen(ai_canonname) and ai_canonname.
610 if (!sendLenAndData(c, ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0, ai->ai_canonname)) {
611 return false;
612 }
613
614 return true;
615}
616
lifr94981782019-05-17 21:15:19 +0800617void DnsProxyListener::GetAddrInfoHandler::doDns64Synthesis(int32_t* rv, addrinfo** res,
618 NetworkDnsEventReported* event) {
Mike Yu19108d52018-11-15 21:58:19 +0800619 if (mHost == nullptr) return;
620
621 const bool ipv6WantedButNoData = (mHints && mHints->ai_family == AF_INET6 && *rv == EAI_NODATA);
622 const bool unspecWantedButNoIPv6 =
623 ((!mHints || mHints->ai_family == AF_UNSPEC) && *rv == 0 && onlyIPv4Answers(*res));
624
625 if (!ipv6WantedButNoData && !unspecWantedButNoIPv6) {
626 return;
627 }
628
629 netdutils::IPPrefix prefix{};
630 if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
631 return;
632 }
633
634 if (ipv6WantedButNoData) {
635 // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis
636 const uid_t uid = mClient->getUid();
637 if (queryLimiter.start(uid)) {
638 mHints->ai_family = AF_INET;
639 // Don't need to do freeaddrinfo(res) before starting new DNS lookup because previous
640 // DNS lookup is failed with error EAI_NODATA.
Luke Huangd8ac4752019-06-18 17:05:47 +0800641 *rv = resolv_getaddrinfo(mHost, mService, mHints, &mNetContext, res, event);
Mike Yu19108d52018-11-15 21:58:19 +0800642 queryLimiter.finish(uid);
643 if (*rv) {
644 *rv = EAI_NODATA; // return original error code
645 return;
646 }
647 } else {
Ken Chenffc224a2019-03-19 17:41:28 +0800648 LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached";
Mike Yu19108d52018-11-15 21:58:19 +0800649 return;
650 }
651 }
652
653 if (!synthesizeNat64PrefixWithARecord(prefix, *res)) {
654 if (ipv6WantedButNoData) {
655 // If caller wants IPv6 answers but no data and failed to synthesize IPv6 answers,
656 // don't return the IPv4 answers.
657 *rv = EAI_NODATA; // return original error code
658 if (*res) {
659 freeaddrinfo(*res);
660 *res = nullptr;
661 }
662 }
663 }
664}
665
666void DnsProxyListener::GetAddrInfoHandler::run() {
Ken Chenffc224a2019-03-19 17:41:28 +0800667 LOG(DEBUG) << "GetAddrInfoHandler::run: {" << mNetContext.app_netid << " "
668 << mNetContext.app_mark << " " << mNetContext.dns_netid << " "
669 << mNetContext.dns_mark << " " << mNetContext.uid << " " << mNetContext.flags << "}";
Mike Yu19108d52018-11-15 21:58:19 +0800670
671 addrinfo* result = nullptr;
672 Stopwatch s;
673 maybeFixupNetContext(&mNetContext);
674 const uid_t uid = mClient->getUid();
675 int32_t rv = 0;
lifr94981782019-05-17 21:15:19 +0800676 NetworkDnsEventReported event;
677 initDnsEvent(&event);
Mike Yu19108d52018-11-15 21:58:19 +0800678 if (queryLimiter.start(uid)) {
lifr94981782019-05-17 21:15:19 +0800679 rv = resolv_getaddrinfo(mHost, mService, mHints, &mNetContext, &result, &event);
Mike Yu19108d52018-11-15 21:58:19 +0800680 queryLimiter.finish(uid);
681 } else {
682 // Note that this error code is currently not passed down to the client.
683 // android_getaddrinfo_proxy() returns EAI_NODATA on any error.
684 rv = EAI_MEMORY;
Ken Chenffc224a2019-03-19 17:41:28 +0800685 LOG(ERROR) << "GetAddrInfoHandler::run: from UID " << uid
686 << ", max concurrent queries reached";
Mike Yu19108d52018-11-15 21:58:19 +0800687 }
688
lifr94981782019-05-17 21:15:19 +0800689 doDns64Synthesis(&rv, &result, &event);
690 const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
691 event.set_latency_micros(latencyUs);
692 event.set_event_type(EVENT_GETADDRINFO);
693 event.set_hints_ai_flags((mHints ? mHints->ai_flags : 0));
Mike Yu19108d52018-11-15 21:58:19 +0800694
695 if (rv) {
696 // getaddrinfo failed
697 mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, &rv, sizeof(rv));
698 } else {
699 bool success = !mClient->sendCode(ResponseCode::DnsProxyQueryResult);
700 addrinfo* ai = result;
701 while (ai && success) {
702 success = sendBE32(mClient, 1) && sendaddrinfo(mClient, ai);
703 ai = ai->ai_next;
704 }
705 success = success && sendBE32(mClient, 0);
706 if (!success) {
Ken Chenffc224a2019-03-19 17:41:28 +0800707 LOG(WARNING) << "GetAddrInfoHandler::run: Error writing DNS result to client";
Mike Yu19108d52018-11-15 21:58:19 +0800708 }
709 }
710 std::vector<std::string> ip_addrs;
711 const int total_ip_addr_count = extractGetAddrInfoAnswers(result, &ip_addrs);
lifr94981782019-05-17 21:15:19 +0800712 reportDnsEvent(INetdEventListener::EVENT_GETADDRINFO, mNetContext, latencyUs, rv, event, mHost,
713 ip_addrs, total_ip_addr_count);
Mike Yu19108d52018-11-15 21:58:19 +0800714 freeaddrinfo(result);
715 mClient->decRef();
716}
717
718namespace {
719
720void addIpAddrWithinLimit(std::vector<std::string>* ip_addrs, const sockaddr* addr,
721 socklen_t addrlen) {
722 // ipAddresses array is limited to first INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT
723 // addresses for A and AAAA. Total count of addresses is provided, to be able to tell whether
724 // some addresses didn't get logged.
725 if (ip_addrs->size() < INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT) {
726 char ip_addr[INET6_ADDRSTRLEN];
727 if (getnameinfo(addr, addrlen, ip_addr, sizeof(ip_addr), nullptr, 0, NI_NUMERICHOST) == 0) {
728 ip_addrs->push_back(std::string(ip_addr));
729 }
730 }
731}
732
733} // namespace
734
735DnsProxyListener::GetAddrInfoCmd::GetAddrInfoCmd() : FrameworkCommand("getaddrinfo") {}
736
737int DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient *cli,
738 int argc, char **argv) {
Bernie Innocenti3952ccc2019-03-03 19:39:53 +0900739 logArguments(argc, argv);
Mike Yu19108d52018-11-15 21:58:19 +0800740
741 if (argc != 8) {
742 char* msg = nullptr;
743 asprintf( &msg, "Invalid number of arguments to getaddrinfo: %i", argc);
Ken Chenffc224a2019-03-19 17:41:28 +0800744 LOG(WARNING) << "GetAddrInfoCmd::runCommand: " << (msg ? msg : "null");
Mike Yu19108d52018-11-15 21:58:19 +0800745 cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
746 free(msg);
747 return -1;
748 }
749
750 char* name = argv[1];
751 if (strcmp("^", name) == 0) {
752 name = nullptr;
753 } else {
754 name = strdup(name);
755 }
756
757 char* service = argv[2];
758 if (strcmp("^", service) == 0) {
759 service = nullptr;
760 } else {
761 service = strdup(service);
762 }
763
764 addrinfo* hints = nullptr;
765 int ai_flags = strtol(argv[3], nullptr, 10);
766 int ai_family = strtol(argv[4], nullptr, 10);
767 int ai_socktype = strtol(argv[5], nullptr, 10);
768 int ai_protocol = strtol(argv[6], nullptr, 10);
769 unsigned netId = strtoul(argv[7], nullptr, 10);
770 const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
771 const uid_t uid = cli->getUid();
772
773 android_net_context netcontext;
Luke Huang36796f32019-03-13 02:54:45 +0800774 gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
Mike Yu19108d52018-11-15 21:58:19 +0800775
776 if (useLocalNameservers) {
777 netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
778 }
779
780 if (ai_flags != -1 || ai_family != -1 ||
781 ai_socktype != -1 || ai_protocol != -1) {
782 hints = (addrinfo*) calloc(1, sizeof(addrinfo));
783 hints->ai_flags = ai_flags;
784 hints->ai_family = ai_family;
785 hints->ai_socktype = ai_socktype;
786 hints->ai_protocol = ai_protocol;
787 }
788
Mike Yu19108d52018-11-15 21:58:19 +0800789 DnsProxyListener::GetAddrInfoHandler* handler =
790 new DnsProxyListener::GetAddrInfoHandler(cli, name, service, hints, netcontext);
791 tryThreadOrError(cli, handler);
792 return 0;
793}
794
795/*******************************************************
Bernie Innocenti3952ccc2019-03-03 19:39:53 +0900796 * ResNSendCommand *
Mike Yu19108d52018-11-15 21:58:19 +0800797 *******************************************************/
798DnsProxyListener::ResNSendCommand::ResNSendCommand() : FrameworkCommand("resnsend") {}
799
800int DnsProxyListener::ResNSendCommand::runCommand(SocketClient* cli, int argc, char** argv) {
Bernie Innocenti3952ccc2019-03-03 19:39:53 +0900801 logArguments(argc, argv);
Mike Yu19108d52018-11-15 21:58:19 +0800802
803 const uid_t uid = cli->getUid();
804 if (argc != 4) {
Ken Chenffc224a2019-03-19 17:41:28 +0800805 LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
806 << ", invalid number of arguments to resnsend: " << argc;
Mike Yu19108d52018-11-15 21:58:19 +0800807 sendBE32(cli, -EINVAL);
808 return -1;
809 }
810
811 unsigned netId;
812 if (!simpleStrtoul(argv[1], &netId)) {
Ken Chenffc224a2019-03-19 17:41:28 +0800813 LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
814 << ", invalid netId";
Mike Yu19108d52018-11-15 21:58:19 +0800815 sendBE32(cli, -EINVAL);
816 return -1;
817 }
818
819 uint32_t flags;
820 if (!simpleStrtoul(argv[2], &flags)) {
Ken Chenffc224a2019-03-19 17:41:28 +0800821 LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
822 << ", invalid flags";
Mike Yu19108d52018-11-15 21:58:19 +0800823 sendBE32(cli, -EINVAL);
824 return -1;
825 }
826
Luke Huangcb346132019-05-14 22:15:06 +0800827 const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
828
Mike Yu19108d52018-11-15 21:58:19 +0800829 android_net_context netcontext;
Luke Huang36796f32019-03-13 02:54:45 +0800830 gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
Luke Huangcb346132019-05-14 22:15:06 +0800831
832 if (useLocalNameservers) {
Mike Yu19108d52018-11-15 21:58:19 +0800833 netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
834 }
835
836 DnsProxyListener::ResNSendHandler* handler =
837 new DnsProxyListener::ResNSendHandler(cli, argv[3], flags, netcontext);
838 tryThreadOrError(cli, handler);
839 return 0;
840}
841
842DnsProxyListener::ResNSendHandler::ResNSendHandler(SocketClient* c, std::string msg, uint32_t flags,
843 const android_net_context& netcontext)
844 : mClient(c), mMsg(std::move(msg)), mFlags(flags), mNetContext(netcontext) {}
845
846DnsProxyListener::ResNSendHandler::~ResNSendHandler() {
847 mClient->decRef();
848}
849
850void DnsProxyListener::ResNSendHandler::run() {
Ken Chenffc224a2019-03-19 17:41:28 +0800851 LOG(DEBUG) << "ResNSendHandler::run: " << mFlags << " / {" << mNetContext.app_netid << " "
852 << mNetContext.app_mark << " " << mNetContext.dns_netid << " "
853 << mNetContext.dns_mark << " " << mNetContext.uid << " " << mNetContext.flags << "}";
Mike Yu19108d52018-11-15 21:58:19 +0800854
855 Stopwatch s;
856 maybeFixupNetContext(&mNetContext);
857
858 // Decode
859 std::vector<uint8_t> msg(MAXPACKET, 0);
860
861 // Max length of mMsg is less than 1024 since the CMD_BUF_SIZE in FrameworkListener is 1024
862 int msgLen = b64_pton(mMsg.c_str(), msg.data(), MAXPACKET);
863 if (msgLen == -1) {
864 // Decode fail
865 sendBE32(mClient, -EILSEQ);
866 return;
867 }
868
869 const uid_t uid = mClient->getUid();
870 int rr_type = 0;
871 std::string rr_name;
Luke Huang70931aa2019-01-31 11:57:41 +0800872 uint16_t original_query_id = 0;
Mike Yu19108d52018-11-15 21:58:19 +0800873
874 // TODO: Handle the case which is msg contains more than one query
Luke Huang70931aa2019-01-31 11:57:41 +0800875 if (!parseQuery(msg.data(), msgLen, &original_query_id, &rr_type, &rr_name) ||
876 !setQueryId(msg.data(), msgLen, arc4random_uniform(65536))) {
Mike Yu19108d52018-11-15 21:58:19 +0800877 // If the query couldn't be parsed, block the request.
Ken Chenffc224a2019-03-19 17:41:28 +0800878 LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid << ", invalid query";
Mike Yu19108d52018-11-15 21:58:19 +0800879 sendBE32(mClient, -EINVAL);
880 return;
881 }
882
883 // Send DNS query
884 std::vector<uint8_t> ansBuf(MAXPACKET, 0);
885 int arcode, nsendAns = -1;
lifr94981782019-05-17 21:15:19 +0800886 NetworkDnsEventReported event;
887 initDnsEvent(&event);
Mike Yu19108d52018-11-15 21:58:19 +0800888 if (queryLimiter.start(uid)) {
889 nsendAns = resolv_res_nsend(&mNetContext, msg.data(), msgLen, ansBuf.data(), MAXPACKET,
lifr94981782019-05-17 21:15:19 +0800890 &arcode, static_cast<ResNsendFlags>(mFlags), &event);
Mike Yu19108d52018-11-15 21:58:19 +0800891 queryLimiter.finish(uid);
892 } else {
Ken Chenffc224a2019-03-19 17:41:28 +0800893 LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid
894 << ", max concurrent queries reached";
Mike Yu19108d52018-11-15 21:58:19 +0800895 nsendAns = -EBUSY;
896 }
897
lifr94981782019-05-17 21:15:19 +0800898 const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
899 event.set_latency_micros(latencyUs);
900 event.set_event_type(EVENT_RES_NSEND);
901 event.set_res_nsend_flags(static_cast<ResNsendFlags>(mFlags));
Mike Yu19108d52018-11-15 21:58:19 +0800902
903 // Fail, send -errno
904 if (nsendAns < 0) {
905 sendBE32(mClient, nsendAns);
906 if (rr_type == ns_t_a || rr_type == ns_t_aaaa) {
907 reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs,
lifr94981782019-05-17 21:15:19 +0800908 resNSendToAiError(nsendAns, arcode), event, rr_name);
Mike Yu19108d52018-11-15 21:58:19 +0800909 }
910 return;
911 }
912
913 // Send rcode
914 if (!sendBE32(mClient, arcode)) {
Ken Chenffc224a2019-03-19 17:41:28 +0800915 PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send rcode to uid " << uid;
Mike Yu19108d52018-11-15 21:58:19 +0800916 return;
917 }
918
Luke Huang70931aa2019-01-31 11:57:41 +0800919 // Restore query id and send answer
920 if (!setQueryId(ansBuf.data(), nsendAns, original_query_id) ||
921 !sendLenAndData(mClient, nsendAns, ansBuf.data())) {
Ken Chenffc224a2019-03-19 17:41:28 +0800922 PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send answer to uid " << uid;
Mike Yu19108d52018-11-15 21:58:19 +0800923 return;
924 }
925
926 if (rr_type == ns_t_a || rr_type == ns_t_aaaa) {
927 std::vector<std::string> ip_addrs;
928 const int total_ip_addr_count =
929 extractResNsendAnswers((uint8_t*) ansBuf.data(), nsendAns, rr_type, &ip_addrs);
930 reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs,
lifr94981782019-05-17 21:15:19 +0800931 resNSendToAiError(nsendAns, arcode), event, rr_name, ip_addrs,
lifr9b87e362019-05-08 13:00:14 +0800932 total_ip_addr_count);
Mike Yu19108d52018-11-15 21:58:19 +0800933 }
934}
935
Luke Huang9807e6b2019-05-20 16:17:12 +0800936namespace {
937
938bool sendCodeAndBe32(SocketClient* c, int code, int data) {
Luke Huang0d592bc2019-05-25 18:24:03 +0800939 return !c->sendCode(code) && sendBE32(c, data);
Luke Huang9807e6b2019-05-20 16:17:12 +0800940}
941
942} // namespace
943
944/*******************************************************
945 * GetDnsNetId *
946 *******************************************************/
947DnsProxyListener::GetDnsNetIdCommand::GetDnsNetIdCommand() : FrameworkCommand("getdnsnetid") {}
948
949int DnsProxyListener::GetDnsNetIdCommand::runCommand(SocketClient* cli, int argc, char** argv) {
950 logArguments(argc, argv);
951
952 const uid_t uid = cli->getUid();
953 if (argc != 2) {
954 LOG(WARNING) << "GetDnsNetIdCommand::runCommand: getdnsnetid: from UID " << uid
955 << ", invalid number of arguments to getdnsnetid: " << argc;
956 sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, -EINVAL);
957 return -1;
958 }
959
960 unsigned netId;
961 if (!simpleStrtoul(argv[1], &netId)) {
962 LOG(WARNING) << "GetDnsNetIdCommand::runCommand: getdnsnetid: from UID " << uid
963 << ", invalid netId";
964 sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, -EINVAL);
965 return -1;
966 }
967
Luke Huang0d592bc2019-05-25 18:24:03 +0800968 const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
Luke Huang9807e6b2019-05-20 16:17:12 +0800969 android_net_context netcontext;
970 gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
971
Luke Huang0d592bc2019-05-25 18:24:03 +0800972 if (useLocalNameservers) {
973 netcontext.app_netid |= NETID_USE_LOCAL_NAMESERVERS;
974 }
975
976 return sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, netcontext.app_netid) ? 0 : -1;
Luke Huang9807e6b2019-05-20 16:17:12 +0800977}
978
Mike Yu19108d52018-11-15 21:58:19 +0800979/*******************************************************
980 * GetHostByName *
981 *******************************************************/
982DnsProxyListener::GetHostByNameCmd::GetHostByNameCmd() : FrameworkCommand("gethostbyname") {}
983
984int DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient *cli,
985 int argc, char **argv) {
Bernie Innocenti3952ccc2019-03-03 19:39:53 +0900986 logArguments(argc, argv);
Mike Yu19108d52018-11-15 21:58:19 +0800987
988 if (argc != 4) {
989 char* msg = nullptr;
990 asprintf(&msg, "Invalid number of arguments to gethostbyname: %i", argc);
Ken Chenffc224a2019-03-19 17:41:28 +0800991 LOG(WARNING) << "GetHostByNameCmd::runCommand: " << (msg ? msg : "null");
Mike Yu19108d52018-11-15 21:58:19 +0800992 cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
993 free(msg);
994 return -1;
995 }
996
997 uid_t uid = cli->getUid();
998 unsigned netId = strtoul(argv[1], nullptr, 10);
999 const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
1000 char* name = argv[2];
1001 int af = strtol(argv[3], nullptr, 10);
1002
1003 if (strcmp(name, "^") == 0) {
1004 name = nullptr;
1005 } else {
1006 name = strdup(name);
1007 }
1008
1009 android_net_context netcontext;
Luke Huang36796f32019-03-13 02:54:45 +08001010 gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
Mike Yu19108d52018-11-15 21:58:19 +08001011
1012 if (useLocalNameservers) {
1013 netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
1014 }
1015
1016 DnsProxyListener::GetHostByNameHandler* handler =
1017 new DnsProxyListener::GetHostByNameHandler(cli, name, af, netcontext);
1018 tryThreadOrError(cli, handler);
1019 return 0;
1020}
1021
1022DnsProxyListener::GetHostByNameHandler::GetHostByNameHandler(SocketClient* c, char* name, int af,
1023 const android_net_context& netcontext)
1024 : mClient(c), mName(name), mAf(af), mNetContext(netcontext) {}
1025
1026DnsProxyListener::GetHostByNameHandler::~GetHostByNameHandler() {
1027 free(mName);
1028}
1029
lifr94981782019-05-17 21:15:19 +08001030void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, struct hostent** hpp,
1031 NetworkDnsEventReported* event) {
Mike Yu19108d52018-11-15 21:58:19 +08001032 // Don't have to consider family AF_UNSPEC case because gethostbyname{, 2} only supports
1033 // family AF_INET or AF_INET6.
1034 const bool ipv6WantedButNoData = (mAf == AF_INET6 && *rv == EAI_NODATA);
1035
1036 if (!ipv6WantedButNoData) {
1037 return;
1038 }
1039
1040 netdutils::IPPrefix prefix{};
1041 if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
1042 return;
1043 }
1044
1045 // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis
1046 const uid_t uid = mClient->getUid();
1047 if (queryLimiter.start(uid)) {
lifr94981782019-05-17 21:15:19 +08001048 *rv = android_gethostbynamefornetcontext(mName, AF_INET, &mNetContext, hpp, event);
Mike Yu19108d52018-11-15 21:58:19 +08001049 queryLimiter.finish(uid);
1050 if (*rv) {
1051 *rv = EAI_NODATA; // return original error code
1052 return;
1053 }
1054 } else {
Ken Chenffc224a2019-03-19 17:41:28 +08001055 LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached";
Mike Yu19108d52018-11-15 21:58:19 +08001056 return;
1057 }
1058
1059 if (!synthesizeNat64PrefixWithARecord(prefix, *hpp)) {
1060 // If caller wants IPv6 answers but no data and failed to synthesize IPv4 answers,
1061 // don't return the IPv4 answers.
1062 *hpp = nullptr;
1063 }
1064}
1065
1066void DnsProxyListener::GetHostByNameHandler::run() {
Mike Yu19108d52018-11-15 21:58:19 +08001067 Stopwatch s;
1068 maybeFixupNetContext(&mNetContext);
1069 const uid_t uid = mClient->getUid();
1070 hostent* hp = nullptr;
1071 int32_t rv = 0;
lifr94981782019-05-17 21:15:19 +08001072 NetworkDnsEventReported event;
1073 initDnsEvent(&event);
Mike Yu19108d52018-11-15 21:58:19 +08001074 if (queryLimiter.start(uid)) {
lifr94981782019-05-17 21:15:19 +08001075 rv = android_gethostbynamefornetcontext(mName, mAf, &mNetContext, &hp, &event);
Mike Yu19108d52018-11-15 21:58:19 +08001076 queryLimiter.finish(uid);
1077 } else {
1078 rv = EAI_MEMORY;
Ken Chenffc224a2019-03-19 17:41:28 +08001079 LOG(ERROR) << "GetHostByNameHandler::run: from UID " << uid
1080 << ", max concurrent queries reached";
Mike Yu19108d52018-11-15 21:58:19 +08001081 }
1082
lifr94981782019-05-17 21:15:19 +08001083 doDns64Synthesis(&rv, &hp, &event);
1084 const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
1085 event.set_latency_micros(latencyUs);
1086 event.set_event_type(EVENT_GETHOSTBYNAME);
1087
Ken Chenffc224a2019-03-19 17:41:28 +08001088 LOG(DEBUG) << "GetHostByNameHandler::run: errno: " << (hp ? "success" : strerror(errno));
Mike Yu19108d52018-11-15 21:58:19 +08001089
1090 bool success = true;
1091 if (hp) {
1092 // hp is not nullptr iff. rv is 0.
1093 success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
1094 success &= sendhostent(mClient, hp);
1095 } else {
1096 success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, nullptr, 0) == 0;
1097 }
1098
1099 if (!success) {
Ken Chenffc224a2019-03-19 17:41:28 +08001100 LOG(WARNING) << "GetHostByNameHandler::run: Error writing DNS result to client";
Mike Yu19108d52018-11-15 21:58:19 +08001101 }
1102
1103 std::vector<std::string> ip_addrs;
1104 const int total_ip_addr_count = extractGetHostByNameAnswers(hp, &ip_addrs);
lifr94981782019-05-17 21:15:19 +08001105 reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYNAME, mNetContext, latencyUs, rv, event,
lifr9b87e362019-05-08 13:00:14 +08001106 mName, ip_addrs, total_ip_addr_count);
Mike Yu19108d52018-11-15 21:58:19 +08001107 mClient->decRef();
1108}
1109
1110
1111/*******************************************************
1112 * GetHostByAddr *
1113 *******************************************************/
1114DnsProxyListener::GetHostByAddrCmd::GetHostByAddrCmd() : FrameworkCommand("gethostbyaddr") {}
1115
1116int DnsProxyListener::GetHostByAddrCmd::runCommand(SocketClient *cli,
1117 int argc, char **argv) {
Bernie Innocenti3952ccc2019-03-03 19:39:53 +09001118 logArguments(argc, argv);
Mike Yu19108d52018-11-15 21:58:19 +08001119
1120 if (argc != 5) {
1121 char* msg = nullptr;
1122 asprintf(&msg, "Invalid number of arguments to gethostbyaddr: %i", argc);
Ken Chenffc224a2019-03-19 17:41:28 +08001123 LOG(WARNING) << "GetHostByAddrCmd::runCommand: " << (msg ? msg : "null");
Mike Yu19108d52018-11-15 21:58:19 +08001124 cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
1125 free(msg);
1126 return -1;
1127 }
1128
1129 char* addrStr = argv[1];
1130 int addrLen = strtol(argv[2], nullptr, 10);
1131 int addrFamily = strtol(argv[3], nullptr, 10);
1132 uid_t uid = cli->getUid();
1133 unsigned netId = strtoul(argv[4], nullptr, 10);
1134 const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
1135
1136 void* addr = malloc(sizeof(in6_addr));
1137 errno = 0;
1138 int result = inet_pton(addrFamily, addrStr, addr);
1139 if (result <= 0) {
1140 char* msg = nullptr;
1141 asprintf(&msg, "inet_pton(\"%s\") failed %s", addrStr, strerror(errno));
Ken Chenffc224a2019-03-19 17:41:28 +08001142 LOG(WARNING) << "GetHostByAddrCmd::runCommand: " << (msg ? msg : "null");
Mike Yu19108d52018-11-15 21:58:19 +08001143 cli->sendMsg(ResponseCode::OperationFailed, msg, false);
1144 free(addr);
1145 free(msg);
1146 return -1;
1147 }
1148
1149 android_net_context netcontext;
Luke Huang36796f32019-03-13 02:54:45 +08001150 gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
Mike Yu19108d52018-11-15 21:58:19 +08001151
1152 if (useLocalNameservers) {
1153 netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
1154 }
1155
1156 DnsProxyListener::GetHostByAddrHandler* handler = new DnsProxyListener::GetHostByAddrHandler(
1157 cli, addr, addrLen, addrFamily, netcontext);
1158 tryThreadOrError(cli, handler);
1159 return 0;
1160}
1161
1162DnsProxyListener::GetHostByAddrHandler::GetHostByAddrHandler(SocketClient* c, void* address,
1163 int addressLen, int addressFamily,
1164 const android_net_context& netcontext)
1165 : mClient(c),
1166 mAddress(address),
1167 mAddressLen(addressLen),
1168 mAddressFamily(addressFamily),
1169 mNetContext(netcontext) {}
1170
1171DnsProxyListener::GetHostByAddrHandler::~GetHostByAddrHandler() {
1172 free(mAddress);
1173}
1174
lifr94981782019-05-17 21:15:19 +08001175void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(struct hostent** hpp,
1176 NetworkDnsEventReported* event) {
Mike Yu19108d52018-11-15 21:58:19 +08001177 if (*hpp != nullptr || mAddressFamily != AF_INET6 || !mAddress) {
1178 return;
1179 }
1180
1181 netdutils::IPPrefix prefix{};
1182 if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
1183 return;
1184 }
1185
1186 if (!isValidNat64Prefix(prefix)) {
1187 return;
1188 }
1189
1190 struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
1191 struct sockaddr_in6* v6prefix = (struct sockaddr_in6*) &ss;
1192 struct in6_addr v6addr = *(in6_addr*) mAddress;
1193 // Check if address has NAT64 prefix. Only /96 IPv6 NAT64 prefixes are supported
1194 if ((v6addr.s6_addr32[0] != v6prefix->sin6_addr.s6_addr32[0]) ||
1195 (v6addr.s6_addr32[1] != v6prefix->sin6_addr.s6_addr32[1]) ||
1196 (v6addr.s6_addr32[2] != v6prefix->sin6_addr.s6_addr32[2])) {
1197 return;
1198 }
1199
1200 const uid_t uid = mClient->getUid();
1201 if (queryLimiter.start(uid)) {
1202 // Remove NAT64 prefix and do reverse DNS query
1203 struct in_addr v4addr = {.s_addr = v6addr.s6_addr32[3]};
lifr94981782019-05-17 21:15:19 +08001204 android_gethostbyaddrfornetcontext(&v4addr, sizeof(v4addr), AF_INET, &mNetContext, hpp,
1205 event);
Mike Yu19108d52018-11-15 21:58:19 +08001206 queryLimiter.finish(uid);
1207 if (*hpp) {
1208 // Replace IPv4 address with original queried IPv6 address in place. The space has
waynema067e9842019-03-08 19:13:41 +08001209 // reserved by dns_gethtbyaddr() and netbsd_gethostent_r() in
Mike Yu19108d52018-11-15 21:58:19 +08001210 // system/netd/resolv/gethnamaddr.cpp.
1211 // Note that android_gethostbyaddrfornetcontext returns only one entry in result.
1212 memcpy((*hpp)->h_addr_list[0], &v6addr, sizeof(v6addr));
1213 (*hpp)->h_addrtype = AF_INET6;
1214 (*hpp)->h_length = sizeof(struct in6_addr);
1215 }
1216 } else {
Ken Chenffc224a2019-03-19 17:41:28 +08001217 LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached";
Mike Yu19108d52018-11-15 21:58:19 +08001218 }
1219}
1220
1221void DnsProxyListener::GetHostByAddrHandler::run() {
Mike Yu19108d52018-11-15 21:58:19 +08001222 Stopwatch s;
1223 maybeFixupNetContext(&mNetContext);
1224 const uid_t uid = mClient->getUid();
1225 hostent* hp = nullptr;
1226 int32_t rv = 0;
lifr94981782019-05-17 21:15:19 +08001227 NetworkDnsEventReported event;
1228 initDnsEvent(&event);
Mike Yu19108d52018-11-15 21:58:19 +08001229 if (queryLimiter.start(uid)) {
lifr94981782019-05-17 21:15:19 +08001230 rv = android_gethostbyaddrfornetcontext(mAddress, mAddressLen, mAddressFamily, &mNetContext,
1231 &hp, &event);
Mike Yu19108d52018-11-15 21:58:19 +08001232 queryLimiter.finish(uid);
1233 } else {
1234 rv = EAI_MEMORY;
Ken Chenffc224a2019-03-19 17:41:28 +08001235 LOG(ERROR) << "GetHostByAddrHandler::run: from UID " << uid
1236 << ", max concurrent queries reached";
Mike Yu19108d52018-11-15 21:58:19 +08001237 }
1238
lifr94981782019-05-17 21:15:19 +08001239 doDns64ReverseLookup(&hp, &event);
1240 const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
1241 event.set_latency_micros(latencyUs);
1242 event.set_event_type(EVENT_GETHOSTBYADDR);
Mike Yu19108d52018-11-15 21:58:19 +08001243
Ken Chenffc224a2019-03-19 17:41:28 +08001244 LOG(DEBUG) << "GetHostByAddrHandler::run: result: " << (hp ? "success" : gai_strerror(rv));
Mike Yu19108d52018-11-15 21:58:19 +08001245
1246 bool success = true;
1247 if (hp) {
1248 success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
1249 success &= sendhostent(mClient, hp);
1250 } else {
1251 success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, nullptr, 0) == 0;
1252 }
1253
1254 if (!success) {
Ken Chenffc224a2019-03-19 17:41:28 +08001255 LOG(WARNING) << "GetHostByAddrHandler::run: Error writing DNS result to client";
Mike Yu19108d52018-11-15 21:58:19 +08001256 }
1257
lifr94981782019-05-17 21:15:19 +08001258 reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYADDR, mNetContext, latencyUs, rv, event,
Mike Yu19108d52018-11-15 21:58:19 +08001259 (hp && hp->h_name) ? hp->h_name : "null", {}, 0);
1260 mClient->decRef();
1261}
1262
1263} // namespace net
1264} // namespace android