blob: dc8cd96b1a18bb6a080c74029c349467123996ae [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 Yu04f1d482019-08-08 11:09:32 +080041#include <cutils/multiuser.h>
Mike Yudaa29932019-03-13 14:43:39 +080042#include <netdutils/InternetAddresses.h>
Mike Yu19108d52018-11-15 21:58:19 +080043#include <netdutils/OperationLimiter.h>
Mike Yudaa29932019-03-13 14:43:39 +080044#include <netdutils/ResponseCode.h>
Mike Yu19108d52018-11-15 21:58:19 +080045#include <netdutils/Slice.h>
Mike Yu40ea2ad2019-03-13 17:15:48 +080046#include <netdutils/Stopwatch.h>
Mike Yu133f7ab2019-03-14 15:14:44 +080047#include <netdutils/ThreadUtil.h>
Mike Yu19108d52018-11-15 21:58:19 +080048#include <private/android_filesystem_config.h> // AID_SYSTEM
lifr9b87e362019-05-08 13:00:14 +080049#include <statslog_resolv.h>
Mike Yu19108d52018-11-15 21:58:19 +080050#include <sysutils/SocketClient.h>
51
Luke Huang36796f32019-03-13 02:54:45 +080052#include "DnsResolver.h"
Remi NGUYEN VAN10e0b712019-02-07 12:25:23 +090053#include "NetdPermissions.h"
Bernie Innocenti23c6e2a2019-05-16 15:18:35 +090054#include "PrivateDnsConfiguration.h"
Bernie Innocentiec4219b2019-01-30 11:16:36 +090055#include "ResolverEventReporter.h"
Bernie Innocentie71a28a2019-05-29 00:42:35 +090056#include "getaddrinfo.h"
57#include "gethnamaddr.h"
Mike Yu19108d52018-11-15 21:58:19 +080058#include "netd_resolv/stats.h" // RCODE_TIMEOUT
Bernie Innocentie71a28a2019-05-29 00:42:35 +090059#include "res_send.h"
Luke Huange126fbe2019-07-20 17:36:30 +080060#include "resolv_cache.h"
chenbruceacb832c2019-02-20 19:45:50 +080061#include "resolv_private.h"
lifr9b87e362019-05-08 13:00:14 +080062#include "stats.pb.h"
Mike Yu19108d52018-11-15 21:58:19 +080063
64using aidl::android::net::metrics::INetdEventListener;
lifr9b87e362019-05-08 13:00:14 +080065using android::net::NetworkDnsEventReported;
Mike Yu19108d52018-11-15 21:58:19 +080066
Mike Yu19108d52018-11-15 21:58:19 +080067namespace android {
Mike Yu19108d52018-11-15 21:58:19 +080068
Mike Yudaa29932019-03-13 14:43:39 +080069using netdutils::ResponseCode;
Mike Yu40ea2ad2019-03-13 17:15:48 +080070using netdutils::Stopwatch;
Mike Yudaa29932019-03-13 14:43:39 +080071
72namespace net {
Mike Yu19108d52018-11-15 21:58:19 +080073namespace {
74
Mike Yu19108d52018-11-15 21:58:19 +080075// Limits the number of outstanding DNS queries by client UID.
76constexpr int MAX_QUERIES_PER_UID = 256;
77
78// Max packet size for answer, sync with getaddrinfo.c
79constexpr int MAXPACKET = 8 * 1024;
80
81android::netdutils::OperationLimiter<uid_t> queryLimiter(MAX_QUERIES_PER_UID);
82
83void logArguments(int argc, char** argv) {
Ken Chenffc224a2019-03-19 17:41:28 +080084 if (!WOULD_LOG(VERBOSE)) return;
Mike Yu19108d52018-11-15 21:58:19 +080085 for (int i = 0; i < argc; i++) {
Ken Chenffc224a2019-03-19 17:41:28 +080086 LOG(VERBOSE) << __func__ << ": argv[" << i << "]=" << (argv[i] ? argv[i] : "null");
Mike Yu19108d52018-11-15 21:58:19 +080087 }
88}
89
90template<typename T>
91void tryThreadOrError(SocketClient* cli, T* handler) {
92 cli->incRef();
93
Mike Yu133f7ab2019-03-14 15:14:44 +080094 const int rval = netdutils::threadLaunch(handler);
Mike Yu19108d52018-11-15 21:58:19 +080095 if (rval == 0) {
96 // SocketClient decRef() happens in the handler's run() method.
97 return;
98 }
99
100 char* msg = nullptr;
101 asprintf(&msg, "%s (%d)", strerror(-rval), -rval);
102 cli->sendMsg(ResponseCode::OperationFailed, msg, false);
103 free(msg);
104
105 delete handler;
106 cli->decRef();
107}
108
109bool checkAndClearUseLocalNameserversFlag(unsigned* netid) {
110 if (netid == nullptr || ((*netid) & NETID_USE_LOCAL_NAMESERVERS) == 0) {
111 return false;
112 }
113 *netid = (*netid) & ~NETID_USE_LOCAL_NAMESERVERS;
114 return true;
115}
116
117constexpr bool requestingUseLocalNameservers(unsigned flags) {
118 return (flags & NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS) != 0;
119}
120
Mike Yu3e829062019-08-07 14:01:14 +0800121bool queryingViaTls(unsigned dns_netid) {
122 const auto privateDnsStatus = gPrivateDnsConfiguration.getStatus(dns_netid);
123 switch (privateDnsStatus.mode) {
Mike Yu19108d52018-11-15 21:58:19 +0800124 case PrivateDnsMode::OPPORTUNISTIC:
Mike Yu3e829062019-08-07 14:01:14 +0800125 return !privateDnsStatus.validatedServers().empty();
Mike Yu19108d52018-11-15 21:58:19 +0800126 case PrivateDnsMode::STRICT:
127 return true;
128 default:
129 return false;
130 }
131}
132
133bool hasPermissionToBypassPrivateDns(uid_t uid) {
134 static_assert(AID_SYSTEM >= 0 && AID_SYSTEM < FIRST_APPLICATION_UID,
135 "Calls from AID_SYSTEM must not result in a permission check to avoid deadlock.");
136 if (uid >= 0 && uid < FIRST_APPLICATION_UID) {
137 return true;
138 }
139
140 for (const char* const permission :
Remi NGUYEN VAN10e0b712019-02-07 12:25:23 +0900141 {PERM_CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERM_NETWORK_BYPASS_PRIVATE_DNS,
142 PERM_MAINLINE_NETWORK_STACK}) {
Luke Huang36796f32019-03-13 02:54:45 +0800143 if (gResNetdCallbacks.check_calling_permission(permission)) {
Mike Yu19108d52018-11-15 21:58:19 +0800144 return true;
145 }
146 }
147 return false;
148}
149
150void maybeFixupNetContext(android_net_context* ctx) {
151 if (requestingUseLocalNameservers(ctx->flags) && !hasPermissionToBypassPrivateDns(ctx->uid)) {
152 // Not permitted; clear the flag.
153 ctx->flags &= ~NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
154 }
155
156 if (!requestingUseLocalNameservers(ctx->flags)) {
157 // If we're not explicitly bypassing DNS-over-TLS servers, check whether
158 // DNS-over-TLS is in use as an indicator for when to use more modern
159 // DNS resolution mechanics.
160 if (queryingViaTls(ctx->dns_netid)) {
chenbruced8cbb9b2019-06-20 18:25:28 +0800161 ctx->flags |= NET_CONTEXT_FLAG_USE_DNS_OVER_TLS | NET_CONTEXT_FLAG_USE_EDNS;
Mike Yu19108d52018-11-15 21:58:19 +0800162 }
163 }
164}
165
166void addIpAddrWithinLimit(std::vector<std::string>* ip_addrs, const sockaddr* addr,
167 socklen_t addrlen);
168
169int extractResNsendAnswers(const uint8_t* answer, size_t anslen, int ipType,
170 std::vector<std::string>* ip_addrs) {
171 int total_ip_addr_count = 0;
172 ns_msg handle;
173 if (ns_initparse((const uint8_t*) answer, anslen, &handle) < 0) {
174 return 0;
175 }
176 int ancount = ns_msg_count(handle, ns_s_an);
177 ns_rr rr;
178 for (int i = 0; i < ancount; i++) {
179 if (ns_parserr(&handle, ns_s_an, i, &rr) < 0) {
180 continue;
181 }
182 const uint8_t* rdata = ns_rr_rdata(rr);
183 if (ipType == ns_t_a) {
184 sockaddr_in sin = {.sin_family = AF_INET};
185 memcpy(&sin.sin_addr, rdata, sizeof(sin.sin_addr));
186 addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin, sizeof(sin));
187 total_ip_addr_count++;
188 } else if (ipType == ns_t_aaaa) {
189 sockaddr_in6 sin6 = {.sin6_family = AF_INET6};
190 memcpy(&sin6.sin6_addr, rdata, sizeof(sin6.sin6_addr));
191 addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin6, sizeof(sin6));
192 total_ip_addr_count++;
193 }
194 }
195
196 return total_ip_addr_count;
197}
198
199int extractGetAddrInfoAnswers(const addrinfo* result, std::vector<std::string>* ip_addrs) {
200 int total_ip_addr_count = 0;
201 if (result == nullptr) {
202 return 0;
203 }
204 for (const addrinfo* ai = result; ai; ai = ai->ai_next) {
205 sockaddr* ai_addr = ai->ai_addr;
206 if (ai_addr) {
207 addIpAddrWithinLimit(ip_addrs, ai_addr, ai->ai_addrlen);
208 total_ip_addr_count++;
209 }
210 }
211 return total_ip_addr_count;
212}
213
214int extractGetHostByNameAnswers(const hostent* hp, std::vector<std::string>* ip_addrs) {
215 int total_ip_addr_count = 0;
216 if (hp == nullptr) {
217 return 0;
218 }
219 if (hp->h_addrtype == AF_INET) {
220 in_addr** list = (in_addr**) hp->h_addr_list;
221 for (int i = 0; list[i] != nullptr; i++) {
222 sockaddr_in sin = {.sin_family = AF_INET, .sin_addr = *list[i]};
223 addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin, sizeof(sin));
224 total_ip_addr_count++;
225 }
226 } else if (hp->h_addrtype == AF_INET6) {
227 in6_addr** list = (in6_addr**) hp->h_addr_list;
228 for (int i = 0; list[i] != nullptr; i++) {
229 sockaddr_in6 sin6 = {.sin6_family = AF_INET6, .sin6_addr = *list[i]};
230 addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin6, sizeof(sin6));
231 total_ip_addr_count++;
232 }
233 }
234 return total_ip_addr_count;
235}
236
237int rcodeToAiError(int rcode) {
238 switch (rcode) {
239 case NOERROR:
240 return 0;
241 case RCODE_TIMEOUT:
242 return NETD_RESOLV_TIMEOUT;
243 default:
244 return EAI_NODATA;
245 }
246}
247
248int resNSendToAiError(int err, int rcode) {
249 if (err > 0) {
250 return rcodeToAiError(rcode);
251 }
252 if (err == -ETIMEDOUT) {
253 return NETD_RESOLV_TIMEOUT;
254 }
255 return EAI_SYSTEM;
256}
257
258template <typename IntegralType>
259bool simpleStrtoul(const char* input, IntegralType* output, int base = 10) {
260 char* endPtr;
261 errno = 0;
262 auto result = strtoul(input, &endPtr, base);
263 // Check the length in order to ensure there is no "-" sign
264 if (!*input || *endPtr || (endPtr - input) != static_cast<ptrdiff_t>(strlen(input)) ||
265 (errno == ERANGE && (result == ULONG_MAX))) {
266 return false;
267 }
268 *output = result;
269 return true;
270}
271
Luke Huang70931aa2019-01-31 11:57:41 +0800272bool setQueryId(uint8_t* msg, size_t msgLen, uint16_t query_id) {
273 if (msgLen < sizeof(HEADER)) {
274 errno = EINVAL;
275 return false;
276 }
277 auto hp = reinterpret_cast<HEADER*>(msg);
278 hp->id = htons(query_id);
279 return true;
280}
281
282bool parseQuery(const uint8_t* msg, size_t msgLen, uint16_t* query_id, int* rr_type,
283 std::string* rr_name) {
Mike Yu19108d52018-11-15 21:58:19 +0800284 ns_msg handle;
285 ns_rr rr;
Luke Huang70931aa2019-01-31 11:57:41 +0800286 if (ns_initparse((const uint8_t*)msg, msgLen, &handle) < 0 ||
Mike Yu19108d52018-11-15 21:58:19 +0800287 ns_parserr(&handle, ns_s_qd, 0, &rr) < 0) {
288 return false;
289 }
Luke Huang70931aa2019-01-31 11:57:41 +0800290 *query_id = ns_msg_id(handle);
Mike Yu19108d52018-11-15 21:58:19 +0800291 *rr_name = ns_rr_name(rr);
292 *rr_type = ns_rr_type(rr);
293 return true;
294}
295
lifr94981782019-05-17 21:15:19 +0800296void initDnsEvent(NetworkDnsEventReported* event) {
lifrd4d9fbb2019-07-31 20:18:35 +0800297 // The value 0 has the special meaning of unset/unknown in Westworld atoms. So, we set both
298 // flags to -1 as default value.
299 // 1. The hints flag is only used in resolv_getaddrinfo. When user set it to -1 in
300 // resolv_getaddrinfo, the flag will cause validation (validateHints) failure in
301 // getaddrinfo, so it will not do DNS query and will upload DNS stats log with
302 // return_code = RC_EAI_BADFLAGS.
303 // 2. The res_nsend flags are only used in resolv_res_nsend. When user set it to -1 in
304 // resolv_res_nsend,res_nsend will do nothing special by the setting.
lifr94981782019-05-17 21:15:19 +0800305 event->set_hints_ai_flags(-1);
306 event->set_res_nsend_flags(-1);
307}
308
Luke Huange126fbe2019-07-20 17:36:30 +0800309// Return 0 if the event should not be logged.
310// Otherwise, return subsampling_denom
311uint32_t getDnsEventSubsamplingRate(int netid, int returnCode) {
312 uint32_t subsampling_denom = resolv_cache_get_subsampling_denom(netid, returnCode);
313 if (subsampling_denom == 0) return 0;
314 // Sample the event with a chance of 1 / denom.
315 return (arc4random_uniform(subsampling_denom) == 0) ? subsampling_denom : 0;
316}
317
Mike Yu19108d52018-11-15 21:58:19 +0800318void reportDnsEvent(int eventType, const android_net_context& netContext, int latencyUs,
lifr94981782019-05-17 21:15:19 +0800319 int returnCode, NetworkDnsEventReported& event, const std::string& query_name,
320 const std::vector<std::string>& ip_addrs = {}, int total_ip_addr_count = 0) {
Luke Huange126fbe2019-07-20 17:36:30 +0800321 if (uint32_t rate = getDnsEventSubsamplingRate(netContext.dns_netid, returnCode)) {
322 const std::string& dnsQueryStats = event.dns_query_events().SerializeAsString();
323 stats::BytesField dnsQueryBytesField{dnsQueryStats.c_str(), dnsQueryStats.size()};
324 event.set_return_code(static_cast<ReturnCode>(returnCode));
325 android::net::stats::stats_write(android::net::stats::NETWORK_DNS_EVENT_REPORTED,
326 event.event_type(), event.return_code(),
327 event.latency_micros(), event.hints_ai_flags(),
328 event.res_nsend_flags(), event.network_type(),
329 event.private_dns_modes(), dnsQueryBytesField, rate);
330 }
Mike Yu19108d52018-11-15 21:58:19 +0800331
Hungming Chena32c8c12019-01-25 10:47:40 +0800332 const auto& listeners = ResolverEventReporter::getInstance().getListeners();
333 if (listeners.size() == 0) {
Ken Chenffc224a2019-03-19 17:41:28 +0800334 LOG(ERROR) << __func__
Hungming Chena32c8c12019-01-25 10:47:40 +0800335 << ": DNS event not sent since no INetdEventListener receiver is available.";
Mike Yu6d2c8922019-02-15 16:03:02 +0800336 return;
337 }
Mike Yu19108d52018-11-15 21:58:19 +0800338 const int latencyMs = latencyUs / 1000;
Hungming Chena32c8c12019-01-25 10:47:40 +0800339 for (const auto& it : listeners) {
340 it->onDnsEvent(netContext.dns_netid, eventType, returnCode, latencyMs, query_name, ip_addrs,
341 total_ip_addr_count, netContext.uid);
342 }
Mike Yu19108d52018-11-15 21:58:19 +0800343}
344
345bool onlyIPv4Answers(const addrinfo* res) {
346 // Null addrinfo pointer isn't checked because the caller doesn't pass null pointer.
347
348 for (const addrinfo* ai = res; ai; ai = ai->ai_next)
349 if (ai->ai_family != AF_INET) return false;
350
351 return true;
352}
353
354bool isSpecialUseIPv4Address(const struct in_addr& ia) {
355 const uint32_t addr = ntohl(ia.s_addr);
356
357 // Only check necessary IP ranges in RFC 5735 section 4
358 return ((addr & 0xff000000) == 0x00000000) || // "This" Network
359 ((addr & 0xff000000) == 0x7f000000) || // Loopback
360 ((addr & 0xffff0000) == 0xa9fe0000) || // Link Local
361 ((addr & 0xf0000000) == 0xe0000000) || // Multicast
362 (addr == INADDR_BROADCAST); // Limited Broadcast
363}
364
365bool isSpecialUseIPv4Address(const struct sockaddr* sa) {
366 if (sa->sa_family != AF_INET) return false;
367
368 return isSpecialUseIPv4Address(((struct sockaddr_in*) sa)->sin_addr);
369}
370
371bool onlyNonSpecialUseIPv4Addresses(struct hostent* hp) {
372 // Null hostent pointer isn't checked because the caller doesn't pass null pointer.
373
374 if (hp->h_addrtype != AF_INET) return false;
375
376 for (int i = 0; hp->h_addr_list[i] != nullptr; i++)
377 if (isSpecialUseIPv4Address(*(struct in_addr*) hp->h_addr_list[i])) return false;
378
379 return true;
380}
381
382bool onlyNonSpecialUseIPv4Addresses(const addrinfo* res) {
383 // Null addrinfo pointer isn't checked because the caller doesn't pass null pointer.
384
385 for (const addrinfo* ai = res; ai; ai = ai->ai_next) {
386 if (ai->ai_family != AF_INET) return false;
387 if (isSpecialUseIPv4Address(ai->ai_addr)) return false;
388 }
389
390 return true;
391}
392
393void logDnsQueryResult(const struct hostent* hp) {
Bernie Innocenti3952ccc2019-03-03 19:39:53 +0900394 if (!WOULD_LOG(DEBUG)) return;
Mike Yu19108d52018-11-15 21:58:19 +0800395 if (hp == nullptr) return;
396
Ken Chenffc224a2019-03-19 17:41:28 +0800397 LOG(DEBUG) << __func__ << ": DNS records:";
Mike Yu19108d52018-11-15 21:58:19 +0800398 for (int i = 0; hp->h_addr_list[i] != nullptr; i++) {
399 char ip_addr[INET6_ADDRSTRLEN];
400 if (inet_ntop(hp->h_addrtype, hp->h_addr_list[i], ip_addr, sizeof(ip_addr)) != nullptr) {
Ken Chenffc224a2019-03-19 17:41:28 +0800401 LOG(DEBUG) << __func__ << ": [" << i << "] " << hp->h_addrtype;
Mike Yu19108d52018-11-15 21:58:19 +0800402 } else {
Ken Chenffc224a2019-03-19 17:41:28 +0800403 PLOG(DEBUG) << __func__ << ": [" << i << "] numeric hostname translation fail";
Mike Yu19108d52018-11-15 21:58:19 +0800404 }
405 }
406}
407
408void logDnsQueryResult(const addrinfo* res) {
Bernie Innocenti3952ccc2019-03-03 19:39:53 +0900409 if (!WOULD_LOG(DEBUG)) return;
Mike Yu19108d52018-11-15 21:58:19 +0800410 if (res == nullptr) return;
411
412 int i;
413 const addrinfo* ai;
Ken Chenffc224a2019-03-19 17:41:28 +0800414 LOG(DEBUG) << __func__ << ": DNS records:";
Mike Yu19108d52018-11-15 21:58:19 +0800415 for (ai = res, i = 0; ai; ai = ai->ai_next, i++) {
416 if ((ai->ai_family != AF_INET) && (ai->ai_family != AF_INET6)) continue;
417 char ip_addr[INET6_ADDRSTRLEN];
418 int ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, ip_addr, sizeof(ip_addr), nullptr, 0,
419 NI_NUMERICHOST);
420 if (!ret) {
Ken Chenffc224a2019-03-19 17:41:28 +0800421 LOG(DEBUG) << __func__ << ": [" << i << "] " << ai->ai_flags << " " << ai->ai_family
422 << " " << ai->ai_socktype << " " << ai->ai_protocol;
Mike Yu19108d52018-11-15 21:58:19 +0800423 } else {
Ken Chenffc224a2019-03-19 17:41:28 +0800424 LOG(DEBUG) << __func__ << ": [" << i << "] numeric hostname translation fail " << ret;
Mike Yu19108d52018-11-15 21:58:19 +0800425 }
426 }
427}
428
429bool isValidNat64Prefix(const netdutils::IPPrefix prefix) {
430 if (prefix.family() != AF_INET6) {
Ken Chenffc224a2019-03-19 17:41:28 +0800431 LOG(ERROR) << __func__ << ": Only IPv6 NAT64 prefixes are supported " << prefix.family();
Mike Yu19108d52018-11-15 21:58:19 +0800432 return false;
433 }
434 if (prefix.length() != 96) {
Ken Chenffc224a2019-03-19 17:41:28 +0800435 LOG(ERROR) << __func__ << ": Only /96 NAT64 prefixes are supported " << prefix.length();
Mike Yu19108d52018-11-15 21:58:19 +0800436 return false;
437 }
438 return true;
439}
440
441bool synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix& prefix, struct hostent* hp) {
442 if (hp == nullptr) return false;
443 if (!onlyNonSpecialUseIPv4Addresses(hp)) return false;
444 if (!isValidNat64Prefix(prefix)) return false;
445
446 struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
447 struct sockaddr_in6* v6prefix = (struct sockaddr_in6*) &ss;
448 for (int i = 0; hp->h_addr_list[i] != nullptr; i++) {
449 struct in_addr iaOriginal = *(struct in_addr*) hp->h_addr_list[i];
450 struct in6_addr* ia6 = (struct in6_addr*) hp->h_addr_list[i];
451 memset(ia6, 0, sizeof(struct in6_addr));
452
453 // Synthesize /96 NAT64 prefix in place. The space has reserved by getanswer() and
454 // _hf_gethtbyname2() in system/netd/resolv/gethnamaddr.cpp and
455 // system/netd/resolv/sethostent.cpp.
456 *ia6 = v6prefix->sin6_addr;
457 ia6->s6_addr32[3] = iaOriginal.s_addr;
458
Ken Chen594fc942019-04-18 18:11:15 +0800459 if (WOULD_LOG(VERBOSE)) {
Mike Yu19108d52018-11-15 21:58:19 +0800460 char buf[INET6_ADDRSTRLEN]; // big enough for either IPv4 or IPv6
461 inet_ntop(AF_INET, &iaOriginal.s_addr, buf, sizeof(buf));
Ken Chen594fc942019-04-18 18:11:15 +0800462 LOG(VERBOSE) << __func__ << ": DNS A record: " << buf;
Mike Yu19108d52018-11-15 21:58:19 +0800463 inet_ntop(AF_INET6, &v6prefix->sin6_addr, buf, sizeof(buf));
Ken Chen594fc942019-04-18 18:11:15 +0800464 LOG(VERBOSE) << __func__ << ": NAT64 prefix: " << buf;
Mike Yu19108d52018-11-15 21:58:19 +0800465 inet_ntop(AF_INET6, ia6, buf, sizeof(buf));
Ken Chen594fc942019-04-18 18:11:15 +0800466 LOG(VERBOSE) << __func__ << ": DNS64 Synthesized AAAA record: " << buf;
Mike Yu19108d52018-11-15 21:58:19 +0800467 }
468 }
469 hp->h_addrtype = AF_INET6;
470 hp->h_length = sizeof(in6_addr);
471
Bernie Innocenti3952ccc2019-03-03 19:39:53 +0900472 logDnsQueryResult(hp);
Mike Yu19108d52018-11-15 21:58:19 +0800473 return true;
474}
475
476bool synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix& prefix, addrinfo* result) {
477 if (result == nullptr) return false;
478 if (!onlyNonSpecialUseIPv4Addresses(result)) return false;
479 if (!isValidNat64Prefix(prefix)) return false;
480
481 struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
482 struct sockaddr_in6* v6prefix = (struct sockaddr_in6*) &ss;
483 for (addrinfo* ai = result; ai; ai = ai->ai_next) {
484 struct sockaddr_in sinOriginal = *(struct sockaddr_in*) ai->ai_addr;
485 struct sockaddr_in6* sin6 = (struct sockaddr_in6*) ai->ai_addr;
486 memset(sin6, 0, sizeof(sockaddr_in6));
487
488 // Synthesize /96 NAT64 prefix in place. The space has reserved by get_ai() in
489 // system/netd/resolv/getaddrinfo.cpp.
490 sin6->sin6_addr = v6prefix->sin6_addr;
491 sin6->sin6_addr.s6_addr32[3] = sinOriginal.sin_addr.s_addr;
492 sin6->sin6_family = AF_INET6;
493 sin6->sin6_port = sinOriginal.sin_port;
494 ai->ai_addrlen = sizeof(struct sockaddr_in6);
495 ai->ai_family = AF_INET6;
496
Ken Chen594fc942019-04-18 18:11:15 +0800497 if (WOULD_LOG(VERBOSE)) {
Mike Yu19108d52018-11-15 21:58:19 +0800498 char buf[INET6_ADDRSTRLEN]; // big enough for either IPv4 or IPv6
499 inet_ntop(AF_INET, &sinOriginal.sin_addr.s_addr, buf, sizeof(buf));
Ken Chen594fc942019-04-18 18:11:15 +0800500 LOG(VERBOSE) << __func__ << ": DNS A record: " << buf;
Mike Yu19108d52018-11-15 21:58:19 +0800501 inet_ntop(AF_INET6, &v6prefix->sin6_addr, buf, sizeof(buf));
Ken Chen594fc942019-04-18 18:11:15 +0800502 LOG(VERBOSE) << __func__ << ": NAT64 prefix: " << buf;
Mike Yu19108d52018-11-15 21:58:19 +0800503 inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof(buf));
Ken Chen594fc942019-04-18 18:11:15 +0800504 LOG(VERBOSE) << __func__ << ": DNS64 Synthesized AAAA record: " << buf;
Mike Yu19108d52018-11-15 21:58:19 +0800505 }
506 }
Bernie Innocenti3952ccc2019-03-03 19:39:53 +0900507 logDnsQueryResult(result);
Mike Yu19108d52018-11-15 21:58:19 +0800508 return true;
509}
510
511bool getDns64Prefix(unsigned netId, netdutils::IPPrefix* prefix) {
Luke Huang5bd827c2019-03-14 16:10:04 +0800512 return !gDnsResolv->resolverCtrl.getPrefix64(netId, prefix);
Mike Yu19108d52018-11-15 21:58:19 +0800513}
514
Mike Yu04f1d482019-08-08 11:09:32 +0800515std::string makeThreadName(unsigned netId, uint32_t uid) {
516 // The maximum of netId and app_id are 5-digit numbers.
517 return android::base::StringPrintf("Dns_%u_%u", netId, multiuser_get_app_id(uid));
518}
519
Mike Yu19108d52018-11-15 21:58:19 +0800520} // namespace
521
Mike Yu19108d52018-11-15 21:58:19 +0800522DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) {
523 registerCmd(new GetAddrInfoCmd());
524 registerCmd(new GetHostByAddrCmd());
525 registerCmd(new GetHostByNameCmd());
526 registerCmd(new ResNSendCommand());
Luke Huang9807e6b2019-05-20 16:17:12 +0800527 registerCmd(new GetDnsNetIdCommand());
Mike Yu19108d52018-11-15 21:58:19 +0800528}
529
530DnsProxyListener::GetAddrInfoHandler::GetAddrInfoHandler(SocketClient* c, char* host, char* service,
531 addrinfo* hints,
532 const android_net_context& netcontext)
533 : mClient(c), mHost(host), mService(service), mHints(hints), mNetContext(netcontext) {}
534
535DnsProxyListener::GetAddrInfoHandler::~GetAddrInfoHandler() {
536 free(mHost);
537 free(mService);
538 free(mHints);
539}
540
541static bool sendBE32(SocketClient* c, uint32_t data) {
542 uint32_t be_data = htonl(data);
543 return c->sendData(&be_data, sizeof(be_data)) == 0;
544}
545
546// Sends 4 bytes of big-endian length, followed by the data.
547// Returns true on success.
548static bool sendLenAndData(SocketClient* c, const int len, const void* data) {
549 return sendBE32(c, len) && (len == 0 || c->sendData(data, len) == 0);
550}
551
552// Returns true on success
553static bool sendhostent(SocketClient* c, hostent* hp) {
554 bool success = true;
555 int i;
556 if (hp->h_name != nullptr) {
557 success &= sendLenAndData(c, strlen(hp->h_name)+1, hp->h_name);
558 } else {
559 success &= sendLenAndData(c, 0, "") == 0;
560 }
561
562 for (i=0; hp->h_aliases[i] != nullptr; i++) {
563 success &= sendLenAndData(c, strlen(hp->h_aliases[i])+1, hp->h_aliases[i]);
564 }
565 success &= sendLenAndData(c, 0, ""); // null to indicate we're done
566
567 uint32_t buf = htonl(hp->h_addrtype);
568 success &= c->sendData(&buf, sizeof(buf)) == 0;
569
570 buf = htonl(hp->h_length);
571 success &= c->sendData(&buf, sizeof(buf)) == 0;
572
573 for (i=0; hp->h_addr_list[i] != nullptr; i++) {
574 success &= sendLenAndData(c, 16, hp->h_addr_list[i]);
575 }
576 success &= sendLenAndData(c, 0, ""); // null to indicate we're done
577 return success;
578}
579
580static bool sendaddrinfo(SocketClient* c, addrinfo* ai) {
581 // struct addrinfo {
582 // int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
583 // int ai_family; /* PF_xxx */
584 // int ai_socktype; /* SOCK_xxx */
585 // int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
586 // socklen_t ai_addrlen; /* length of ai_addr */
587 // char *ai_canonname; /* canonical name for hostname */
588 // struct sockaddr *ai_addr; /* binary address */
589 // struct addrinfo *ai_next; /* next structure in linked list */
590 // };
591
592 // Write the struct piece by piece because we might be a 64-bit netd
593 // talking to a 32-bit process.
594 bool success =
595 sendBE32(c, ai->ai_flags) &&
596 sendBE32(c, ai->ai_family) &&
597 sendBE32(c, ai->ai_socktype) &&
598 sendBE32(c, ai->ai_protocol);
599 if (!success) {
600 return false;
601 }
602
603 // ai_addrlen and ai_addr.
604 if (!sendLenAndData(c, ai->ai_addrlen, ai->ai_addr)) {
605 return false;
606 }
607
608 // strlen(ai_canonname) and ai_canonname.
609 if (!sendLenAndData(c, ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0, ai->ai_canonname)) {
610 return false;
611 }
612
613 return true;
614}
615
lifr94981782019-05-17 21:15:19 +0800616void DnsProxyListener::GetAddrInfoHandler::doDns64Synthesis(int32_t* rv, addrinfo** res,
617 NetworkDnsEventReported* event) {
Mike Yu19108d52018-11-15 21:58:19 +0800618 if (mHost == nullptr) return;
619
620 const bool ipv6WantedButNoData = (mHints && mHints->ai_family == AF_INET6 && *rv == EAI_NODATA);
621 const bool unspecWantedButNoIPv6 =
622 ((!mHints || mHints->ai_family == AF_UNSPEC) && *rv == 0 && onlyIPv4Answers(*res));
623
624 if (!ipv6WantedButNoData && !unspecWantedButNoIPv6) {
625 return;
626 }
627
628 netdutils::IPPrefix prefix{};
629 if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
630 return;
631 }
632
633 if (ipv6WantedButNoData) {
634 // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis
635 const uid_t uid = mClient->getUid();
636 if (queryLimiter.start(uid)) {
637 mHints->ai_family = AF_INET;
638 // Don't need to do freeaddrinfo(res) before starting new DNS lookup because previous
639 // DNS lookup is failed with error EAI_NODATA.
Luke Huangd8ac4752019-06-18 17:05:47 +0800640 *rv = resolv_getaddrinfo(mHost, mService, mHints, &mNetContext, res, event);
Mike Yu19108d52018-11-15 21:58:19 +0800641 queryLimiter.finish(uid);
642 if (*rv) {
643 *rv = EAI_NODATA; // return original error code
644 return;
645 }
646 } else {
Ken Chenffc224a2019-03-19 17:41:28 +0800647 LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached";
Mike Yu19108d52018-11-15 21:58:19 +0800648 return;
649 }
650 }
651
652 if (!synthesizeNat64PrefixWithARecord(prefix, *res)) {
653 if (ipv6WantedButNoData) {
654 // If caller wants IPv6 answers but no data and failed to synthesize IPv6 answers,
655 // don't return the IPv4 answers.
656 *rv = EAI_NODATA; // return original error code
657 if (*res) {
658 freeaddrinfo(*res);
659 *res = nullptr;
660 }
661 }
662 }
663}
664
665void DnsProxyListener::GetAddrInfoHandler::run() {
Ken Chenffc224a2019-03-19 17:41:28 +0800666 LOG(DEBUG) << "GetAddrInfoHandler::run: {" << mNetContext.app_netid << " "
667 << mNetContext.app_mark << " " << mNetContext.dns_netid << " "
668 << mNetContext.dns_mark << " " << mNetContext.uid << " " << mNetContext.flags << "}";
Mike Yu19108d52018-11-15 21:58:19 +0800669
670 addrinfo* result = nullptr;
671 Stopwatch s;
672 maybeFixupNetContext(&mNetContext);
673 const uid_t uid = mClient->getUid();
674 int32_t rv = 0;
lifr94981782019-05-17 21:15:19 +0800675 NetworkDnsEventReported event;
676 initDnsEvent(&event);
Mike Yu19108d52018-11-15 21:58:19 +0800677 if (queryLimiter.start(uid)) {
lifr94981782019-05-17 21:15:19 +0800678 rv = resolv_getaddrinfo(mHost, mService, mHints, &mNetContext, &result, &event);
Mike Yu19108d52018-11-15 21:58:19 +0800679 queryLimiter.finish(uid);
680 } else {
681 // Note that this error code is currently not passed down to the client.
682 // android_getaddrinfo_proxy() returns EAI_NODATA on any error.
683 rv = EAI_MEMORY;
Ken Chenffc224a2019-03-19 17:41:28 +0800684 LOG(ERROR) << "GetAddrInfoHandler::run: from UID " << uid
685 << ", max concurrent queries reached";
Mike Yu19108d52018-11-15 21:58:19 +0800686 }
687
lifr94981782019-05-17 21:15:19 +0800688 doDns64Synthesis(&rv, &result, &event);
689 const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
690 event.set_latency_micros(latencyUs);
691 event.set_event_type(EVENT_GETADDRINFO);
692 event.set_hints_ai_flags((mHints ? mHints->ai_flags : 0));
Mike Yu19108d52018-11-15 21:58:19 +0800693
694 if (rv) {
695 // getaddrinfo failed
696 mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, &rv, sizeof(rv));
697 } else {
698 bool success = !mClient->sendCode(ResponseCode::DnsProxyQueryResult);
699 addrinfo* ai = result;
700 while (ai && success) {
701 success = sendBE32(mClient, 1) && sendaddrinfo(mClient, ai);
702 ai = ai->ai_next;
703 }
704 success = success && sendBE32(mClient, 0);
705 if (!success) {
Ken Chenffc224a2019-03-19 17:41:28 +0800706 LOG(WARNING) << "GetAddrInfoHandler::run: Error writing DNS result to client";
Mike Yu19108d52018-11-15 21:58:19 +0800707 }
708 }
709 std::vector<std::string> ip_addrs;
710 const int total_ip_addr_count = extractGetAddrInfoAnswers(result, &ip_addrs);
lifr94981782019-05-17 21:15:19 +0800711 reportDnsEvent(INetdEventListener::EVENT_GETADDRINFO, mNetContext, latencyUs, rv, event, mHost,
712 ip_addrs, total_ip_addr_count);
Mike Yu19108d52018-11-15 21:58:19 +0800713 freeaddrinfo(result);
714 mClient->decRef();
715}
716
Mike Yu04f1d482019-08-08 11:09:32 +0800717std::string DnsProxyListener::GetAddrInfoHandler::threadName() {
718 return makeThreadName(mNetContext.dns_netid, mClient->getUid());
719}
720
Mike Yu19108d52018-11-15 21:58:19 +0800721namespace {
722
723void addIpAddrWithinLimit(std::vector<std::string>* ip_addrs, const sockaddr* addr,
724 socklen_t addrlen) {
725 // ipAddresses array is limited to first INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT
726 // addresses for A and AAAA. Total count of addresses is provided, to be able to tell whether
727 // some addresses didn't get logged.
728 if (ip_addrs->size() < INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT) {
729 char ip_addr[INET6_ADDRSTRLEN];
730 if (getnameinfo(addr, addrlen, ip_addr, sizeof(ip_addr), nullptr, 0, NI_NUMERICHOST) == 0) {
731 ip_addrs->push_back(std::string(ip_addr));
732 }
733 }
734}
735
736} // namespace
737
738DnsProxyListener::GetAddrInfoCmd::GetAddrInfoCmd() : FrameworkCommand("getaddrinfo") {}
739
740int DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient *cli,
741 int argc, char **argv) {
Bernie Innocenti3952ccc2019-03-03 19:39:53 +0900742 logArguments(argc, argv);
Mike Yu19108d52018-11-15 21:58:19 +0800743
744 if (argc != 8) {
745 char* msg = nullptr;
746 asprintf( &msg, "Invalid number of arguments to getaddrinfo: %i", argc);
Ken Chenffc224a2019-03-19 17:41:28 +0800747 LOG(WARNING) << "GetAddrInfoCmd::runCommand: " << (msg ? msg : "null");
Mike Yu19108d52018-11-15 21:58:19 +0800748 cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
749 free(msg);
750 return -1;
751 }
752
753 char* name = argv[1];
754 if (strcmp("^", name) == 0) {
755 name = nullptr;
756 } else {
757 name = strdup(name);
758 }
759
760 char* service = argv[2];
761 if (strcmp("^", service) == 0) {
762 service = nullptr;
763 } else {
764 service = strdup(service);
765 }
766
767 addrinfo* hints = nullptr;
768 int ai_flags = strtol(argv[3], nullptr, 10);
769 int ai_family = strtol(argv[4], nullptr, 10);
770 int ai_socktype = strtol(argv[5], nullptr, 10);
771 int ai_protocol = strtol(argv[6], nullptr, 10);
772 unsigned netId = strtoul(argv[7], nullptr, 10);
773 const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
774 const uid_t uid = cli->getUid();
775
776 android_net_context netcontext;
Luke Huang36796f32019-03-13 02:54:45 +0800777 gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
Mike Yu19108d52018-11-15 21:58:19 +0800778
779 if (useLocalNameservers) {
780 netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
781 }
782
783 if (ai_flags != -1 || ai_family != -1 ||
784 ai_socktype != -1 || ai_protocol != -1) {
785 hints = (addrinfo*) calloc(1, sizeof(addrinfo));
786 hints->ai_flags = ai_flags;
787 hints->ai_family = ai_family;
788 hints->ai_socktype = ai_socktype;
789 hints->ai_protocol = ai_protocol;
790 }
791
Mike Yu19108d52018-11-15 21:58:19 +0800792 DnsProxyListener::GetAddrInfoHandler* handler =
793 new DnsProxyListener::GetAddrInfoHandler(cli, name, service, hints, netcontext);
794 tryThreadOrError(cli, handler);
795 return 0;
796}
797
798/*******************************************************
Bernie Innocenti3952ccc2019-03-03 19:39:53 +0900799 * ResNSendCommand *
Mike Yu19108d52018-11-15 21:58:19 +0800800 *******************************************************/
801DnsProxyListener::ResNSendCommand::ResNSendCommand() : FrameworkCommand("resnsend") {}
802
803int DnsProxyListener::ResNSendCommand::runCommand(SocketClient* cli, int argc, char** argv) {
Bernie Innocenti3952ccc2019-03-03 19:39:53 +0900804 logArguments(argc, argv);
Mike Yu19108d52018-11-15 21:58:19 +0800805
806 const uid_t uid = cli->getUid();
807 if (argc != 4) {
Ken Chenffc224a2019-03-19 17:41:28 +0800808 LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
809 << ", invalid number of arguments to resnsend: " << argc;
Mike Yu19108d52018-11-15 21:58:19 +0800810 sendBE32(cli, -EINVAL);
811 return -1;
812 }
813
814 unsigned netId;
815 if (!simpleStrtoul(argv[1], &netId)) {
Ken Chenffc224a2019-03-19 17:41:28 +0800816 LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
817 << ", invalid netId";
Mike Yu19108d52018-11-15 21:58:19 +0800818 sendBE32(cli, -EINVAL);
819 return -1;
820 }
821
822 uint32_t flags;
823 if (!simpleStrtoul(argv[2], &flags)) {
Ken Chenffc224a2019-03-19 17:41:28 +0800824 LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
825 << ", invalid flags";
Mike Yu19108d52018-11-15 21:58:19 +0800826 sendBE32(cli, -EINVAL);
827 return -1;
828 }
829
Luke Huangcb346132019-05-14 22:15:06 +0800830 const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
831
Mike Yu19108d52018-11-15 21:58:19 +0800832 android_net_context netcontext;
Luke Huang36796f32019-03-13 02:54:45 +0800833 gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
Luke Huangcb346132019-05-14 22:15:06 +0800834
835 if (useLocalNameservers) {
Mike Yu19108d52018-11-15 21:58:19 +0800836 netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
837 }
838
839 DnsProxyListener::ResNSendHandler* handler =
840 new DnsProxyListener::ResNSendHandler(cli, argv[3], flags, netcontext);
841 tryThreadOrError(cli, handler);
842 return 0;
843}
844
845DnsProxyListener::ResNSendHandler::ResNSendHandler(SocketClient* c, std::string msg, uint32_t flags,
846 const android_net_context& netcontext)
847 : mClient(c), mMsg(std::move(msg)), mFlags(flags), mNetContext(netcontext) {}
848
849DnsProxyListener::ResNSendHandler::~ResNSendHandler() {
850 mClient->decRef();
851}
852
853void DnsProxyListener::ResNSendHandler::run() {
Ken Chenffc224a2019-03-19 17:41:28 +0800854 LOG(DEBUG) << "ResNSendHandler::run: " << mFlags << " / {" << mNetContext.app_netid << " "
855 << mNetContext.app_mark << " " << mNetContext.dns_netid << " "
856 << mNetContext.dns_mark << " " << mNetContext.uid << " " << mNetContext.flags << "}";
Mike Yu19108d52018-11-15 21:58:19 +0800857
858 Stopwatch s;
859 maybeFixupNetContext(&mNetContext);
860
861 // Decode
862 std::vector<uint8_t> msg(MAXPACKET, 0);
863
864 // Max length of mMsg is less than 1024 since the CMD_BUF_SIZE in FrameworkListener is 1024
865 int msgLen = b64_pton(mMsg.c_str(), msg.data(), MAXPACKET);
866 if (msgLen == -1) {
867 // Decode fail
868 sendBE32(mClient, -EILSEQ);
869 return;
870 }
871
872 const uid_t uid = mClient->getUid();
873 int rr_type = 0;
874 std::string rr_name;
Luke Huang70931aa2019-01-31 11:57:41 +0800875 uint16_t original_query_id = 0;
Mike Yu19108d52018-11-15 21:58:19 +0800876
877 // TODO: Handle the case which is msg contains more than one query
Luke Huang70931aa2019-01-31 11:57:41 +0800878 if (!parseQuery(msg.data(), msgLen, &original_query_id, &rr_type, &rr_name) ||
879 !setQueryId(msg.data(), msgLen, arc4random_uniform(65536))) {
Mike Yu19108d52018-11-15 21:58:19 +0800880 // If the query couldn't be parsed, block the request.
Ken Chenffc224a2019-03-19 17:41:28 +0800881 LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid << ", invalid query";
Mike Yu19108d52018-11-15 21:58:19 +0800882 sendBE32(mClient, -EINVAL);
883 return;
884 }
885
886 // Send DNS query
887 std::vector<uint8_t> ansBuf(MAXPACKET, 0);
888 int arcode, nsendAns = -1;
lifr94981782019-05-17 21:15:19 +0800889 NetworkDnsEventReported event;
890 initDnsEvent(&event);
Mike Yu19108d52018-11-15 21:58:19 +0800891 if (queryLimiter.start(uid)) {
892 nsendAns = resolv_res_nsend(&mNetContext, msg.data(), msgLen, ansBuf.data(), MAXPACKET,
lifr94981782019-05-17 21:15:19 +0800893 &arcode, static_cast<ResNsendFlags>(mFlags), &event);
Mike Yu19108d52018-11-15 21:58:19 +0800894 queryLimiter.finish(uid);
895 } else {
Ken Chenffc224a2019-03-19 17:41:28 +0800896 LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid
897 << ", max concurrent queries reached";
Mike Yu19108d52018-11-15 21:58:19 +0800898 nsendAns = -EBUSY;
899 }
900
lifr94981782019-05-17 21:15:19 +0800901 const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
902 event.set_latency_micros(latencyUs);
903 event.set_event_type(EVENT_RES_NSEND);
904 event.set_res_nsend_flags(static_cast<ResNsendFlags>(mFlags));
Mike Yu19108d52018-11-15 21:58:19 +0800905
906 // Fail, send -errno
907 if (nsendAns < 0) {
908 sendBE32(mClient, nsendAns);
909 if (rr_type == ns_t_a || rr_type == ns_t_aaaa) {
910 reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs,
lifr94981782019-05-17 21:15:19 +0800911 resNSendToAiError(nsendAns, arcode), event, rr_name);
Mike Yu19108d52018-11-15 21:58:19 +0800912 }
913 return;
914 }
915
916 // Send rcode
917 if (!sendBE32(mClient, arcode)) {
Ken Chenffc224a2019-03-19 17:41:28 +0800918 PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send rcode to uid " << uid;
Mike Yu19108d52018-11-15 21:58:19 +0800919 return;
920 }
921
Luke Huang70931aa2019-01-31 11:57:41 +0800922 // Restore query id and send answer
923 if (!setQueryId(ansBuf.data(), nsendAns, original_query_id) ||
924 !sendLenAndData(mClient, nsendAns, ansBuf.data())) {
Ken Chenffc224a2019-03-19 17:41:28 +0800925 PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send answer to uid " << uid;
Mike Yu19108d52018-11-15 21:58:19 +0800926 return;
927 }
928
929 if (rr_type == ns_t_a || rr_type == ns_t_aaaa) {
930 std::vector<std::string> ip_addrs;
931 const int total_ip_addr_count =
932 extractResNsendAnswers((uint8_t*) ansBuf.data(), nsendAns, rr_type, &ip_addrs);
933 reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs,
lifr94981782019-05-17 21:15:19 +0800934 resNSendToAiError(nsendAns, arcode), event, rr_name, ip_addrs,
lifr9b87e362019-05-08 13:00:14 +0800935 total_ip_addr_count);
Mike Yu19108d52018-11-15 21:58:19 +0800936 }
937}
938
Mike Yu04f1d482019-08-08 11:09:32 +0800939std::string DnsProxyListener::ResNSendHandler::threadName() {
940 return makeThreadName(mNetContext.dns_netid, mClient->getUid());
941}
942
Luke Huang9807e6b2019-05-20 16:17:12 +0800943namespace {
944
945bool sendCodeAndBe32(SocketClient* c, int code, int data) {
Luke Huang0d592bc2019-05-25 18:24:03 +0800946 return !c->sendCode(code) && sendBE32(c, data);
Luke Huang9807e6b2019-05-20 16:17:12 +0800947}
948
949} // namespace
950
951/*******************************************************
952 * GetDnsNetId *
953 *******************************************************/
954DnsProxyListener::GetDnsNetIdCommand::GetDnsNetIdCommand() : FrameworkCommand("getdnsnetid") {}
955
956int DnsProxyListener::GetDnsNetIdCommand::runCommand(SocketClient* cli, int argc, char** argv) {
957 logArguments(argc, argv);
958
959 const uid_t uid = cli->getUid();
960 if (argc != 2) {
961 LOG(WARNING) << "GetDnsNetIdCommand::runCommand: getdnsnetid: from UID " << uid
962 << ", invalid number of arguments to getdnsnetid: " << argc;
963 sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, -EINVAL);
964 return -1;
965 }
966
967 unsigned netId;
968 if (!simpleStrtoul(argv[1], &netId)) {
969 LOG(WARNING) << "GetDnsNetIdCommand::runCommand: getdnsnetid: from UID " << uid
970 << ", invalid netId";
971 sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, -EINVAL);
972 return -1;
973 }
974
Luke Huang0d592bc2019-05-25 18:24:03 +0800975 const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
Luke Huang9807e6b2019-05-20 16:17:12 +0800976 android_net_context netcontext;
977 gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
978
Luke Huang0d592bc2019-05-25 18:24:03 +0800979 if (useLocalNameservers) {
980 netcontext.app_netid |= NETID_USE_LOCAL_NAMESERVERS;
981 }
982
983 return sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, netcontext.app_netid) ? 0 : -1;
Luke Huang9807e6b2019-05-20 16:17:12 +0800984}
985
Mike Yu19108d52018-11-15 21:58:19 +0800986/*******************************************************
987 * GetHostByName *
988 *******************************************************/
989DnsProxyListener::GetHostByNameCmd::GetHostByNameCmd() : FrameworkCommand("gethostbyname") {}
990
991int DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient *cli,
992 int argc, char **argv) {
Bernie Innocenti3952ccc2019-03-03 19:39:53 +0900993 logArguments(argc, argv);
Mike Yu19108d52018-11-15 21:58:19 +0800994
995 if (argc != 4) {
996 char* msg = nullptr;
997 asprintf(&msg, "Invalid number of arguments to gethostbyname: %i", argc);
Ken Chenffc224a2019-03-19 17:41:28 +0800998 LOG(WARNING) << "GetHostByNameCmd::runCommand: " << (msg ? msg : "null");
Mike Yu19108d52018-11-15 21:58:19 +0800999 cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
1000 free(msg);
1001 return -1;
1002 }
1003
1004 uid_t uid = cli->getUid();
1005 unsigned netId = strtoul(argv[1], nullptr, 10);
1006 const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
1007 char* name = argv[2];
1008 int af = strtol(argv[3], nullptr, 10);
1009
1010 if (strcmp(name, "^") == 0) {
1011 name = nullptr;
1012 } else {
1013 name = strdup(name);
1014 }
1015
1016 android_net_context netcontext;
Luke Huang36796f32019-03-13 02:54:45 +08001017 gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
Mike Yu19108d52018-11-15 21:58:19 +08001018
1019 if (useLocalNameservers) {
1020 netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
1021 }
1022
1023 DnsProxyListener::GetHostByNameHandler* handler =
1024 new DnsProxyListener::GetHostByNameHandler(cli, name, af, netcontext);
1025 tryThreadOrError(cli, handler);
1026 return 0;
1027}
1028
1029DnsProxyListener::GetHostByNameHandler::GetHostByNameHandler(SocketClient* c, char* name, int af,
1030 const android_net_context& netcontext)
1031 : mClient(c), mName(name), mAf(af), mNetContext(netcontext) {}
1032
1033DnsProxyListener::GetHostByNameHandler::~GetHostByNameHandler() {
1034 free(mName);
1035}
1036
lifr94981782019-05-17 21:15:19 +08001037void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, struct hostent** hpp,
1038 NetworkDnsEventReported* event) {
Mike Yu19108d52018-11-15 21:58:19 +08001039 // Don't have to consider family AF_UNSPEC case because gethostbyname{, 2} only supports
1040 // family AF_INET or AF_INET6.
1041 const bool ipv6WantedButNoData = (mAf == AF_INET6 && *rv == EAI_NODATA);
1042
1043 if (!ipv6WantedButNoData) {
1044 return;
1045 }
1046
1047 netdutils::IPPrefix prefix{};
1048 if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
1049 return;
1050 }
1051
1052 // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis
1053 const uid_t uid = mClient->getUid();
1054 if (queryLimiter.start(uid)) {
lifr94981782019-05-17 21:15:19 +08001055 *rv = android_gethostbynamefornetcontext(mName, AF_INET, &mNetContext, hpp, event);
Mike Yu19108d52018-11-15 21:58:19 +08001056 queryLimiter.finish(uid);
1057 if (*rv) {
1058 *rv = EAI_NODATA; // return original error code
1059 return;
1060 }
1061 } else {
Ken Chenffc224a2019-03-19 17:41:28 +08001062 LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached";
Mike Yu19108d52018-11-15 21:58:19 +08001063 return;
1064 }
1065
1066 if (!synthesizeNat64PrefixWithARecord(prefix, *hpp)) {
1067 // If caller wants IPv6 answers but no data and failed to synthesize IPv4 answers,
1068 // don't return the IPv4 answers.
1069 *hpp = nullptr;
1070 }
1071}
1072
1073void DnsProxyListener::GetHostByNameHandler::run() {
Mike Yu19108d52018-11-15 21:58:19 +08001074 Stopwatch s;
1075 maybeFixupNetContext(&mNetContext);
1076 const uid_t uid = mClient->getUid();
1077 hostent* hp = nullptr;
1078 int32_t rv = 0;
lifr94981782019-05-17 21:15:19 +08001079 NetworkDnsEventReported event;
1080 initDnsEvent(&event);
Mike Yu19108d52018-11-15 21:58:19 +08001081 if (queryLimiter.start(uid)) {
lifr94981782019-05-17 21:15:19 +08001082 rv = android_gethostbynamefornetcontext(mName, mAf, &mNetContext, &hp, &event);
Mike Yu19108d52018-11-15 21:58:19 +08001083 queryLimiter.finish(uid);
1084 } else {
1085 rv = EAI_MEMORY;
Ken Chenffc224a2019-03-19 17:41:28 +08001086 LOG(ERROR) << "GetHostByNameHandler::run: from UID " << uid
1087 << ", max concurrent queries reached";
Mike Yu19108d52018-11-15 21:58:19 +08001088 }
1089
lifr94981782019-05-17 21:15:19 +08001090 doDns64Synthesis(&rv, &hp, &event);
1091 const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
1092 event.set_latency_micros(latencyUs);
1093 event.set_event_type(EVENT_GETHOSTBYNAME);
1094
Ken Chenffc224a2019-03-19 17:41:28 +08001095 LOG(DEBUG) << "GetHostByNameHandler::run: errno: " << (hp ? "success" : strerror(errno));
Mike Yu19108d52018-11-15 21:58:19 +08001096
1097 bool success = true;
1098 if (hp) {
1099 // hp is not nullptr iff. rv is 0.
1100 success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
1101 success &= sendhostent(mClient, hp);
1102 } else {
1103 success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, nullptr, 0) == 0;
1104 }
1105
1106 if (!success) {
Ken Chenffc224a2019-03-19 17:41:28 +08001107 LOG(WARNING) << "GetHostByNameHandler::run: Error writing DNS result to client";
Mike Yu19108d52018-11-15 21:58:19 +08001108 }
1109
1110 std::vector<std::string> ip_addrs;
1111 const int total_ip_addr_count = extractGetHostByNameAnswers(hp, &ip_addrs);
lifr94981782019-05-17 21:15:19 +08001112 reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYNAME, mNetContext, latencyUs, rv, event,
lifr9b87e362019-05-08 13:00:14 +08001113 mName, ip_addrs, total_ip_addr_count);
Mike Yu19108d52018-11-15 21:58:19 +08001114 mClient->decRef();
1115}
1116
Mike Yu04f1d482019-08-08 11:09:32 +08001117std::string DnsProxyListener::GetHostByNameHandler::threadName() {
1118 return makeThreadName(mNetContext.dns_netid, mClient->getUid());
1119}
Mike Yu19108d52018-11-15 21:58:19 +08001120
1121/*******************************************************
1122 * GetHostByAddr *
1123 *******************************************************/
1124DnsProxyListener::GetHostByAddrCmd::GetHostByAddrCmd() : FrameworkCommand("gethostbyaddr") {}
1125
1126int DnsProxyListener::GetHostByAddrCmd::runCommand(SocketClient *cli,
1127 int argc, char **argv) {
Bernie Innocenti3952ccc2019-03-03 19:39:53 +09001128 logArguments(argc, argv);
Mike Yu19108d52018-11-15 21:58:19 +08001129
1130 if (argc != 5) {
1131 char* msg = nullptr;
1132 asprintf(&msg, "Invalid number of arguments to gethostbyaddr: %i", argc);
Ken Chenffc224a2019-03-19 17:41:28 +08001133 LOG(WARNING) << "GetHostByAddrCmd::runCommand: " << (msg ? msg : "null");
Mike Yu19108d52018-11-15 21:58:19 +08001134 cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
1135 free(msg);
1136 return -1;
1137 }
1138
1139 char* addrStr = argv[1];
1140 int addrLen = strtol(argv[2], nullptr, 10);
1141 int addrFamily = strtol(argv[3], nullptr, 10);
1142 uid_t uid = cli->getUid();
1143 unsigned netId = strtoul(argv[4], nullptr, 10);
1144 const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
1145
1146 void* addr = malloc(sizeof(in6_addr));
1147 errno = 0;
1148 int result = inet_pton(addrFamily, addrStr, addr);
1149 if (result <= 0) {
1150 char* msg = nullptr;
1151 asprintf(&msg, "inet_pton(\"%s\") failed %s", addrStr, strerror(errno));
Ken Chenffc224a2019-03-19 17:41:28 +08001152 LOG(WARNING) << "GetHostByAddrCmd::runCommand: " << (msg ? msg : "null");
Mike Yu19108d52018-11-15 21:58:19 +08001153 cli->sendMsg(ResponseCode::OperationFailed, msg, false);
1154 free(addr);
1155 free(msg);
1156 return -1;
1157 }
1158
1159 android_net_context netcontext;
Luke Huang36796f32019-03-13 02:54:45 +08001160 gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
Mike Yu19108d52018-11-15 21:58:19 +08001161
1162 if (useLocalNameservers) {
1163 netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
1164 }
1165
1166 DnsProxyListener::GetHostByAddrHandler* handler = new DnsProxyListener::GetHostByAddrHandler(
1167 cli, addr, addrLen, addrFamily, netcontext);
1168 tryThreadOrError(cli, handler);
1169 return 0;
1170}
1171
1172DnsProxyListener::GetHostByAddrHandler::GetHostByAddrHandler(SocketClient* c, void* address,
1173 int addressLen, int addressFamily,
1174 const android_net_context& netcontext)
1175 : mClient(c),
1176 mAddress(address),
1177 mAddressLen(addressLen),
1178 mAddressFamily(addressFamily),
1179 mNetContext(netcontext) {}
1180
1181DnsProxyListener::GetHostByAddrHandler::~GetHostByAddrHandler() {
1182 free(mAddress);
1183}
1184
lifr94981782019-05-17 21:15:19 +08001185void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(struct hostent** hpp,
1186 NetworkDnsEventReported* event) {
Mike Yu19108d52018-11-15 21:58:19 +08001187 if (*hpp != nullptr || mAddressFamily != AF_INET6 || !mAddress) {
1188 return;
1189 }
1190
1191 netdutils::IPPrefix prefix{};
1192 if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
1193 return;
1194 }
1195
1196 if (!isValidNat64Prefix(prefix)) {
1197 return;
1198 }
1199
1200 struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
1201 struct sockaddr_in6* v6prefix = (struct sockaddr_in6*) &ss;
1202 struct in6_addr v6addr = *(in6_addr*) mAddress;
1203 // Check if address has NAT64 prefix. Only /96 IPv6 NAT64 prefixes are supported
1204 if ((v6addr.s6_addr32[0] != v6prefix->sin6_addr.s6_addr32[0]) ||
1205 (v6addr.s6_addr32[1] != v6prefix->sin6_addr.s6_addr32[1]) ||
1206 (v6addr.s6_addr32[2] != v6prefix->sin6_addr.s6_addr32[2])) {
1207 return;
1208 }
1209
1210 const uid_t uid = mClient->getUid();
1211 if (queryLimiter.start(uid)) {
1212 // Remove NAT64 prefix and do reverse DNS query
1213 struct in_addr v4addr = {.s_addr = v6addr.s6_addr32[3]};
lifr94981782019-05-17 21:15:19 +08001214 android_gethostbyaddrfornetcontext(&v4addr, sizeof(v4addr), AF_INET, &mNetContext, hpp,
1215 event);
Mike Yu19108d52018-11-15 21:58:19 +08001216 queryLimiter.finish(uid);
1217 if (*hpp) {
1218 // Replace IPv4 address with original queried IPv6 address in place. The space has
waynema067e9842019-03-08 19:13:41 +08001219 // reserved by dns_gethtbyaddr() and netbsd_gethostent_r() in
Mike Yu19108d52018-11-15 21:58:19 +08001220 // system/netd/resolv/gethnamaddr.cpp.
1221 // Note that android_gethostbyaddrfornetcontext returns only one entry in result.
1222 memcpy((*hpp)->h_addr_list[0], &v6addr, sizeof(v6addr));
1223 (*hpp)->h_addrtype = AF_INET6;
1224 (*hpp)->h_length = sizeof(struct in6_addr);
1225 }
1226 } else {
Ken Chenffc224a2019-03-19 17:41:28 +08001227 LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached";
Mike Yu19108d52018-11-15 21:58:19 +08001228 }
1229}
1230
1231void DnsProxyListener::GetHostByAddrHandler::run() {
Mike Yu19108d52018-11-15 21:58:19 +08001232 Stopwatch s;
1233 maybeFixupNetContext(&mNetContext);
1234 const uid_t uid = mClient->getUid();
1235 hostent* hp = nullptr;
1236 int32_t rv = 0;
lifr94981782019-05-17 21:15:19 +08001237 NetworkDnsEventReported event;
1238 initDnsEvent(&event);
Mike Yu19108d52018-11-15 21:58:19 +08001239 if (queryLimiter.start(uid)) {
lifr94981782019-05-17 21:15:19 +08001240 rv = android_gethostbyaddrfornetcontext(mAddress, mAddressLen, mAddressFamily, &mNetContext,
1241 &hp, &event);
Mike Yu19108d52018-11-15 21:58:19 +08001242 queryLimiter.finish(uid);
1243 } else {
1244 rv = EAI_MEMORY;
Ken Chenffc224a2019-03-19 17:41:28 +08001245 LOG(ERROR) << "GetHostByAddrHandler::run: from UID " << uid
1246 << ", max concurrent queries reached";
Mike Yu19108d52018-11-15 21:58:19 +08001247 }
1248
lifr94981782019-05-17 21:15:19 +08001249 doDns64ReverseLookup(&hp, &event);
1250 const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
1251 event.set_latency_micros(latencyUs);
1252 event.set_event_type(EVENT_GETHOSTBYADDR);
Mike Yu19108d52018-11-15 21:58:19 +08001253
Ken Chenffc224a2019-03-19 17:41:28 +08001254 LOG(DEBUG) << "GetHostByAddrHandler::run: result: " << (hp ? "success" : gai_strerror(rv));
Mike Yu19108d52018-11-15 21:58:19 +08001255
1256 bool success = true;
1257 if (hp) {
1258 success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
1259 success &= sendhostent(mClient, hp);
1260 } else {
1261 success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, nullptr, 0) == 0;
1262 }
1263
1264 if (!success) {
Ken Chenffc224a2019-03-19 17:41:28 +08001265 LOG(WARNING) << "GetHostByAddrHandler::run: Error writing DNS result to client";
Mike Yu19108d52018-11-15 21:58:19 +08001266 }
1267
lifr94981782019-05-17 21:15:19 +08001268 reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYADDR, mNetContext, latencyUs, rv, event,
Mike Yu19108d52018-11-15 21:58:19 +08001269 (hp && hp->h_name) ? hp->h_name : "null", {}, 0);
1270 mClient->decRef();
1271}
1272
Mike Yu04f1d482019-08-08 11:09:32 +08001273std::string DnsProxyListener::GetHostByAddrHandler::threadName() {
1274 return makeThreadName(mNetContext.dns_netid, mClient->getUid());
1275}
1276
Mike Yu19108d52018-11-15 21:58:19 +08001277} // namespace net
1278} // namespace android