1 /*
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
17 #include "DnsProxyListener.h"
18
19 #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 <resolv.h> // b64_pton()
28 #include <stdlib.h>
29 #include <string.h>
30 #include <sys/socket.h>
31
32 #define LOG_TAG "resolv"
33
34 #include <algorithm>
35 #include <vector>
36
37 #include <android/multinetwork.h> // ResNsendFlags
38 #include <cutils/misc.h> // FIRST_APPLICATION_UID
39 #include <cutils/multiuser.h>
40 #include <netdutils/InternetAddresses.h>
41 #include <netdutils/ResponseCode.h>
42 #include <netdutils/Stopwatch.h>
43 #include <netdutils/ThreadUtil.h>
44 #include <private/android_filesystem_config.h> // AID_SYSTEM
45 #include <statslog_resolv.h>
46 #include <sysutils/SocketClient.h>
47
48 #include "DnsResolver.h"
49 #include "Experiments.h"
50 #include "NetdPermissions.h"
51 #include "OperationLimiter.h"
52 #include "PrivateDnsConfiguration.h"
53 #include "ResolverEventReporter.h"
54 #include "dnsproxyd_protocol/DnsProxydProtocol.h" // NETID_USE_LOCAL_NAMESERVERS
55 #include "getaddrinfo.h"
56 #include "gethnamaddr.h"
57 #include "res_send.h"
58 #include "resolv_cache.h"
59 #include "resolv_private.h"
60 #include "stats.h" // RCODE_TIMEOUT
61 #include "stats.pb.h"
62
63 using aidl::android::net::metrics::INetdEventListener;
64 using aidl::android::net::resolv::aidl::DnsHealthEventParcel;
65 using aidl::android::net::resolv::aidl::IDnsResolverUnsolicitedEventListener;
66 using std::span;
67
68 namespace android {
69
70 using netdutils::ResponseCode;
71 using netdutils::Stopwatch;
72
73 namespace net {
74 namespace {
75
76 // Limits the number of outstanding DNS queries by client UID.
77 constexpr int MAX_QUERIES_PER_UID = 256;
78
79 android::netdutils::OperationLimiter<uid_t> queryLimiter(MAX_QUERIES_PER_UID);
80
logArguments(int argc,char ** argv)81 void logArguments(int argc, char** argv) {
82 if (!WOULD_LOG(VERBOSE)) return;
83 for (int i = 0; i < argc; i++) {
84 LOG(VERBOSE) << __func__ << ": argv[" << i << "]=" << (argv[i] ? argv[i] : "null");
85 }
86 }
87
checkAndClearUseLocalNameserversFlag(unsigned * netid)88 bool checkAndClearUseLocalNameserversFlag(unsigned* netid) {
89 if (netid == nullptr || ((*netid) & NETID_USE_LOCAL_NAMESERVERS) == 0) {
90 return false;
91 }
92 *netid = (*netid) & ~NETID_USE_LOCAL_NAMESERVERS;
93 return true;
94 }
95
requestingUseLocalNameservers(unsigned flags)96 constexpr bool requestingUseLocalNameservers(unsigned flags) {
97 return (flags & NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS) != 0;
98 }
99
queryingViaTls(unsigned dns_netid)100 bool queryingViaTls(unsigned dns_netid) {
101 const auto privateDnsStatus = PrivateDnsConfiguration::getInstance().getStatus(dns_netid);
102 switch (privateDnsStatus.mode) {
103 case PrivateDnsMode::OPPORTUNISTIC:
104 return !privateDnsStatus.validatedServers().empty();
105 case PrivateDnsMode::STRICT:
106 return true;
107 default:
108 return false;
109 }
110 }
111
hasPermissionToBypassPrivateDns(uid_t uid)112 bool hasPermissionToBypassPrivateDns(uid_t uid) {
113 static_assert(AID_SYSTEM >= 0 && AID_SYSTEM < FIRST_APPLICATION_UID,
114 "Calls from AID_SYSTEM must not result in a permission check to avoid deadlock.");
115 if (uid >= 0 && uid < FIRST_APPLICATION_UID) {
116 return true;
117 }
118
119 for (const char* const permission :
120 {PERM_CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERM_NETWORK_BYPASS_PRIVATE_DNS,
121 PERM_MAINLINE_NETWORK_STACK}) {
122 if (gResNetdCallbacks.check_calling_permission(permission)) {
123 return true;
124 }
125 }
126 return false;
127 }
128
maybeFixupNetContext(android_net_context * ctx,pid_t pid)129 void maybeFixupNetContext(android_net_context* ctx, pid_t pid) {
130 if (requestingUseLocalNameservers(ctx->flags) && !hasPermissionToBypassPrivateDns(ctx->uid)) {
131 // Not permitted; clear the flag.
132 ctx->flags &= ~NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
133 }
134
135 if (!requestingUseLocalNameservers(ctx->flags)) {
136 // If we're not explicitly bypassing DNS-over-TLS servers, check whether
137 // DNS-over-TLS is in use as an indicator for when to use more modern
138 // DNS resolution mechanics.
139 if (queryingViaTls(ctx->dns_netid)) {
140 ctx->flags |= NET_CONTEXT_FLAG_USE_DNS_OVER_TLS | NET_CONTEXT_FLAG_USE_EDNS;
141 }
142 }
143 ctx->pid = pid;
144 }
145
146 void addIpAddrWithinLimit(std::vector<std::string>* ip_addrs, const sockaddr* addr,
147 socklen_t addrlen);
148
extractResNsendAnswers(std::span<const uint8_t> answer,int ipType,std::vector<std::string> * ip_addrs)149 int extractResNsendAnswers(std::span<const uint8_t> answer, int ipType,
150 std::vector<std::string>* ip_addrs) {
151 int total_ip_addr_count = 0;
152 ns_msg handle;
153 if (ns_initparse(answer.data(), answer.size(), &handle) < 0) {
154 return 0;
155 }
156 int ancount = ns_msg_count(handle, ns_s_an);
157 ns_rr rr;
158 for (int i = 0; i < ancount; i++) {
159 if (ns_parserr(&handle, ns_s_an, i, &rr) < 0) {
160 continue;
161 }
162 const uint8_t* rdata = ns_rr_rdata(rr);
163 if (ipType == ns_t_a) {
164 sockaddr_in sin = {.sin_family = AF_INET};
165 memcpy(&sin.sin_addr, rdata, sizeof(sin.sin_addr));
166 addIpAddrWithinLimit(ip_addrs, (sockaddr*)&sin, sizeof(sin));
167 total_ip_addr_count++;
168 } else if (ipType == ns_t_aaaa) {
169 sockaddr_in6 sin6 = {.sin6_family = AF_INET6};
170 memcpy(&sin6.sin6_addr, rdata, sizeof(sin6.sin6_addr));
171 addIpAddrWithinLimit(ip_addrs, (sockaddr*)&sin6, sizeof(sin6));
172 total_ip_addr_count++;
173 }
174 }
175
176 return total_ip_addr_count;
177 }
178
extractGetAddrInfoAnswers(const addrinfo * result,std::vector<std::string> * ip_addrs)179 int extractGetAddrInfoAnswers(const addrinfo* result, std::vector<std::string>* ip_addrs) {
180 int total_ip_addr_count = 0;
181 if (result == nullptr) {
182 return 0;
183 }
184 for (const addrinfo* ai = result; ai; ai = ai->ai_next) {
185 sockaddr* ai_addr = ai->ai_addr;
186 if (ai_addr) {
187 addIpAddrWithinLimit(ip_addrs, ai_addr, ai->ai_addrlen);
188 total_ip_addr_count++;
189 }
190 }
191 return total_ip_addr_count;
192 }
193
extractGetHostByNameAnswers(const hostent * hp,std::vector<std::string> * ip_addrs)194 int extractGetHostByNameAnswers(const hostent* hp, std::vector<std::string>* ip_addrs) {
195 int total_ip_addr_count = 0;
196 if (hp == nullptr) {
197 return 0;
198 }
199 if (hp->h_addrtype == AF_INET) {
200 in_addr** list = (in_addr**)hp->h_addr_list;
201 for (int i = 0; list[i] != nullptr; i++) {
202 sockaddr_in sin = {.sin_family = AF_INET, .sin_addr = *list[i]};
203 addIpAddrWithinLimit(ip_addrs, (sockaddr*)&sin, sizeof(sin));
204 total_ip_addr_count++;
205 }
206 } else if (hp->h_addrtype == AF_INET6) {
207 in6_addr** list = (in6_addr**)hp->h_addr_list;
208 for (int i = 0; list[i] != nullptr; i++) {
209 sockaddr_in6 sin6 = {.sin6_family = AF_INET6, .sin6_addr = *list[i]};
210 addIpAddrWithinLimit(ip_addrs, (sockaddr*)&sin6, sizeof(sin6));
211 total_ip_addr_count++;
212 }
213 }
214 return total_ip_addr_count;
215 }
216
rcodeToAiError(int rcode)217 int rcodeToAiError(int rcode) {
218 switch (rcode) {
219 case NOERROR:
220 return 0;
221 case RCODE_TIMEOUT:
222 return NETD_RESOLV_TIMEOUT;
223 default:
224 return EAI_NODATA;
225 }
226 }
227
resNSendToAiError(int err,int rcode)228 int resNSendToAiError(int err, int rcode) {
229 if (err > 0) {
230 return rcodeToAiError(rcode);
231 }
232 if (err == -ETIMEDOUT) {
233 return NETD_RESOLV_TIMEOUT;
234 }
235 return EAI_SYSTEM;
236 }
237
238 template <typename IntegralType>
simpleStrtoul(const char * input,IntegralType * output,int base=10)239 bool simpleStrtoul(const char* input, IntegralType* output, int base = 10) {
240 char* endPtr;
241 errno = 0;
242 auto result = strtoul(input, &endPtr, base);
243 // Check the length in order to ensure there is no "-" sign
244 if (!*input || *endPtr || (endPtr - input) != static_cast<ptrdiff_t>(strlen(input)) ||
245 (errno == ERANGE && (result == ULONG_MAX))) {
246 return false;
247 }
248 *output = result;
249 return true;
250 }
251
setQueryId(span<uint8_t> msg,uint16_t query_id)252 bool setQueryId(span<uint8_t> msg, uint16_t query_id) {
253 if ((size_t)msg.size() < sizeof(HEADER)) {
254 errno = EINVAL;
255 return false;
256 }
257 auto hp = reinterpret_cast<HEADER*>(msg.data());
258 hp->id = htons(query_id);
259 return true;
260 }
261
parseQuery(span<const uint8_t> msg,uint16_t * query_id,int * rr_type,std::string * rr_name)262 bool parseQuery(span<const uint8_t> msg, uint16_t* query_id, int* rr_type, std::string* rr_name) {
263 ns_msg handle;
264 ns_rr rr;
265 if (ns_initparse(msg.data(), msg.size(), &handle) < 0 ||
266 ns_parserr(&handle, ns_s_qd, 0, &rr) < 0) {
267 return false;
268 }
269 *query_id = ns_msg_id(handle);
270 *rr_name = ns_rr_name(rr);
271 *rr_type = ns_rr_type(rr);
272 return true;
273 }
274
275 // Note: Even if it returns PDM_OFF, it doesn't mean there's no DoT stats in the message
276 // because Private DNS mode can change at any time.
getPrivateDnsModeForMetrics(uint32_t netId)277 PrivateDnsModes getPrivateDnsModeForMetrics(uint32_t netId) {
278 switch (PrivateDnsConfiguration::getInstance().getStatus(netId).mode) {
279 case PrivateDnsMode::OFF:
280 // It can also be due to netId not found.
281 return PrivateDnsModes::PDM_OFF;
282 case PrivateDnsMode::OPPORTUNISTIC:
283 return PrivateDnsModes::PDM_OPPORTUNISTIC;
284 case PrivateDnsMode::STRICT:
285 return PrivateDnsModes::PDM_STRICT;
286 default:
287 return PrivateDnsModes::PDM_UNKNOWN;
288 }
289 }
290
initDnsEvent(NetworkDnsEventReported * event,const android_net_context & netContext)291 void initDnsEvent(NetworkDnsEventReported* event, const android_net_context& netContext) {
292 // The value 0 has the special meaning of unset/unknown in Statsd atoms. So, we set both
293 // flags to -1 as default value.
294 // 1. The hints flag is only used in resolv_getaddrinfo. When user set it to -1 in
295 // resolv_getaddrinfo, the flag will cause validation (validateHints) failure in
296 // getaddrinfo, so it will not do DNS query and will upload DNS stats log with
297 // return_code = RC_EAI_BADFLAGS.
298 // 2. The res_nsend flags are only used in resolv_res_nsend. When user set it to -1 in
299 // resolv_res_nsend,res_nsend will do nothing special by the setting.
300 event->set_hints_ai_flags(-1);
301 event->set_res_nsend_flags(-1);
302 event->set_private_dns_modes(getPrivateDnsModeForMetrics(netContext.dns_netid));
303 }
304
305 // Return 0 if the event should not be logged.
306 // Otherwise, return subsampling_denom
getDnsEventSubsamplingRate(int netid,int returnCode,bool isMdns)307 uint32_t getDnsEventSubsamplingRate(int netid, int returnCode, bool isMdns) {
308 uint32_t subsampling_denom = resolv_cache_get_subsampling_denom(netid, returnCode, isMdns);
309 if (subsampling_denom == 0) return 0;
310 // Sample the event with a chance of 1 / denom.
311 return (arc4random_uniform(subsampling_denom) == 0) ? subsampling_denom : 0;
312 }
313
maybeLogQuery(int eventType,const android_net_context & netContext,const NetworkDnsEventReported & event,const std::string & query_name,const std::vector<std::string> & ip_addrs)314 void maybeLogQuery(int eventType, const android_net_context& netContext,
315 const NetworkDnsEventReported& event, const std::string& query_name,
316 const std::vector<std::string>& ip_addrs) {
317 // Skip reverse queries.
318 if (eventType == INetdEventListener::EVENT_GETHOSTBYADDR) return;
319
320 for (const auto& query : event.dns_query_events().dns_query_event()) {
321 // Log it when the cache misses.
322 if (query.cache_hit() != CS_FOUND) {
323 const int timeTakenMs = event.latency_micros() / 1000;
324 DnsQueryLog::Record record(netContext.dns_netid, netContext.uid, netContext.pid,
325 query_name, ip_addrs, timeTakenMs);
326 gDnsResolv->dnsQueryLog().push(std::move(record));
327 return;
328 }
329 }
330 }
331
reportDnsEvent(int eventType,const android_net_context & netContext,int latencyUs,int returnCode,NetworkDnsEventReported & event,const std::string & query_name,const std::vector<std::string> & ip_addrs={},int total_ip_addr_count=0)332 void reportDnsEvent(int eventType, const android_net_context& netContext, int latencyUs,
333 int returnCode, NetworkDnsEventReported& event, const std::string& query_name,
334 const std::vector<std::string>& ip_addrs = {}, int total_ip_addr_count = 0) {
335 uint32_t rate =
336 (query_name.ends_with(".local") && is_mdns_supported_network(netContext.dns_netid) &&
337 android::net::Experiments::getInstance()->getFlag("mdns_resolution", 1))
338 ? getDnsEventSubsamplingRate(netContext.dns_netid, returnCode, true)
339 : getDnsEventSubsamplingRate(netContext.dns_netid, returnCode, false);
340
341 if (rate) {
342 const std::string& dnsQueryStats = event.dns_query_events().SerializeAsString();
343 stats::BytesField dnsQueryBytesField{dnsQueryStats.c_str(), dnsQueryStats.size()};
344 event.set_return_code(static_cast<ReturnCode>(returnCode));
345 event.set_network_type(resolv_get_network_types_for_net(netContext.dns_netid));
346 android::net::stats::stats_write(android::net::stats::NETWORK_DNS_EVENT_REPORTED,
347 event.event_type(), event.return_code(),
348 event.latency_micros(), event.hints_ai_flags(),
349 event.res_nsend_flags(), event.network_type(),
350 event.private_dns_modes(), dnsQueryBytesField, rate);
351 }
352
353 maybeLogQuery(eventType, netContext, event, query_name, ip_addrs);
354
355 const auto& listeners = ResolverEventReporter::getInstance().getListeners();
356 if (listeners.empty()) {
357 LOG(ERROR) << __func__
358 << ": DNS event not sent since no INetdEventListener receiver is available.";
359 }
360 const int latencyMs = latencyUs / 1000;
361 for (const auto& it : listeners) {
362 it->onDnsEvent(netContext.dns_netid, eventType, returnCode, latencyMs, query_name, ip_addrs,
363 total_ip_addr_count, netContext.uid);
364 }
365
366 const auto& unsolEventListeners = ResolverEventReporter::getInstance().getUnsolEventListeners();
367
368 if (returnCode == NETD_RESOLV_TIMEOUT) {
369 const DnsHealthEventParcel dnsHealthEvent = {
370 .netId = static_cast<int32_t>(netContext.dns_netid),
371 .healthResult = IDnsResolverUnsolicitedEventListener::DNS_HEALTH_RESULT_TIMEOUT,
372 };
373 for (const auto& it : unsolEventListeners) {
374 it->onDnsHealthEvent(dnsHealthEvent);
375 }
376 } else if (returnCode == NOERROR) {
377 DnsHealthEventParcel dnsHealthEvent = {
378 .netId = static_cast<int32_t>(netContext.dns_netid),
379 .healthResult = IDnsResolverUnsolicitedEventListener::DNS_HEALTH_RESULT_OK,
380 };
381 for (const auto& query : event.dns_query_events().dns_query_event()) {
382 if (query.cache_hit() != CS_FOUND && query.rcode() == NS_R_NO_ERROR) {
383 dnsHealthEvent.successRttMicros.push_back(query.latency_micros());
384 }
385 }
386
387 if (!dnsHealthEvent.successRttMicros.empty()) {
388 for (const auto& it : unsolEventListeners) {
389 it->onDnsHealthEvent(dnsHealthEvent);
390 }
391 }
392 }
393 }
394
onlyIPv4Answers(const addrinfo * res)395 bool onlyIPv4Answers(const addrinfo* res) {
396 // Null addrinfo pointer isn't checked because the caller doesn't pass null pointer.
397
398 for (const addrinfo* ai = res; ai; ai = ai->ai_next)
399 if (ai->ai_family != AF_INET) return false;
400
401 return true;
402 }
403
isSpecialUseIPv4Address(const struct in_addr & ia)404 bool isSpecialUseIPv4Address(const struct in_addr& ia) {
405 const uint32_t addr = ntohl(ia.s_addr);
406
407 // Only check necessary IP ranges in RFC 5735 section 4
408 return ((addr & 0xff000000) == 0x00000000) || // "This" Network
409 ((addr & 0xff000000) == 0x7f000000) || // Loopback
410 ((addr & 0xffff0000) == 0xa9fe0000) || // Link Local
411 ((addr & 0xf0000000) == 0xe0000000) || // Multicast
412 (addr == INADDR_BROADCAST); // Limited Broadcast
413 }
414
isSpecialUseIPv4Address(const struct sockaddr * sa)415 bool isSpecialUseIPv4Address(const struct sockaddr* sa) {
416 if (sa->sa_family != AF_INET) return false;
417
418 return isSpecialUseIPv4Address(((struct sockaddr_in*)sa)->sin_addr);
419 }
420
onlyNonSpecialUseIPv4Addresses(struct hostent * hp)421 bool onlyNonSpecialUseIPv4Addresses(struct hostent* hp) {
422 // Null hostent pointer isn't checked because the caller doesn't pass null pointer.
423
424 if (hp->h_addrtype != AF_INET) return false;
425
426 for (int i = 0; hp->h_addr_list[i] != nullptr; i++)
427 if (isSpecialUseIPv4Address(*(struct in_addr*)hp->h_addr_list[i])) return false;
428
429 return true;
430 }
431
onlyNonSpecialUseIPv4Addresses(const addrinfo * res)432 bool onlyNonSpecialUseIPv4Addresses(const addrinfo* res) {
433 // Null addrinfo pointer isn't checked because the caller doesn't pass null pointer.
434
435 for (const addrinfo* ai = res; ai; ai = ai->ai_next) {
436 if (ai->ai_family != AF_INET) return false;
437 if (isSpecialUseIPv4Address(ai->ai_addr)) return false;
438 }
439
440 return true;
441 }
442
logDnsQueryResult(const struct hostent * hp)443 void logDnsQueryResult(const struct hostent* hp) {
444 if (!WOULD_LOG(DEBUG)) return;
445 if (hp == nullptr) return;
446
447 LOG(DEBUG) << __func__ << ": DNS records:";
448 for (int i = 0; hp->h_addr_list[i] != nullptr; i++) {
449 char ip_addr[INET6_ADDRSTRLEN];
450 if (inet_ntop(hp->h_addrtype, hp->h_addr_list[i], ip_addr, sizeof(ip_addr)) != nullptr) {
451 LOG(DEBUG) << __func__ << ": [" << i << "] " << hp->h_addrtype;
452 } else {
453 PLOG(DEBUG) << __func__ << ": [" << i << "] numeric hostname translation fail";
454 }
455 }
456 }
457
logDnsQueryResult(const addrinfo * res)458 void logDnsQueryResult(const addrinfo* res) {
459 if (!WOULD_LOG(DEBUG)) return;
460 if (res == nullptr) return;
461
462 int i;
463 const addrinfo* ai;
464 LOG(DEBUG) << __func__ << ": DNS records:";
465 for (ai = res, i = 0; ai; ai = ai->ai_next, i++) {
466 if ((ai->ai_family != AF_INET) && (ai->ai_family != AF_INET6)) continue;
467 char ip_addr[INET6_ADDRSTRLEN];
468 int ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, ip_addr, sizeof(ip_addr), nullptr, 0,
469 NI_NUMERICHOST);
470 if (!ret) {
471 LOG(DEBUG) << __func__ << ": [" << i << "] " << ai->ai_flags << " " << ai->ai_family
472 << " " << ai->ai_socktype << " " << ai->ai_protocol;
473 } else {
474 LOG(DEBUG) << __func__ << ": [" << i << "] numeric hostname translation fail " << ret;
475 }
476 }
477 }
478
isValidNat64Prefix(const netdutils::IPPrefix prefix)479 bool isValidNat64Prefix(const netdutils::IPPrefix prefix) {
480 if (prefix.family() != AF_INET6) {
481 LOG(ERROR) << __func__ << ": Only IPv6 NAT64 prefixes are supported " << prefix.family();
482 return false;
483 }
484 if (prefix.length() != 96) {
485 LOG(ERROR) << __func__ << ": Only /96 NAT64 prefixes are supported " << prefix.length();
486 return false;
487 }
488 return true;
489 }
490
synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix & prefix,struct hostent * hp)491 bool synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix& prefix, struct hostent* hp) {
492 if (hp == nullptr) return false;
493 if (!onlyNonSpecialUseIPv4Addresses(hp)) return false;
494 if (!isValidNat64Prefix(prefix)) return false;
495
496 struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
497 struct sockaddr_in6* v6prefix = (struct sockaddr_in6*)&ss;
498 for (int i = 0; hp->h_addr_list[i] != nullptr; i++) {
499 struct in_addr iaOriginal = *(struct in_addr*)hp->h_addr_list[i];
500 struct in6_addr* ia6 = (struct in6_addr*)hp->h_addr_list[i];
501 memset(ia6, 0, sizeof(struct in6_addr));
502
503 // Synthesize /96 NAT64 prefix in place. The space has reserved by getanswer() and
504 // _hf_gethtbyname2() in system/netd/resolv/gethnamaddr.cpp and
505 // system/netd/resolv/sethostent.cpp.
506 *ia6 = v6prefix->sin6_addr;
507 ia6->s6_addr32[3] = iaOriginal.s_addr;
508
509 if (WOULD_LOG(VERBOSE)) {
510 char buf[INET6_ADDRSTRLEN]; // big enough for either IPv4 or IPv6
511 inet_ntop(AF_INET, &iaOriginal.s_addr, buf, sizeof(buf));
512 LOG(VERBOSE) << __func__ << ": DNS A record: " << buf;
513 inet_ntop(AF_INET6, &v6prefix->sin6_addr, buf, sizeof(buf));
514 LOG(VERBOSE) << __func__ << ": NAT64 prefix: " << buf;
515 inet_ntop(AF_INET6, ia6, buf, sizeof(buf));
516 LOG(VERBOSE) << __func__ << ": DNS64 Synthesized AAAA record: " << buf;
517 }
518 }
519 hp->h_addrtype = AF_INET6;
520 hp->h_length = sizeof(in6_addr);
521
522 logDnsQueryResult(hp);
523 return true;
524 }
525
synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix & prefix,addrinfo * result)526 bool synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix& prefix, addrinfo* result) {
527 if (result == nullptr) return false;
528 if (!onlyNonSpecialUseIPv4Addresses(result)) return false;
529 if (!isValidNat64Prefix(prefix)) return false;
530
531 struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
532 struct sockaddr_in6* v6prefix = (struct sockaddr_in6*)&ss;
533 for (addrinfo* ai = result; ai; ai = ai->ai_next) {
534 struct sockaddr_in sinOriginal = *(struct sockaddr_in*)ai->ai_addr;
535 struct sockaddr_in6* sin6 = (struct sockaddr_in6*)ai->ai_addr;
536 memset(sin6, 0, sizeof(sockaddr_in6));
537
538 // Synthesize /96 NAT64 prefix in place. The space has reserved by get_ai() in
539 // system/netd/resolv/getaddrinfo.cpp.
540 sin6->sin6_addr = v6prefix->sin6_addr;
541 sin6->sin6_addr.s6_addr32[3] = sinOriginal.sin_addr.s_addr;
542 sin6->sin6_family = AF_INET6;
543 sin6->sin6_port = sinOriginal.sin_port;
544 ai->ai_addrlen = sizeof(struct sockaddr_in6);
545 ai->ai_family = AF_INET6;
546
547 if (WOULD_LOG(VERBOSE)) {
548 char buf[INET6_ADDRSTRLEN]; // big enough for either IPv4 or IPv6
549 inet_ntop(AF_INET, &sinOriginal.sin_addr.s_addr, buf, sizeof(buf));
550 LOG(VERBOSE) << __func__ << ": DNS A record: " << buf;
551 inet_ntop(AF_INET6, &v6prefix->sin6_addr, buf, sizeof(buf));
552 LOG(VERBOSE) << __func__ << ": NAT64 prefix: " << buf;
553 inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof(buf));
554 LOG(VERBOSE) << __func__ << ": DNS64 Synthesized AAAA record: " << buf;
555 }
556 }
557 logDnsQueryResult(result);
558 return true;
559 }
560
getDns64Prefix(unsigned netId,netdutils::IPPrefix * prefix)561 bool getDns64Prefix(unsigned netId, netdutils::IPPrefix* prefix) {
562 return !gDnsResolv->resolverCtrl.getPrefix64(netId, prefix);
563 }
564
makeThreadName(unsigned netId,uint32_t uid)565 std::string makeThreadName(unsigned netId, uint32_t uid) {
566 // The maximum of netId and app_id are 5-digit numbers.
567 return fmt::format("Dns_{}_{}", netId, multiuser_get_app_id(uid));
568 }
569
570 } // namespace
571
DnsProxyListener()572 DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) {
573 registerCmd(new GetAddrInfoCmd());
574 registerCmd(new GetHostByAddrCmd());
575 registerCmd(new GetHostByNameCmd());
576 registerCmd(new ResNSendCommand());
577 registerCmd(new GetDnsNetIdCommand());
578 }
579
spawn()580 void DnsProxyListener::Handler::spawn() {
581 const int rval = netdutils::threadLaunch(this);
582 if (rval == 0) {
583 return;
584 }
585
586 char* msg = nullptr;
587 asprintf(&msg, "%s (%d)", strerror(-rval), -rval);
588 mClient->sendMsg(ResponseCode::OperationFailed, msg, false);
589 free(msg);
590 delete this;
591 }
592
GetAddrInfoHandler(SocketClient * c,std::string host,std::string service,std::unique_ptr<addrinfo> hints,const android_net_context & netcontext)593 DnsProxyListener::GetAddrInfoHandler::GetAddrInfoHandler(SocketClient* c, std::string host,
594 std::string service,
595 std::unique_ptr<addrinfo> hints,
596 const android_net_context& netcontext)
597 : Handler(c),
598 mHost(move(host)),
599 mService(move(service)),
600 mHints(move(hints)),
601 mNetContext(netcontext) {}
602
evaluate_domain_name(const android_net_context & netcontext,const char * host)603 static bool evaluate_domain_name(const android_net_context& netcontext, const char* host) {
604 if (!gResNetdCallbacks.evaluate_domain_name) return true;
605 return gResNetdCallbacks.evaluate_domain_name(netcontext, host);
606 }
607
sendBE32(SocketClient * c,uint32_t data)608 static bool sendBE32(SocketClient* c, uint32_t data) {
609 uint32_t be_data = htonl(data);
610 return c->sendData(&be_data, sizeof(be_data)) == 0;
611 }
612
613 // Sends 4 bytes of big-endian length, followed by the data.
614 // Returns true on success.
sendLenAndData(SocketClient * c,const int len,const void * data)615 static bool sendLenAndData(SocketClient* c, const int len, const void* data) {
616 return sendBE32(c, len) && (len == 0 || c->sendData(data, len) == 0);
617 }
618
619 // Returns true on success
sendhostent(SocketClient * c,hostent * hp)620 static bool sendhostent(SocketClient* c, hostent* hp) {
621 bool success = true;
622 int i;
623 if (hp->h_name != nullptr) {
624 success &= sendLenAndData(c, strlen(hp->h_name) + 1, hp->h_name);
625 } else {
626 success &= sendLenAndData(c, 0, "") == 0;
627 }
628
629 for (i = 0; hp->h_aliases[i] != nullptr; i++) {
630 success &= sendLenAndData(c, strlen(hp->h_aliases[i]) + 1, hp->h_aliases[i]);
631 }
632 success &= sendLenAndData(c, 0, ""); // null to indicate we're done
633
634 uint32_t buf = htonl(hp->h_addrtype);
635 success &= c->sendData(&buf, sizeof(buf)) == 0;
636
637 buf = htonl(hp->h_length);
638 success &= c->sendData(&buf, sizeof(buf)) == 0;
639
640 for (i = 0; hp->h_addr_list[i] != nullptr; i++) {
641 success &= sendLenAndData(c, 16, hp->h_addr_list[i]);
642 }
643 success &= sendLenAndData(c, 0, ""); // null to indicate we're done
644 return success;
645 }
646
sendaddrinfo(SocketClient * c,addrinfo * ai)647 static bool sendaddrinfo(SocketClient* c, addrinfo* ai) {
648 // struct addrinfo {
649 // int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
650 // int ai_family; /* PF_xxx */
651 // int ai_socktype; /* SOCK_xxx */
652 // int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
653 // socklen_t ai_addrlen; /* length of ai_addr */
654 // char *ai_canonname; /* canonical name for hostname */
655 // struct sockaddr *ai_addr; /* binary address */
656 // struct addrinfo *ai_next; /* next structure in linked list */
657 // };
658
659 // Write the struct piece by piece because we might be a 64-bit netd
660 // talking to a 32-bit process.
661 bool success = sendBE32(c, ai->ai_flags) && sendBE32(c, ai->ai_family) &&
662 sendBE32(c, ai->ai_socktype) && sendBE32(c, ai->ai_protocol);
663 if (!success) {
664 return false;
665 }
666
667 // ai_addrlen and ai_addr.
668 if (!sendLenAndData(c, ai->ai_addrlen, ai->ai_addr)) {
669 return false;
670 }
671
672 // strlen(ai_canonname) and ai_canonname.
673 if (!sendLenAndData(c, ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0, ai->ai_canonname)) {
674 return false;
675 }
676
677 return true;
678 }
679
doDns64Synthesis(int32_t * rv,addrinfo ** res,NetworkDnsEventReported * event)680 void DnsProxyListener::GetAddrInfoHandler::doDns64Synthesis(int32_t* rv, addrinfo** res,
681 NetworkDnsEventReported* event) {
682 const bool ipv6WantedButNoData = (mHints && mHints->ai_family == AF_INET6 && *rv == EAI_NODATA);
683 const bool unspecWantedButNoIPv6 =
684 ((!mHints || mHints->ai_family == AF_UNSPEC) && *rv == 0 && onlyIPv4Answers(*res));
685
686 if (!ipv6WantedButNoData && !unspecWantedButNoIPv6) {
687 return;
688 }
689
690 netdutils::IPPrefix prefix{};
691 if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
692 return;
693 }
694
695 if (ipv6WantedButNoData) {
696 // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis
697 const uid_t uid = mClient->getUid();
698 if (queryLimiter.start(uid)) {
699 const char* host = mHost.starts_with('^') ? nullptr : mHost.c_str();
700 const char* service = mService.starts_with('^') ? nullptr : mService.c_str();
701 mHints->ai_family = AF_INET;
702 // Don't need to do freeaddrinfo(res) before starting new DNS lookup because previous
703 // DNS lookup is failed with error EAI_NODATA.
704 *rv = resolv_getaddrinfo(host, service, mHints.get(), &mNetContext, res, event);
705 queryLimiter.finish(uid);
706 if (*rv) {
707 *rv = EAI_NODATA; // return original error code
708 return;
709 }
710 } else {
711 LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached";
712 return;
713 }
714 }
715
716 if (!synthesizeNat64PrefixWithARecord(prefix, *res)) {
717 if (ipv6WantedButNoData) {
718 // If caller wants IPv6 answers but no data and failed to synthesize IPv6 answers,
719 // don't return the IPv4 answers.
720 *rv = EAI_NODATA; // return original error code
721 if (*res) {
722 freeaddrinfo(*res);
723 *res = nullptr;
724 }
725 }
726 }
727 }
728
run()729 void DnsProxyListener::GetAddrInfoHandler::run() {
730 LOG(DEBUG) << "GetAddrInfoHandler::run: {" << mNetContext.app_netid << " "
731 << mNetContext.app_mark << " " << mNetContext.dns_netid << " "
732 << mNetContext.dns_mark << " " << mNetContext.uid << " " << mNetContext.flags << "}";
733
734 addrinfo* result = nullptr;
735 Stopwatch s;
736 maybeFixupNetContext(&mNetContext, mClient->getPid());
737 const uid_t uid = mClient->getUid();
738 int32_t rv = 0;
739 NetworkDnsEventReported event;
740 initDnsEvent(&event, mNetContext);
741 if (queryLimiter.start(uid)) {
742 const char* host = mHost.starts_with('^') ? nullptr : mHost.c_str();
743 const char* service = mService.starts_with('^') ? nullptr : mService.c_str();
744 if (evaluate_domain_name(mNetContext, host)) {
745 rv = resolv_getaddrinfo(host, service, mHints.get(), &mNetContext, &result, &event);
746 } else {
747 rv = EAI_SYSTEM;
748 }
749 queryLimiter.finish(uid);
750 } else {
751 // Note that this error code is currently not passed down to the client.
752 // android_getaddrinfo_proxy() returns EAI_NODATA on any error.
753 rv = EAI_MEMORY;
754 LOG(ERROR) << "GetAddrInfoHandler::run: from UID " << uid
755 << ", max concurrent queries reached";
756 }
757
758 doDns64Synthesis(&rv, &result, &event);
759 const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
760 event.set_latency_micros(latencyUs);
761 event.set_event_type(EVENT_GETADDRINFO);
762 event.set_hints_ai_flags((mHints ? mHints->ai_flags : 0));
763
764 bool success = true;
765 if (rv) {
766 // getaddrinfo failed
767 success = !mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, &rv, sizeof(rv));
768 } else {
769 success = !mClient->sendCode(ResponseCode::DnsProxyQueryResult);
770 addrinfo* ai = result;
771 while (ai && success) {
772 success = sendBE32(mClient, 1) && sendaddrinfo(mClient, ai);
773 ai = ai->ai_next;
774 }
775 success = success && sendBE32(mClient, 0);
776 }
777
778 if (!success) {
779 PLOG(WARNING) << "GetAddrInfoHandler::run: Error writing DNS result to client uid " << uid
780 << " pid " << mClient->getPid();
781 }
782
783 std::vector<std::string> ip_addrs;
784 const int total_ip_addr_count = extractGetAddrInfoAnswers(result, &ip_addrs);
785 reportDnsEvent(INetdEventListener::EVENT_GETADDRINFO, mNetContext, latencyUs, rv, event, mHost,
786 ip_addrs, total_ip_addr_count);
787 freeaddrinfo(result);
788 }
789
threadName()790 std::string DnsProxyListener::GetAddrInfoHandler::threadName() {
791 return makeThreadName(mNetContext.dns_netid, mClient->getUid());
792 }
793
794 namespace {
795
addIpAddrWithinLimit(std::vector<std::string> * ip_addrs,const sockaddr * addr,socklen_t addrlen)796 void addIpAddrWithinLimit(std::vector<std::string>* ip_addrs, const sockaddr* addr,
797 socklen_t addrlen) {
798 // ipAddresses array is limited to first INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT
799 // addresses for A and AAAA. Total count of addresses is provided, to be able to tell whether
800 // some addresses didn't get logged.
801 if (ip_addrs->size() < INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT) {
802 char ip_addr[INET6_ADDRSTRLEN];
803 if (getnameinfo(addr, addrlen, ip_addr, sizeof(ip_addr), nullptr, 0, NI_NUMERICHOST) == 0) {
804 ip_addrs->push_back(std::string(ip_addr));
805 }
806 }
807 }
808
809 } // namespace
810
GetAddrInfoCmd()811 DnsProxyListener::GetAddrInfoCmd::GetAddrInfoCmd() : FrameworkCommand("getaddrinfo") {}
812
runCommand(SocketClient * cli,int argc,char ** argv)813 int DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient* cli, int argc, char** argv) {
814 logArguments(argc, argv);
815
816 if (argc != 8) {
817 char* msg = nullptr;
818 asprintf(&msg, "Invalid number of arguments to getaddrinfo: %i", argc);
819 LOG(WARNING) << "GetAddrInfoCmd::runCommand: " << (msg ? msg : "null");
820 cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
821 free(msg);
822 return -1;
823 }
824
825 const std::string name = argv[1];
826 const std::string service = argv[2];
827 int ai_flags = strtol(argv[3], nullptr, 10);
828 int ai_family = strtol(argv[4], nullptr, 10);
829 int ai_socktype = strtol(argv[5], nullptr, 10);
830 int ai_protocol = strtol(argv[6], nullptr, 10);
831 unsigned netId = strtoul(argv[7], nullptr, 10);
832 const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
833 const uid_t uid = cli->getUid();
834
835 android_net_context netcontext;
836 gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
837
838 if (useLocalNameservers) {
839 netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
840 }
841
842 std::unique_ptr<addrinfo> hints;
843 if (ai_flags != -1 || ai_family != -1 || ai_socktype != -1 || ai_protocol != -1) {
844 hints.reset((addrinfo*)calloc(1, sizeof(addrinfo)));
845 hints->ai_flags = ai_flags;
846 hints->ai_family = ai_family;
847 hints->ai_socktype = ai_socktype;
848 hints->ai_protocol = ai_protocol;
849 }
850
851 (new GetAddrInfoHandler(cli, name, service, move(hints), netcontext))->spawn();
852 return 0;
853 }
854
855 /*******************************************************
856 * ResNSendCommand *
857 *******************************************************/
ResNSendCommand()858 DnsProxyListener::ResNSendCommand::ResNSendCommand() : FrameworkCommand("resnsend") {}
859
runCommand(SocketClient * cli,int argc,char ** argv)860 int DnsProxyListener::ResNSendCommand::runCommand(SocketClient* cli, int argc, char** argv) {
861 logArguments(argc, argv);
862
863 const uid_t uid = cli->getUid();
864 if (argc != 4) {
865 LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
866 << ", invalid number of arguments to resnsend: " << argc;
867 sendBE32(cli, -EINVAL);
868 return -1;
869 }
870
871 unsigned netId;
872 if (!simpleStrtoul(argv[1], &netId)) {
873 LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
874 << ", invalid netId";
875 sendBE32(cli, -EINVAL);
876 return -1;
877 }
878
879 uint32_t flags;
880 if (!simpleStrtoul(argv[2], &flags)) {
881 LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
882 << ", invalid flags";
883 sendBE32(cli, -EINVAL);
884 return -1;
885 }
886
887 const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
888
889 android_net_context netcontext;
890 gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
891
892 if (useLocalNameservers) {
893 netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
894 }
895
896 (new ResNSendHandler(cli, argv[3], flags, netcontext))->spawn();
897 return 0;
898 }
899
ResNSendHandler(SocketClient * c,std::string msg,uint32_t flags,const android_net_context & netcontext)900 DnsProxyListener::ResNSendHandler::ResNSendHandler(SocketClient* c, std::string msg, uint32_t flags,
901 const android_net_context& netcontext)
902 : Handler(c), mMsg(std::move(msg)), mFlags(flags), mNetContext(netcontext) {}
903
run()904 void DnsProxyListener::ResNSendHandler::run() {
905 LOG(DEBUG) << "ResNSendHandler::run: " << mFlags << " / {" << mNetContext.app_netid << " "
906 << mNetContext.app_mark << " " << mNetContext.dns_netid << " "
907 << mNetContext.dns_mark << " " << mNetContext.uid << " " << mNetContext.flags << "}";
908
909 Stopwatch s;
910 maybeFixupNetContext(&mNetContext, mClient->getPid());
911
912 // Decode
913 std::vector<uint8_t> msg(MAXPACKET, 0);
914
915 // Max length of mMsg is less than 1024 since the CMD_BUF_SIZE in FrameworkListener is 1024
916 int msgLen = b64_pton(mMsg.c_str(), msg.data(), MAXPACKET);
917 if (msgLen == -1) {
918 // Decode fail
919 sendBE32(mClient, -EILSEQ);
920 return;
921 }
922
923 const uid_t uid = mClient->getUid();
924 int rr_type = 0;
925 std::string rr_name;
926 uint16_t original_query_id = 0;
927
928 // TODO: Handle the case which is msg contains more than one query
929 if (!parseQuery({msg.data(), msgLen}, &original_query_id, &rr_type, &rr_name) ||
930 !setQueryId({msg.data(), msgLen}, arc4random_uniform(65536))) {
931 // If the query couldn't be parsed, block the request.
932 LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid << ", invalid query";
933 sendBE32(mClient, -EINVAL);
934 return;
935 }
936
937 // Send DNS query
938 std::vector<uint8_t> ansBuf(MAXPACKET, 0);
939 int rcode = ns_r_noerror;
940 int ansLen = -1;
941 NetworkDnsEventReported event;
942 initDnsEvent(&event, mNetContext);
943 if (queryLimiter.start(uid)) {
944 if (evaluate_domain_name(mNetContext, rr_name.c_str())) {
945 ansLen = resolv_res_nsend(&mNetContext, {msg.data(), msgLen}, ansBuf, &rcode,
946 static_cast<ResNsendFlags>(mFlags), &event);
947 } else {
948 ansLen = -EAI_SYSTEM;
949 }
950 queryLimiter.finish(uid);
951 } else {
952 LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid
953 << ", max concurrent queries reached";
954 ansLen = -EBUSY;
955 }
956
957 const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
958 event.set_latency_micros(latencyUs);
959 event.set_event_type(EVENT_RES_NSEND);
960 event.set_res_nsend_flags(static_cast<ResNsendFlags>(mFlags));
961
962 // Fail, send -errno
963 if (ansLen < 0) {
964 if (!sendBE32(mClient, ansLen)) {
965 PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send errno to uid " << uid
966 << " pid " << mClient->getPid();
967 }
968 if (rr_type == ns_t_a || rr_type == ns_t_aaaa) {
969 reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs,
970 resNSendToAiError(ansLen, rcode), event, rr_name);
971 }
972 return;
973 }
974
975 // Send rcode
976 if (!sendBE32(mClient, rcode)) {
977 PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send rcode to uid " << uid
978 << " pid " << mClient->getPid();
979 return;
980 }
981
982 // Restore query id and send answer
983 if (!setQueryId({ansBuf.data(), ansLen}, original_query_id) ||
984 !sendLenAndData(mClient, ansLen, ansBuf.data())) {
985 PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send answer to uid " << uid
986 << " pid " << mClient->getPid();
987 return;
988 }
989
990 if (rr_type == ns_t_a || rr_type == ns_t_aaaa) {
991 std::vector<std::string> ip_addrs;
992 const int total_ip_addr_count =
993 extractResNsendAnswers({ansBuf.data(), ansLen}, rr_type, &ip_addrs);
994 reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs,
995 resNSendToAiError(ansLen, rcode), event, rr_name, ip_addrs,
996 total_ip_addr_count);
997 }
998 }
999
threadName()1000 std::string DnsProxyListener::ResNSendHandler::threadName() {
1001 return makeThreadName(mNetContext.dns_netid, mClient->getUid());
1002 }
1003
1004 namespace {
1005
sendCodeAndBe32(SocketClient * c,int code,int data)1006 bool sendCodeAndBe32(SocketClient* c, int code, int data) {
1007 return !c->sendCode(code) && sendBE32(c, data);
1008 }
1009
1010 } // namespace
1011
1012 /*******************************************************
1013 * GetDnsNetId *
1014 *******************************************************/
GetDnsNetIdCommand()1015 DnsProxyListener::GetDnsNetIdCommand::GetDnsNetIdCommand() : FrameworkCommand("getdnsnetid") {}
1016
runCommand(SocketClient * cli,int argc,char ** argv)1017 int DnsProxyListener::GetDnsNetIdCommand::runCommand(SocketClient* cli, int argc, char** argv) {
1018 logArguments(argc, argv);
1019
1020 const uid_t uid = cli->getUid();
1021 if (argc != 2) {
1022 LOG(WARNING) << "GetDnsNetIdCommand::runCommand: getdnsnetid: from UID " << uid
1023 << ", invalid number of arguments to getdnsnetid: " << argc;
1024 sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, -EINVAL);
1025 return -1;
1026 }
1027
1028 unsigned netId;
1029 if (!simpleStrtoul(argv[1], &netId)) {
1030 LOG(WARNING) << "GetDnsNetIdCommand::runCommand: getdnsnetid: from UID " << uid
1031 << ", invalid netId";
1032 sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, -EINVAL);
1033 return -1;
1034 }
1035
1036 const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
1037 android_net_context netcontext;
1038 gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
1039
1040 if (useLocalNameservers) {
1041 netcontext.app_netid |= NETID_USE_LOCAL_NAMESERVERS;
1042 }
1043
1044 const bool success =
1045 sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, netcontext.app_netid);
1046 if (!success) {
1047 PLOG(WARNING)
1048 << "GetDnsNetIdCommand::runCommand: getdnsnetid: failed to send result to uid "
1049 << uid << " pid " << cli->getPid();
1050 }
1051
1052 return success ? 0 : -1;
1053 }
1054
1055 /*******************************************************
1056 * GetHostByName *
1057 *******************************************************/
GetHostByNameCmd()1058 DnsProxyListener::GetHostByNameCmd::GetHostByNameCmd() : FrameworkCommand("gethostbyname") {}
1059
runCommand(SocketClient * cli,int argc,char ** argv)1060 int DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient* cli, int argc, char** argv) {
1061 logArguments(argc, argv);
1062
1063 if (argc != 4) {
1064 char* msg = nullptr;
1065 asprintf(&msg, "Invalid number of arguments to gethostbyname: %i", argc);
1066 LOG(WARNING) << "GetHostByNameCmd::runCommand: " << (msg ? msg : "null");
1067 cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
1068 free(msg);
1069 return -1;
1070 }
1071
1072 uid_t uid = cli->getUid();
1073 unsigned netId = strtoul(argv[1], nullptr, 10);
1074 const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
1075 std::string name = argv[2];
1076 int af = strtol(argv[3], nullptr, 10);
1077
1078 android_net_context netcontext;
1079 gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
1080
1081 if (useLocalNameservers) {
1082 netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
1083 }
1084
1085 (new GetHostByNameHandler(cli, name, af, netcontext))->spawn();
1086 return 0;
1087 }
1088
GetHostByNameHandler(SocketClient * c,std::string name,int af,const android_net_context & netcontext)1089 DnsProxyListener::GetHostByNameHandler::GetHostByNameHandler(SocketClient* c, std::string name,
1090 int af,
1091 const android_net_context& netcontext)
1092 : Handler(c), mName(move(name)), mAf(af), mNetContext(netcontext) {}
1093
doDns64Synthesis(int32_t * rv,hostent * hbuf,char * buf,size_t buflen,struct hostent ** hpp,NetworkDnsEventReported * event)1094 void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, hostent* hbuf, char* buf,
1095 size_t buflen, struct hostent** hpp,
1096 NetworkDnsEventReported* event) {
1097 // Don't have to consider family AF_UNSPEC case because gethostbyname{, 2} only supports
1098 // family AF_INET or AF_INET6.
1099 const bool ipv6WantedButNoData = (mAf == AF_INET6 && *rv == EAI_NODATA);
1100
1101 if (!ipv6WantedButNoData) {
1102 return;
1103 }
1104
1105 netdutils::IPPrefix prefix{};
1106 if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
1107 return;
1108 }
1109
1110 // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis
1111 const uid_t uid = mClient->getUid();
1112 if (queryLimiter.start(uid)) {
1113 const char* name = mName.starts_with('^') ? nullptr : mName.c_str();
1114 *rv = resolv_gethostbyname(name, AF_INET, hbuf, buf, buflen, &mNetContext, hpp, event);
1115 queryLimiter.finish(uid);
1116 if (*rv) {
1117 *rv = EAI_NODATA; // return original error code
1118 return;
1119 }
1120 } else {
1121 LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached";
1122 return;
1123 }
1124
1125 if (!synthesizeNat64PrefixWithARecord(prefix, *hpp)) {
1126 // If caller wants IPv6 answers but no data and failed to synthesize IPv4 answers,
1127 // don't return the IPv4 answers.
1128 *hpp = nullptr;
1129 }
1130 }
1131
run()1132 void DnsProxyListener::GetHostByNameHandler::run() {
1133 Stopwatch s;
1134 maybeFixupNetContext(&mNetContext, mClient->getPid());
1135 const uid_t uid = mClient->getUid();
1136 hostent* hp = nullptr;
1137 hostent hbuf;
1138 char tmpbuf[MAXPACKET];
1139 int32_t rv = 0;
1140 NetworkDnsEventReported event;
1141 initDnsEvent(&event, mNetContext);
1142 if (queryLimiter.start(uid)) {
1143 const char* name = mName.starts_with('^') ? nullptr : mName.c_str();
1144 if (evaluate_domain_name(mNetContext, name)) {
1145 rv = resolv_gethostbyname(name, mAf, &hbuf, tmpbuf, sizeof tmpbuf, &mNetContext, &hp,
1146 &event);
1147 } else {
1148 rv = EAI_SYSTEM;
1149 }
1150 queryLimiter.finish(uid);
1151 } else {
1152 rv = EAI_MEMORY;
1153 LOG(ERROR) << "GetHostByNameHandler::run: from UID " << uid
1154 << ", max concurrent queries reached";
1155 }
1156
1157 doDns64Synthesis(&rv, &hbuf, tmpbuf, sizeof tmpbuf, &hp, &event);
1158 const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
1159 event.set_latency_micros(latencyUs);
1160 event.set_event_type(EVENT_GETHOSTBYNAME);
1161
1162 if (rv) {
1163 LOG(DEBUG) << "GetHostByNameHandler::run: result failed: " << gai_strerror(rv);
1164 }
1165
1166 bool success = true;
1167 if (hp) {
1168 // hp is not nullptr iff. rv is 0.
1169 success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
1170 success &= sendhostent(mClient, hp);
1171 } else {
1172 success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, nullptr, 0) == 0;
1173 }
1174
1175 if (!success) {
1176 PLOG(WARNING) << "GetHostByNameHandler::run: Error writing DNS result to client uid " << uid
1177 << " pid " << mClient->getPid();
1178 }
1179
1180 std::vector<std::string> ip_addrs;
1181 const int total_ip_addr_count = extractGetHostByNameAnswers(hp, &ip_addrs);
1182 reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYNAME, mNetContext, latencyUs, rv, event,
1183 mName, ip_addrs, total_ip_addr_count);
1184 }
1185
threadName()1186 std::string DnsProxyListener::GetHostByNameHandler::threadName() {
1187 return makeThreadName(mNetContext.dns_netid, mClient->getUid());
1188 }
1189
1190 /*******************************************************
1191 * GetHostByAddr *
1192 *******************************************************/
GetHostByAddrCmd()1193 DnsProxyListener::GetHostByAddrCmd::GetHostByAddrCmd() : FrameworkCommand("gethostbyaddr") {}
1194
runCommand(SocketClient * cli,int argc,char ** argv)1195 int DnsProxyListener::GetHostByAddrCmd::runCommand(SocketClient* cli, int argc, char** argv) {
1196 logArguments(argc, argv);
1197
1198 if (argc != 5) {
1199 char* msg = nullptr;
1200 asprintf(&msg, "Invalid number of arguments to gethostbyaddr: %i", argc);
1201 LOG(WARNING) << "GetHostByAddrCmd::runCommand: " << (msg ? msg : "null");
1202 cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
1203 free(msg);
1204 return -1;
1205 }
1206
1207 char* addrStr = argv[1];
1208 int addrLen = strtol(argv[2], nullptr, 10);
1209 int addrFamily = strtol(argv[3], nullptr, 10);
1210 uid_t uid = cli->getUid();
1211 unsigned netId = strtoul(argv[4], nullptr, 10);
1212 const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
1213
1214 in6_addr addr;
1215 errno = 0;
1216 int result = inet_pton(addrFamily, addrStr, &addr);
1217 if (result <= 0) {
1218 char* msg = nullptr;
1219 asprintf(&msg, "inet_pton(\"%s\") failed %s", addrStr, strerror(errno));
1220 LOG(WARNING) << "GetHostByAddrCmd::runCommand: " << (msg ? msg : "null");
1221 cli->sendMsg(ResponseCode::OperationFailed, msg, false);
1222 free(msg);
1223 return -1;
1224 }
1225
1226 android_net_context netcontext;
1227 gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
1228
1229 if (useLocalNameservers) {
1230 netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
1231 }
1232
1233 (new GetHostByAddrHandler(cli, addr, addrLen, addrFamily, netcontext))->spawn();
1234 return 0;
1235 }
1236
GetHostByAddrHandler(SocketClient * c,in6_addr address,int addressLen,int addressFamily,const android_net_context & netcontext)1237 DnsProxyListener::GetHostByAddrHandler::GetHostByAddrHandler(SocketClient* c, in6_addr address,
1238 int addressLen, int addressFamily,
1239 const android_net_context& netcontext)
1240 : Handler(c),
1241 mAddress(address),
1242 mAddressLen(addressLen),
1243 mAddressFamily(addressFamily),
1244 mNetContext(netcontext) {}
1245
doDns64ReverseLookup(hostent * hbuf,char * buf,size_t buflen,struct hostent ** hpp,NetworkDnsEventReported * event)1246 void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(hostent* hbuf, char* buf,
1247 size_t buflen,
1248 struct hostent** hpp,
1249 NetworkDnsEventReported* event) {
1250 if (*hpp != nullptr || mAddressFamily != AF_INET6) {
1251 return;
1252 }
1253
1254 netdutils::IPPrefix prefix{};
1255 if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
1256 return;
1257 }
1258
1259 if (!isValidNat64Prefix(prefix)) {
1260 return;
1261 }
1262
1263 struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
1264 struct sockaddr_in6* v6prefix = (struct sockaddr_in6*)&ss;
1265 struct in6_addr v6addr = mAddress;
1266 // Check if address has NAT64 prefix. Only /96 IPv6 NAT64 prefixes are supported
1267 if ((v6addr.s6_addr32[0] != v6prefix->sin6_addr.s6_addr32[0]) ||
1268 (v6addr.s6_addr32[1] != v6prefix->sin6_addr.s6_addr32[1]) ||
1269 (v6addr.s6_addr32[2] != v6prefix->sin6_addr.s6_addr32[2])) {
1270 return;
1271 }
1272
1273 const uid_t uid = mClient->getUid();
1274 if (queryLimiter.start(uid)) {
1275 // Remove NAT64 prefix and do reverse DNS query
1276 struct in_addr v4addr = {.s_addr = v6addr.s6_addr32[3]};
1277 resolv_gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET, hbuf, buf, buflen, &mNetContext, hpp,
1278 event);
1279 queryLimiter.finish(uid);
1280 if (*hpp) {
1281 // Replace IPv4 address with original queried IPv6 address in place. The space has
1282 // reserved by dns_gethtbyaddr() and netbsd_gethostent_r() in
1283 // system/netd/resolv/gethnamaddr.cpp.
1284 // Note that resolv_gethostbyaddr() returns only one entry in result.
1285 memcpy((*hpp)->h_addr_list[0], &v6addr, sizeof(v6addr));
1286 (*hpp)->h_addrtype = AF_INET6;
1287 (*hpp)->h_length = sizeof(struct in6_addr);
1288 }
1289 } else {
1290 LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached";
1291 }
1292 }
1293
run()1294 void DnsProxyListener::GetHostByAddrHandler::run() {
1295 Stopwatch s;
1296 maybeFixupNetContext(&mNetContext, mClient->getPid());
1297 const uid_t uid = mClient->getUid();
1298 hostent* hp = nullptr;
1299 hostent hbuf;
1300 char tmpbuf[MAXPACKET];
1301 int32_t rv = 0;
1302 NetworkDnsEventReported event;
1303 initDnsEvent(&event, mNetContext);
1304 if (queryLimiter.start(uid)) {
1305 rv = resolv_gethostbyaddr(&mAddress, mAddressLen, mAddressFamily, &hbuf, tmpbuf,
1306 sizeof tmpbuf, &mNetContext, &hp, &event);
1307 queryLimiter.finish(uid);
1308 } else {
1309 rv = EAI_MEMORY;
1310 LOG(ERROR) << "GetHostByAddrHandler::run: from UID " << uid
1311 << ", max concurrent queries reached";
1312 }
1313
1314 doDns64ReverseLookup(&hbuf, tmpbuf, sizeof tmpbuf, &hp, &event);
1315 const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
1316 event.set_latency_micros(latencyUs);
1317 event.set_event_type(EVENT_GETHOSTBYADDR);
1318
1319 if (rv) {
1320 LOG(DEBUG) << "GetHostByAddrHandler::run: result failed: " << gai_strerror(rv);
1321 }
1322
1323 bool success = true;
1324 if (hp) {
1325 success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
1326 success &= sendhostent(mClient, hp);
1327 } else {
1328 success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, nullptr, 0) == 0;
1329 }
1330
1331 if (!success) {
1332 PLOG(WARNING) << "GetHostByAddrHandler::run: Error writing DNS result to client uid " << uid
1333 << " pid " << mClient->getPid();
1334 }
1335
1336 reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYADDR, mNetContext, latencyUs, rv, event,
1337 (hp && hp->h_name) ? hp->h_name : "null", {}, 0);
1338 }
1339
threadName()1340 std::string DnsProxyListener::GetHostByAddrHandler::threadName() {
1341 return makeThreadName(mNetContext.dns_netid, mClient->getUid());
1342 }
1343
1344 } // namespace net
1345 } // namespace android
1346