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