• 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 <dlfcn.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/parseint.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/Stopwatch.h>
44 #include <netdutils/ThreadUtil.h>
45 #include <private/android_filesystem_config.h>  // AID_SYSTEM
46 #include <statslog_resolv.h>
47 #include <sysutils/SocketClient.h>
48 
49 #include "DnsResolver.h"
50 #include "Experiments.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 #include "util.h"
64 
65 using aidl::android::net::metrics::INetdEventListener;
66 using aidl::android::net::resolv::aidl::DnsHealthEventParcel;
67 using aidl::android::net::resolv::aidl::IDnsResolverUnsolicitedEventListener;
68 using android::base::ParseInt;
69 using android::base::ParseUint;
70 using std::span;
71 
72 namespace android {
73 
74 using netdutils::MAX_QUERIES_IN_TOTAL;
75 using netdutils::MAX_QUERIES_PER_UID;
76 using netdutils::ResponseCode;
77 using netdutils::Stopwatch;
78 
79 namespace net {
80 namespace {
81 
82 android::netdutils::OperationLimiter<uid_t> queryLimiter(MAX_QUERIES_PER_UID);
83 
startQueryLimiter(uid_t uid)84 bool startQueryLimiter(uid_t uid) {
85     const int globalLimit = android::net::Experiments::getInstance()->getFlag("max_queries_global",
86                                                                               MAX_QUERIES_IN_TOTAL);
87     return queryLimiter.start(uid, globalLimit);
88 }
89 
endQueryLimiter(uid_t uid)90 void endQueryLimiter(uid_t uid) {
91     queryLimiter.finish(uid);
92 }
93 
logArguments(int argc,char ** argv)94 void logArguments(int argc, char** argv) {
95     if (!WOULD_LOG(VERBOSE)) return;
96     for (int i = 0; i < argc; i++) {
97         LOG(VERBOSE) << __func__ << ": argv[" << i << "]=" << (argv[i] ? argv[i] : "null");
98     }
99 }
100 
checkAndClearUseLocalNameserversFlag(unsigned * netid)101 bool checkAndClearUseLocalNameserversFlag(unsigned* netid) {
102     if (netid == nullptr || ((*netid) & NETID_USE_LOCAL_NAMESERVERS) == 0) {
103         return false;
104     }
105     *netid = (*netid) & ~NETID_USE_LOCAL_NAMESERVERS;
106     return true;
107 }
108 
requestingUseLocalNameservers(unsigned flags)109 constexpr bool requestingUseLocalNameservers(unsigned flags) {
110     return (flags & NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS) != 0;
111 }
112 
queryingViaTls(unsigned dns_netid)113 bool queryingViaTls(unsigned dns_netid) {
114     const auto privateDnsStatus = PrivateDnsConfiguration::getInstance().getStatus(dns_netid);
115     switch (privateDnsStatus.mode) {
116         case PrivateDnsMode::OPPORTUNISTIC:
117             return !privateDnsStatus.validatedServers().empty();
118         case PrivateDnsMode::STRICT:
119             return true;
120         default:
121             return false;
122     }
123 }
124 
hasPermissionToBypassPrivateDns(uid_t uid)125 bool hasPermissionToBypassPrivateDns(uid_t uid) {
126     static_assert(AID_SYSTEM >= 0 && AID_SYSTEM < FIRST_APPLICATION_UID,
127                   "Calls from AID_SYSTEM must not result in a permission check to avoid deadlock.");
128     if (uid >= 0 && uid < FIRST_APPLICATION_UID) {
129         return true;
130     }
131 
132     for (const char* const permission :
133          {PERM_CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERM_NETWORK_BYPASS_PRIVATE_DNS,
134           PERM_MAINLINE_NETWORK_STACK}) {
135         if (gResNetdCallbacks.check_calling_permission(permission)) {
136             return true;
137         }
138     }
139     return false;
140 }
141 
maybeFixupNetContext(android_net_context * ctx,pid_t pid)142 void maybeFixupNetContext(android_net_context* ctx, pid_t pid) {
143     if (requestingUseLocalNameservers(ctx->flags) && !hasPermissionToBypassPrivateDns(ctx->uid)) {
144         // Not permitted; clear the flag.
145         ctx->flags &= ~NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
146     }
147 
148     if (!requestingUseLocalNameservers(ctx->flags)) {
149         // If we're not explicitly bypassing DNS-over-TLS servers, check whether
150         // DNS-over-TLS is in use as an indicator for when to use more modern
151         // DNS resolution mechanics.
152         if (queryingViaTls(ctx->dns_netid)) {
153             ctx->flags |= NET_CONTEXT_FLAG_USE_DNS_OVER_TLS | NET_CONTEXT_FLAG_USE_EDNS;
154         }
155     }
156     ctx->pid = pid;
157 }
158 
159 void addIpAddrWithinLimit(std::vector<std::string>* ip_addrs, const sockaddr* addr,
160                           socklen_t addrlen);
161 
extractResNsendAnswers(std::span<const uint8_t> answer,int ipType,std::vector<std::string> * ip_addrs)162 int extractResNsendAnswers(std::span<const uint8_t> answer, int ipType,
163                            std::vector<std::string>* ip_addrs) {
164     int total_ip_addr_count = 0;
165     ns_msg handle;
166     if (ns_initparse(answer.data(), answer.size(), &handle) < 0) {
167         return 0;
168     }
169     int ancount = ns_msg_count(handle, ns_s_an);
170     ns_rr rr;
171     for (int i = 0; i < ancount; i++) {
172         if (ns_parserr(&handle, ns_s_an, i, &rr) < 0) {
173             continue;
174         }
175         const uint8_t* rdata = ns_rr_rdata(rr);
176         if (ipType == ns_t_a) {
177             sockaddr_in sin = {.sin_family = AF_INET};
178             memcpy(&sin.sin_addr, rdata, sizeof(sin.sin_addr));
179             addIpAddrWithinLimit(ip_addrs, (sockaddr*)&sin, sizeof(sin));
180             total_ip_addr_count++;
181         } else if (ipType == ns_t_aaaa) {
182             sockaddr_in6 sin6 = {.sin6_family = AF_INET6};
183             memcpy(&sin6.sin6_addr, rdata, sizeof(sin6.sin6_addr));
184             addIpAddrWithinLimit(ip_addrs, (sockaddr*)&sin6, sizeof(sin6));
185             total_ip_addr_count++;
186         }
187     }
188 
189     return total_ip_addr_count;
190 }
191 
extractGetAddrInfoAnswers(const addrinfo * result,std::vector<std::string> * ip_addrs)192 int extractGetAddrInfoAnswers(const addrinfo* result, std::vector<std::string>* ip_addrs) {
193     int total_ip_addr_count = 0;
194     if (result == nullptr) {
195         return 0;
196     }
197     for (const addrinfo* ai = result; ai; ai = ai->ai_next) {
198         sockaddr* ai_addr = ai->ai_addr;
199         if (ai_addr) {
200             addIpAddrWithinLimit(ip_addrs, ai_addr, ai->ai_addrlen);
201             total_ip_addr_count++;
202         }
203     }
204     return total_ip_addr_count;
205 }
206 
extractGetHostByNameAnswers(const hostent * hp,std::vector<std::string> * ip_addrs)207 int extractGetHostByNameAnswers(const hostent* hp, std::vector<std::string>* ip_addrs) {
208     int total_ip_addr_count = 0;
209     if (hp == nullptr) {
210         return 0;
211     }
212     if (hp->h_addrtype == AF_INET) {
213         in_addr** list = (in_addr**)hp->h_addr_list;
214         for (int i = 0; list[i] != nullptr; i++) {
215             sockaddr_in sin = {.sin_family = AF_INET, .sin_addr = *list[i]};
216             addIpAddrWithinLimit(ip_addrs, (sockaddr*)&sin, sizeof(sin));
217             total_ip_addr_count++;
218         }
219     } else if (hp->h_addrtype == AF_INET6) {
220         in6_addr** list = (in6_addr**)hp->h_addr_list;
221         for (int i = 0; list[i] != nullptr; i++) {
222             sockaddr_in6 sin6 = {.sin6_family = AF_INET6, .sin6_addr = *list[i]};
223             addIpAddrWithinLimit(ip_addrs, (sockaddr*)&sin6, sizeof(sin6));
224             total_ip_addr_count++;
225         }
226     }
227     return total_ip_addr_count;
228 }
229 
rcodeToAiError(int rcode)230 int rcodeToAiError(int rcode) {
231     switch (rcode) {
232         case NOERROR:
233             return 0;
234         case RCODE_TIMEOUT:
235             return NETD_RESOLV_TIMEOUT;
236         default:
237             return EAI_NODATA;
238     }
239 }
240 
resNSendToAiError(int err,int rcode)241 int resNSendToAiError(int err, int rcode) {
242     if (err > 0) {
243         return rcodeToAiError(rcode);
244     }
245     if (err == -ETIMEDOUT) {
246         return NETD_RESOLV_TIMEOUT;
247     }
248     return EAI_SYSTEM;
249 }
250 
setQueryId(span<uint8_t> msg,uint16_t query_id)251 bool setQueryId(span<uint8_t> msg, uint16_t query_id) {
252     if ((size_t)msg.size() < sizeof(HEADER)) {
253         LOG(ERROR) << __func__ << ": Invalid parameter";
254         return false;
255     }
256     auto hp = reinterpret_cast<HEADER*>(msg.data());
257     hp->id = htons(query_id);
258     return true;
259 }
260 
parseQuery(span<const uint8_t> msg,uint16_t * query_id,int * rr_type,std::string * rr_name)261 bool parseQuery(span<const uint8_t> msg, uint16_t* query_id, int* rr_type, std::string* rr_name) {
262     ns_msg handle;
263     ns_rr rr;
264     if (ns_initparse(msg.data(), msg.size(), &handle) < 0 ||
265         ns_parserr(&handle, ns_s_qd, 0, &rr) < 0) {
266         return false;
267     }
268     *query_id = ns_msg_id(handle);
269     *rr_name = ns_rr_name(rr);
270     *rr_type = ns_rr_type(rr);
271     return true;
272 }
273 
274 // Note: Even if it returns PDM_OFF, it doesn't mean there's no DoT stats in the message
275 // because Private DNS mode can change at any time.
getPrivateDnsModeForMetrics(uint32_t netId)276 PrivateDnsModes getPrivateDnsModeForMetrics(uint32_t netId) {
277     // If the network `netId` doesn't exist, getStatus() sets the mode to PrivateDnsMode::OFF and
278     // returns it. This is incorrect for the metrics. Consider returning PDM_UNKNOWN in such case.
279     return convertEnumType(PrivateDnsConfiguration::getInstance().getStatus(netId).mode);
280 }
281 
initDnsEvent(NetworkDnsEventReported * event,const android_net_context & netContext)282 void initDnsEvent(NetworkDnsEventReported* event, const android_net_context& netContext) {
283     // The value 0 has the special meaning of unset/unknown in Statsd atoms. So, we set both
284     // flags to -1 as default value.
285     //  1. The hints flag is only used in resolv_getaddrinfo. When user set it to -1 in
286     //     resolv_getaddrinfo, the flag will cause validation (validateHints) failure in
287     //     getaddrinfo, so it will not do DNS query and will upload DNS stats log with
288     //     return_code = RC_EAI_BADFLAGS.
289     //  2. The res_nsend flags are only used in resolv_res_nsend. When user set it to -1 in
290     //     resolv_res_nsend,res_nsend will do nothing special by the setting.
291     event->set_hints_ai_flags(-1);
292     event->set_res_nsend_flags(-1);
293     event->set_private_dns_modes(getPrivateDnsModeForMetrics(netContext.dns_netid));
294 }
295 
296 // Return 0 if the event should not be logged.
297 // Otherwise, return subsampling_denom
getDnsEventSubsamplingRate(int netid,int returnCode,bool isMdns)298 uint32_t getDnsEventSubsamplingRate(int netid, int returnCode, bool isMdns) {
299     uint32_t subsampling_denom = resolv_cache_get_subsampling_denom(netid, returnCode, isMdns);
300     if (subsampling_denom == 0) return 0;
301     // Sample the event with a chance of 1 / denom.
302     return (arc4random_uniform(subsampling_denom) == 0) ? subsampling_denom : 0;
303 }
304 
maybeLogQuery(int eventType,const android_net_context & netContext,const NetworkDnsEventReported & event,const std::string & query_name,const std::vector<std::string> & ip_addrs)305 void maybeLogQuery(int eventType, const android_net_context& netContext,
306                    const NetworkDnsEventReported& event, const std::string& query_name,
307                    const std::vector<std::string>& ip_addrs) {
308     // Skip reverse queries.
309     if (eventType == INetdEventListener::EVENT_GETHOSTBYADDR) return;
310 
311     for (const auto& query : event.dns_query_events().dns_query_event()) {
312         // Log it when the cache misses.
313         if (query.cache_hit() != CS_FOUND) {
314             const int timeTakenMs = event.latency_micros() / 1000;
315             DnsQueryLog::Record record(netContext.dns_netid, netContext.uid, netContext.pid,
316                                        query_name, ip_addrs, timeTakenMs);
317             gDnsResolv->dnsQueryLog().push(std::move(record));
318             return;
319         }
320     }
321 }
322 
reportDnsEvent(int eventType,const android_net_context & netContext,int latencyUs,int returnCode,NetworkDnsEventReported & event,const std::string & query_name,bool skipStats,const std::vector<std::string> & ip_addrs={},int total_ip_addr_count=0)323 void reportDnsEvent(int eventType, const android_net_context& netContext, int latencyUs,
324                     int returnCode, NetworkDnsEventReported& event, const std::string& query_name,
325                     bool skipStats, const std::vector<std::string>& ip_addrs = {},
326                     int total_ip_addr_count = 0) {
327     int32_t rate =
328             skipStats ? 0
329             : (query_name.ends_with(".local") && is_mdns_supported_network(netContext.dns_netid) &&
330                android::net::Experiments::getInstance()->getFlag("mdns_resolution", 1))
331                     ? getDnsEventSubsamplingRate(netContext.dns_netid, returnCode, true)
332                     : getDnsEventSubsamplingRate(netContext.dns_netid, returnCode, false);
333 
334     if (rate) {
335         const std::string& dnsQueryStats = event.dns_query_events().SerializeAsString();
336         stats::BytesField dnsQueryBytesField{dnsQueryStats.c_str(), dnsQueryStats.size()};
337         event.set_return_code(static_cast<ReturnCode>(returnCode));
338         event.set_network_type(resolv_get_network_types_for_net(netContext.dns_netid));
339         event.set_uid(netContext.uid);
340         android::net::stats::stats_write(
341                 android::net::stats::NETWORK_DNS_EVENT_REPORTED, event.event_type(),
342                 event.return_code(), event.latency_micros(), event.hints_ai_flags(),
343                 event.res_nsend_flags(), event.network_type(), event.private_dns_modes(),
344                 dnsQueryBytesField, rate, event.uid());
345     }
346 
347     maybeLogQuery(eventType, netContext, event, query_name, ip_addrs);
348 
349     const auto& listeners = ResolverEventReporter::getInstance().getListeners();
350     if (listeners.empty()) {
351         LOG(ERROR) << __func__
352                    << ": DNS event not sent since no INetdEventListener receiver is available.";
353     }
354     const int latencyMs = latencyUs / 1000;
355     for (const auto& it : listeners) {
356         it->onDnsEvent(netContext.dns_netid, eventType, returnCode, latencyMs, query_name, ip_addrs,
357                        total_ip_addr_count, netContext.uid);
358     }
359 
360     const auto& unsolEventListeners = ResolverEventReporter::getInstance().getUnsolEventListeners();
361 
362     if (returnCode == NETD_RESOLV_TIMEOUT) {
363         const DnsHealthEventParcel dnsHealthEvent = {
364                 .netId = static_cast<int32_t>(netContext.dns_netid),
365                 .healthResult = IDnsResolverUnsolicitedEventListener::DNS_HEALTH_RESULT_TIMEOUT,
366         };
367         for (const auto& it : unsolEventListeners) {
368             it->onDnsHealthEvent(dnsHealthEvent);
369         }
370     } else if (returnCode == NOERROR) {
371         DnsHealthEventParcel dnsHealthEvent = {
372                 .netId = static_cast<int32_t>(netContext.dns_netid),
373                 .healthResult = IDnsResolverUnsolicitedEventListener::DNS_HEALTH_RESULT_OK,
374         };
375         for (const auto& query : event.dns_query_events().dns_query_event()) {
376             if (query.cache_hit() != CS_FOUND && query.rcode() == NS_R_NO_ERROR) {
377                 dnsHealthEvent.successRttMicros.push_back(query.latency_micros());
378             }
379         }
380 
381         if (!dnsHealthEvent.successRttMicros.empty()) {
382             for (const auto& it : unsolEventListeners) {
383                 it->onDnsHealthEvent(dnsHealthEvent);
384             }
385         }
386     }
387 }
388 
onlyIPv4Answers(const addrinfo * res)389 bool onlyIPv4Answers(const addrinfo* res) {
390     // Null addrinfo pointer isn't checked because the caller doesn't pass null pointer.
391 
392     for (const addrinfo* ai = res; ai; ai = ai->ai_next)
393         if (ai->ai_family != AF_INET) return false;
394 
395     return true;
396 }
397 
isSpecialUseIPv4Address(const struct in_addr & ia)398 bool isSpecialUseIPv4Address(const struct in_addr& ia) {
399     const uint32_t addr = ntohl(ia.s_addr);
400 
401     // Only check necessary IP ranges in RFC 5735 section 4
402     return ((addr & 0xff000000) == 0x00000000) ||  // "This" Network
403            ((addr & 0xff000000) == 0x7f000000) ||  // Loopback
404            ((addr & 0xffff0000) == 0xa9fe0000) ||  // Link Local
405            ((addr & 0xf0000000) == 0xe0000000) ||  // Multicast
406            (addr == INADDR_BROADCAST);             // Limited Broadcast
407 }
408 
isSpecialUseIPv4Address(const struct sockaddr * sa)409 bool isSpecialUseIPv4Address(const struct sockaddr* sa) {
410     if (sa->sa_family != AF_INET) return false;
411 
412     return isSpecialUseIPv4Address(((struct sockaddr_in*)sa)->sin_addr);
413 }
414 
onlyNonSpecialUseIPv4Addresses(struct hostent * hp)415 bool onlyNonSpecialUseIPv4Addresses(struct hostent* hp) {
416     // Null hostent pointer isn't checked because the caller doesn't pass null pointer.
417 
418     if (hp->h_addrtype != AF_INET) return false;
419 
420     for (int i = 0; hp->h_addr_list[i] != nullptr; i++)
421         if (isSpecialUseIPv4Address(*(struct in_addr*)hp->h_addr_list[i])) return false;
422 
423     return true;
424 }
425 
onlyNonSpecialUseIPv4Addresses(const addrinfo * res)426 bool onlyNonSpecialUseIPv4Addresses(const addrinfo* res) {
427     // Null addrinfo pointer isn't checked because the caller doesn't pass null pointer.
428 
429     for (const addrinfo* ai = res; ai; ai = ai->ai_next) {
430         if (ai->ai_family != AF_INET) return false;
431         if (isSpecialUseIPv4Address(ai->ai_addr)) return false;
432     }
433 
434     return true;
435 }
436 
logDnsQueryResult(const struct hostent * hp)437 void logDnsQueryResult(const struct hostent* hp) {
438     if (!WOULD_LOG(DEBUG)) return;
439     if (hp == nullptr) return;
440 
441     LOG(DEBUG) << __func__ << ": DNS records:";
442     for (int i = 0; hp->h_addr_list[i] != nullptr; i++) {
443         char ip_addr[INET6_ADDRSTRLEN];
444         if (inet_ntop(hp->h_addrtype, hp->h_addr_list[i], ip_addr, sizeof(ip_addr)) != nullptr) {
445             LOG(DEBUG) << __func__ << ": [" << i << "] " << hp->h_addrtype;
446         } else {
447             PLOG(DEBUG) << __func__ << ": [" << i << "] numeric hostname translation fail";
448         }
449     }
450 }
451 
logDnsQueryResult(const addrinfo * res)452 void logDnsQueryResult(const addrinfo* res) {
453     if (!WOULD_LOG(DEBUG)) return;
454     if (res == nullptr) return;
455 
456     int i;
457     const addrinfo* ai;
458     LOG(DEBUG) << __func__ << ": DNS records:";
459     for (ai = res, i = 0; ai; ai = ai->ai_next, i++) {
460         if ((ai->ai_family != AF_INET) && (ai->ai_family != AF_INET6)) continue;
461         // Reassign it to a local variable to avoid -Wnullable-to-nonnull-conversion on calling
462         // getnameinfo.
463         const sockaddr* ai_addr = ai->ai_addr;
464         char ip_addr[INET6_ADDRSTRLEN];
465         const int ret = getnameinfo(ai_addr, ai->ai_addrlen, ip_addr, sizeof(ip_addr), nullptr, 0,
466                                     NI_NUMERICHOST);
467         if (!ret) {
468             LOG(DEBUG) << __func__ << ": [" << i << "] " << ai->ai_flags << " " << ai->ai_family
469                        << " " << ai->ai_socktype << " " << ai->ai_protocol << " " << ip_addr;
470         } else {
471             LOG(DEBUG) << __func__ << ": [" << i << "] numeric hostname translation fail " << ret;
472         }
473     }
474 }
475 
isValidNat64Prefix(const netdutils::IPPrefix prefix)476 bool isValidNat64Prefix(const netdutils::IPPrefix prefix) {
477     if (prefix.family() != AF_INET6) {
478         LOG(ERROR) << __func__ << ": Only IPv6 NAT64 prefixes are supported " << prefix.family();
479         return false;
480     }
481     if (prefix.length() != 96) {
482         LOG(ERROR) << __func__ << ": Only /96 NAT64 prefixes are supported " << prefix.length();
483         return false;
484     }
485     return true;
486 }
487 
synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix & prefix,struct hostent * hp)488 bool synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix& prefix, struct hostent* hp) {
489     if (hp == nullptr) return false;
490     if (!onlyNonSpecialUseIPv4Addresses(hp)) return false;
491     if (!isValidNat64Prefix(prefix)) return false;
492 
493     struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
494     struct sockaddr_in6* v6prefix = (struct sockaddr_in6*)&ss;
495     for (int i = 0; hp->h_addr_list[i] != nullptr; i++) {
496         struct in_addr iaOriginal = *(struct in_addr*)hp->h_addr_list[i];
497         struct in6_addr* ia6 = (struct in6_addr*)hp->h_addr_list[i];
498         memset(ia6, 0, sizeof(struct in6_addr));
499 
500         // Synthesize /96 NAT64 prefix in place. The space has reserved by getanswer() and
501         // _hf_gethtbyname2() in system/netd/resolv/gethnamaddr.cpp and
502         // system/netd/resolv/sethostent.cpp.
503         *ia6 = v6prefix->sin6_addr;
504         ia6->s6_addr32[3] = iaOriginal.s_addr;
505 
506         if (WOULD_LOG(VERBOSE)) {
507             char buf[INET6_ADDRSTRLEN];  // big enough for either IPv4 or IPv6
508             inet_ntop(AF_INET, &iaOriginal.s_addr, buf, sizeof(buf));
509             LOG(VERBOSE) << __func__ << ": DNS A record: " << buf;
510             inet_ntop(AF_INET6, &v6prefix->sin6_addr, buf, sizeof(buf));
511             LOG(VERBOSE) << __func__ << ": NAT64 prefix: " << buf;
512             inet_ntop(AF_INET6, ia6, buf, sizeof(buf));
513             LOG(VERBOSE) << __func__ << ": DNS64 Synthesized AAAA record: " << buf;
514         }
515     }
516     hp->h_addrtype = AF_INET6;
517     hp->h_length = sizeof(in6_addr);
518 
519     logDnsQueryResult(hp);
520     return true;
521 }
522 
synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix & prefix,addrinfo ** res,bool unspecWantedButNoIPv6,const android_net_context * netcontext)523 bool synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix& prefix, addrinfo** res,
524                                       bool unspecWantedButNoIPv6,
525                                       const android_net_context* netcontext) {
526     if (*res == nullptr) return false;
527     if (!onlyNonSpecialUseIPv4Addresses(*res)) return false;
528     if (!isValidNat64Prefix(prefix)) return false;
529 
530     const sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
531     const sockaddr_in6* v6prefix = (sockaddr_in6*)&ss;
532     addrinfo* const head4 = *res;
533     addrinfo* head6 = nullptr;
534     addrinfo* cur6 = nullptr;
535 
536     // Build a synthesized AAAA addrinfo list from the queried A addrinfo list. Here is the diagram
537     // for the relationship of pointers.
538     //
539     // head4: point to the first queried A addrinfo
540     // |
541     // v
542     // +-------------+   +-------------+
543     // | addrinfo4#1 |-->| addrinfo4#2 |--> .. queried A addrinfo(s) for DNS64 synthesis
544     // +-------------+   +-------------+
545     //                   ^
546     //                   |
547     //                   cur4: current worked-on queried A addrinfo
548     //
549     // head6: point to the first synthesized AAAA addrinfo
550     // |
551     // v
552     // +-------------+   +-------------+
553     // | addrinfo6#1 |-->| addrinfo6#2 |--> .. synthesized DNS64 AAAA addrinfo(s)
554     // +-------------+   +-------------+
555     //                   ^
556     //                   |
557     //                   cur6: current worked-on synthesized addrinfo
558     //
559     for (const addrinfo* cur4 = head4; cur4; cur4 = cur4->ai_next) {
560         // Allocate a space for a synthesized AAAA addrinfo. Note that the addrinfo and sockaddr
561         // occupy one contiguous block of memory and are allocated and freed as a single block.
562         // See get_ai and freeaddrinfo in packages/modules/DnsResolver/getaddrinfo.cpp.
563         addrinfo* sa = (addrinfo*)calloc(1, sizeof(addrinfo) + sizeof(sockaddr_in6));
564         if (sa == nullptr) {
565             LOG(ERROR) << "allocate memory failed for synthesized result";
566             freeaddrinfo(head6);
567             return false;
568         }
569 
570         // Initialize the synthesized AAAA addrinfo by the queried A addrinfo. The ai_addr will be
571         // set lately.
572         sa->ai_flags = cur4->ai_flags;
573         sa->ai_family = AF_INET6;
574         sa->ai_socktype = cur4->ai_socktype;
575         sa->ai_protocol = cur4->ai_protocol;
576         sa->ai_addrlen = sizeof(sockaddr_in6);
577         sa->ai_addr = (sockaddr*)(sa + 1);
578         sa->ai_canonname = nullptr;
579         sa->ai_next = nullptr;
580 
581         if (cur4->ai_canonname != nullptr) {
582             // Reassign it to a local variable to avoid -Wnullable-to-nonnull-conversion on calling
583             // strdup.
584             const char* ai_canonname = cur4->ai_canonname;
585             sa->ai_canonname = strdup(ai_canonname);
586             if (sa->ai_canonname == nullptr) {
587                 LOG(ERROR) << "allocate memory failed for canonname";
588                 freeaddrinfo(sa);
589                 freeaddrinfo(head6);
590                 return false;
591             }
592         }
593 
594         // Synthesize /96 NAT64 prefix with the queried IPv4 address.
595         const sockaddr_in* sin4 = (sockaddr_in*)cur4->ai_addr;
596         sockaddr_in6* sin6 = (sockaddr_in6*)sa->ai_addr;
597         sin6->sin6_addr = v6prefix->sin6_addr;
598         sin6->sin6_addr.s6_addr32[3] = sin4->sin_addr.s_addr;
599         sin6->sin6_family = AF_INET6;
600         sin6->sin6_port = sin4->sin_port;
601 
602         // If the synthesized list is empty, this becomes the first element.
603         if (head6 == nullptr) {
604             head6 = sa;
605         }
606 
607         // Add this element to the end of the synthesized list.
608         if (cur6 != nullptr) {
609             cur6->ai_next = sa;
610         }
611         cur6 = sa;
612 
613         if (WOULD_LOG(VERBOSE)) {
614             char buf[INET6_ADDRSTRLEN];  // big enough for either IPv4 or IPv6
615             inet_ntop(AF_INET, &sin4->sin_addr.s_addr, buf, sizeof(buf));
616             LOG(VERBOSE) << __func__ << ": DNS A record: " << buf;
617             inet_ntop(AF_INET6, &v6prefix->sin6_addr, buf, sizeof(buf));
618             LOG(VERBOSE) << __func__ << ": NAT64 prefix: " << buf;
619             inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof(buf));
620             LOG(VERBOSE) << __func__ << ": DNS64 Synthesized AAAA record: " << buf;
621         }
622     }
623 
624     // Simply concatenate the synthesized AAAA addrinfo list and the queried A addrinfo list when
625     // AF_UNSPEC is specified. In the other words, the IPv6 addresses are listed first and then
626     // IPv4 addresses. For example:
627     //     64:ff9b::102:304 (socktype=2, protocol=17) ->
628     //     64:ff9b::102:304 (socktype=1, protocol=6) ->
629     //     1.2.3.4 (socktype=2, protocol=17) ->
630     //     1.2.3.4 (socktype=1, protocol=6)
631     // Note that head6 and cur6 should be non-null because there was at least one IPv4 address
632     // synthesized. From the above example, the synthesized addrinfo list puts IPv6 and IPv4 in
633     // groups and sort by RFC 6724 later. This ordering is different from no synthesized case
634     // because resolv_getaddrinfo() sorts results in explore_options. resolv_getaddrinfo() calls
635     // explore_fqdn() many times by the different items of explore_options. It means that
636     // resolv_rfc6724_sort() only sorts the results in each explore_options and concatenates each
637     // results into one. For example, getaddrinfo() is called with null hints for a domain name
638     // which has both IPv4 and IPv6 addresses. The address order of the result addrinfo may be:
639     //     2001:db8::102:304 (socktype=2, protocol=17) -> 1.2.3.4 (socktype=2, protocol=17) ->
640     //     2001:db8::102:304 (socktype=1, protocol=6) -> 1.2.3.4 (socktype=1, protocol=6)
641     // In above example, the first two results come from one explore option and the last two come
642     // from another one. They are sorted first, and then concatenate together to be the result.
643     // See also resolv_getaddrinfo in packages/modules/DnsResolver/getaddrinfo.cpp.
644     if (unspecWantedButNoIPv6) {
645         cur6->ai_next = head4;
646     } else {
647         freeaddrinfo(head4);
648     }
649 
650     // Sort the concatenated addresses by RFC 6724 section 2.1.
651     struct addrinfo sorting_head = {.ai_next = head6};
652     resolv_rfc6724_sort(&sorting_head, netcontext->app_mark, netcontext->uid);
653 
654     *res = sorting_head.ai_next;
655     logDnsQueryResult(*res);
656     return true;
657 }
658 
getDns64Prefix(unsigned netId,netdutils::IPPrefix * prefix)659 bool getDns64Prefix(unsigned netId, netdutils::IPPrefix* prefix) {
660     return !gDnsResolv->resolverCtrl.getPrefix64(netId, prefix);
661 }
662 
makeThreadName(unsigned netId,uint32_t uid)663 std::string makeThreadName(unsigned netId, uint32_t uid) {
664     // The maximum of netId and app_id are 5-digit numbers.
665     return fmt::format("Dns_{}_{}", netId, multiuser_get_app_id(uid));
666 }
667 
668 typedef int (*InitFn)();
669 typedef int (*IsUidBlockedFn)(uid_t, bool);
670 
671 IsUidBlockedFn ADnsHelper_isUidNetworkingBlocked;
672 
resolveIsUidNetworkingBlockedFn()673 IsUidBlockedFn resolveIsUidNetworkingBlockedFn() {
674     // Related BPF maps were mainlined from T, but we want to init on S too.
675     if (!isAtLeastS()) return nullptr;
676 
677     // TODO: Check whether it is safe to shared link the .so without using dlopen when the carrier
678     // APEX module (tethering) is fully released.
679     void* handle = dlopen("libcom.android.tethering.dns_helper.so", RTLD_NOW | RTLD_LOCAL);
680     if (!handle) {
681         // Can happen if the tethering apex is ancient.
682         LOG(WARNING) << __func__ << ": " << dlerror();
683         return nullptr;
684     }
685 
686     InitFn ADnsHelper_init = reinterpret_cast<InitFn>(dlsym(handle, "ADnsHelper_init"));
687     if (!ADnsHelper_init) {
688         LOG(ERROR) << __func__ << ": " << dlerror();
689         abort();
690     }
691     const int ret = (*ADnsHelper_init)();
692     if (ret) {
693         // On S/Sv2 this can fail if tethering apex is too old, ignore it.
694         if (ret == -EOPNOTSUPP && !isAtLeastT()) return nullptr;
695         LOG(ERROR) << __func__ << ": ADnsHelper_init failed " << strerror(-ret);
696         abort();
697     }
698 
699     // Related BPF maps were only mainlined from T.
700     if (!isAtLeastT()) return nullptr;
701 
702     IsUidBlockedFn f =
703             reinterpret_cast<IsUidBlockedFn>(dlsym(handle, "ADnsHelper_isUidNetworkingBlocked"));
704     if (!f) {
705         LOG(ERROR) << __func__ << ": " << dlerror();
706         // TODO: Change to abort() when NDK is finalized
707         return nullptr;
708     }
709     return f;
710 }
711 
isUidNetworkingBlocked(uid_t uid,unsigned netId)712 bool isUidNetworkingBlocked(uid_t uid, unsigned netId) {
713     if (!ADnsHelper_isUidNetworkingBlocked) return false;
714 
715     // The enforceDnsUid is an OEM feature that sets DNS packet with AID_DNS instead of the
716     // application's UID. Its DNS packets are not subject to certain network restriction features.
717     if (resolv_is_enforceDnsUid_enabled_network(netId)) return false;
718 
719     // Feature flag that can disable the feature.
720     if (!android::net::Experiments::getInstance()->getFlag("fail_fast_on_uid_network_blocking",
721                                                            1)) {
722         return false;
723     }
724 
725     return (*ADnsHelper_isUidNetworkingBlocked)(uid, resolv_is_metered_network(netId)) == 1;
726 }
727 
728 }  // namespace
729 
DnsProxyListener()730 DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) {
731     mGetAddrInfoCmd = std::make_unique<GetAddrInfoCmd>();
732     registerCmd(mGetAddrInfoCmd.get());
733 
734     mGetHostByAddrCmd = std::make_unique<GetHostByAddrCmd>();
735     registerCmd(mGetHostByAddrCmd.get());
736 
737     mGetHostByNameCmd = std::make_unique<GetHostByNameCmd>();
738     registerCmd(mGetHostByNameCmd.get());
739 
740     mResNSendCommand = std::make_unique<ResNSendCommand>();
741     registerCmd(mResNSendCommand.get());
742 
743     mGetDnsNetIdCommand = std::make_unique<GetDnsNetIdCommand>();
744     registerCmd(mGetDnsNetIdCommand.get());
745 
746     ADnsHelper_isUidNetworkingBlocked = resolveIsUidNetworkingBlockedFn();
747 }
748 
spawn()749 void DnsProxyListener::Handler::spawn() {
750     const int rval = netdutils::threadLaunch(this);
751     if (rval == 0) {
752         return;
753     }
754 
755     char* msg = nullptr;
756     asprintf(&msg, "%s (%d)", strerror(-rval), -rval);
757     mClient->sendMsg(ResponseCode::OperationFailed, msg, false);
758     free(msg);
759     delete this;
760 }
761 
GetAddrInfoHandler(SocketClient * c,std::string host,std::string service,std::unique_ptr<addrinfo> hints,const android_net_context & netcontext)762 DnsProxyListener::GetAddrInfoHandler::GetAddrInfoHandler(SocketClient* c, std::string host,
763                                                          std::string service,
764                                                          std::unique_ptr<addrinfo> hints,
765                                                          const android_net_context& netcontext)
766     : Handler(c),
767       mHost(std::move(host)),
768       mService(std::move(service)),
769       mHints(std::move(hints)),
770       mNetContext(netcontext) {}
771 
772 DnsProxyListener::GetAddrInfoHandler::~GetAddrInfoHandler() = default;
773 
774 // Before U, the Netd callback is implemented by OEM to evaluate if a DNS query for the provided
775 // hostname is allowed. On U+, the Netd callback also checks if the user is allowed to send DNS on
776 // the specified network.
evaluate_domain_name(const android_net_context & netcontext,const char * host)777 static bool evaluate_domain_name(const android_net_context& netcontext, const char* host) {
778     if (!gResNetdCallbacks.evaluate_domain_name) return true;
779     return gResNetdCallbacks.evaluate_domain_name(netcontext, host);
780 }
781 
HandleArgumentError(SocketClient * cli,int errorcode,std::string strerrormessage,int argc,char ** argv)782 static int HandleArgumentError(SocketClient* cli, int errorcode, std::string strerrormessage,
783                                int argc, char** argv) {
784     for (int i = 0; i < argc; i++) {
785         strerrormessage += "argv[" + std::to_string(i) + "]=" + (argv[i] ? argv[i] : "null") + " ";
786     }
787 
788     LOG(WARNING) << strerrormessage;
789     cli->sendMsg(errorcode, strerrormessage.c_str(), false);
790     return -1;
791 }
792 
sendBE32(SocketClient * c,uint32_t data)793 static bool sendBE32(SocketClient* c, uint32_t data) {
794     uint32_t be_data = htonl(data);
795     return c->sendData(&be_data, sizeof(be_data)) == 0;
796 }
797 
798 // Sends 4 bytes of big-endian length, followed by the data.
799 // Returns true on success.
sendLenAndData(SocketClient * c,const int len,const void * data)800 static bool sendLenAndData(SocketClient* c, const int len, const void* data) {
801     return sendBE32(c, len) && (len == 0 || c->sendData(data, len) == 0);
802 }
803 
804 // Returns true on success
sendhostent(SocketClient * c,hostent * hp)805 static bool sendhostent(SocketClient* c, hostent* hp) {
806     bool success = true;
807     int i;
808     if (hp->h_name != nullptr) {
809         const char* h_name = hp->h_name;
810         success &= sendLenAndData(c, strlen(h_name) + 1, hp->h_name);
811     } else {
812         success &= sendLenAndData(c, 0, "") == 0;
813     }
814 
815     for (i = 0; hp->h_aliases[i] != nullptr; i++) {
816         const char* h_aliases = hp->h_aliases[i];
817         success &= sendLenAndData(c, strlen(h_aliases) + 1, hp->h_aliases[i]);
818     }
819     success &= sendLenAndData(c, 0, "");  // null to indicate we're done
820 
821     uint32_t buf = htonl(hp->h_addrtype);
822     success &= c->sendData(&buf, sizeof(buf)) == 0;
823 
824     buf = htonl(hp->h_length);
825     success &= c->sendData(&buf, sizeof(buf)) == 0;
826 
827     for (i = 0; hp->h_addr_list[i] != nullptr; i++) {
828         success &= sendLenAndData(c, 16, hp->h_addr_list[i]);
829     }
830     success &= sendLenAndData(c, 0, "");  // null to indicate we're done
831     return success;
832 }
833 
sendaddrinfo(SocketClient * c,addrinfo * ai)834 static bool sendaddrinfo(SocketClient* c, addrinfo* ai) {
835     // struct addrinfo {
836     //      int     ai_flags;       /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
837     //      int     ai_family;      /* PF_xxx */
838     //      int     ai_socktype;    /* SOCK_xxx */
839     //      int     ai_protocol;    /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
840     //      socklen_t ai_addrlen;   /* length of ai_addr */
841     //      char    *ai_canonname;  /* canonical name for hostname */
842     //      struct  sockaddr *ai_addr;      /* binary address */
843     //      struct  addrinfo *ai_next;      /* next structure in linked list */
844     // };
845 
846     // Write the struct piece by piece because we might be a 64-bit netd
847     // talking to a 32-bit process.
848     bool success = sendBE32(c, ai->ai_flags) && sendBE32(c, ai->ai_family) &&
849                    sendBE32(c, ai->ai_socktype) && sendBE32(c, ai->ai_protocol);
850     if (!success) {
851         return false;
852     }
853 
854     // ai_addrlen and ai_addr.
855     if (!sendLenAndData(c, ai->ai_addrlen, ai->ai_addr)) {
856         return false;
857     }
858 
859     // strlen(ai_canonname) and ai_canonname.
860     int len = 0;
861     if (ai->ai_canonname != nullptr) {
862         const char* ai_canonname = ai->ai_canonname;
863         len = strlen(ai_canonname) + 1;
864     }
865     if (!sendLenAndData(c, len, ai->ai_canonname)) {
866         return false;
867     }
868 
869     return true;
870 }
871 
doDns64Synthesis(int32_t * rv,addrinfo ** res,NetworkDnsEventReported * event)872 void DnsProxyListener::GetAddrInfoHandler::doDns64Synthesis(int32_t* rv, addrinfo** res,
873                                                             NetworkDnsEventReported* event) {
874     const bool ipv6WantedButNoData = (mHints && mHints->ai_family == AF_INET6 && *rv == EAI_NODATA);
875     const bool unspecWantedButNoIPv6 =
876             ((!mHints || mHints->ai_family == AF_UNSPEC) && *rv == 0 && onlyIPv4Answers(*res));
877 
878     if (!ipv6WantedButNoData && !unspecWantedButNoIPv6) {
879         return;
880     }
881 
882     netdutils::IPPrefix prefix{};
883     if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
884         return;
885     }
886 
887     if (ipv6WantedButNoData) {
888         // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis
889         const char* host = mHost.starts_with('^') ? nullptr : mHost.c_str();
890         const char* service = mService.starts_with('^') ? nullptr : mService.c_str();
891         mHints->ai_family = AF_INET;
892         // Don't need to do freeaddrinfo(res) before starting new DNS lookup because previous
893         // DNS lookup is failed with error EAI_NODATA.
894         *rv = resolv_getaddrinfo(host, service, mHints.get(), &mNetContext, mClient->getSocket(),
895                                  res, event);
896         if (*rv) {
897             *rv = EAI_NODATA;  // return original error code
898             return;
899         }
900     }
901 
902     if (!synthesizeNat64PrefixWithARecord(prefix, res, unspecWantedButNoIPv6, &mNetContext)) {
903         if (ipv6WantedButNoData) {
904             // If caller wants IPv6 answers but no data and failed to synthesize IPv6 answers,
905             // don't return the IPv4 answers.
906             *rv = EAI_NODATA;  // return original error code
907             if (*res) {
908                 freeaddrinfo(*res);
909                 *res = nullptr;
910             }
911         }
912     }
913 }
914 
run()915 void DnsProxyListener::GetAddrInfoHandler::run() {
916     LOG(INFO) << "GetAddrInfoHandler::run: {" << mNetContext.toString() << "}";
917 
918     addrinfo* result = nullptr;
919     Stopwatch s;
920     maybeFixupNetContext(&mNetContext, mClient->getPid());
921     const uid_t uid = mClient->getUid();
922     int32_t rv = 0;
923     NetworkDnsEventReported event;
924     initDnsEvent(&event, mNetContext);
925     const bool isUidBlocked = isUidNetworkingBlocked(mNetContext.uid, mNetContext.dns_netid);
926     if (isUidBlocked) {
927         LOG(INFO) << "GetAddrInfoHandler::run: network access blocked";
928         rv = EAI_FAIL;
929     } else if (startQueryLimiter(uid)) {
930         const char* host = mHost.starts_with('^') ? nullptr : mHost.c_str();
931         const char* service = mService.starts_with('^') ? nullptr : mService.c_str();
932         if (evaluate_domain_name(mNetContext, host)) {
933             rv = resolv_getaddrinfo(host, service, mHints.get(), &mNetContext, mClient->getSocket(),
934                                     &result, &event);
935             doDns64Synthesis(&rv, &result, &event);
936         } else {
937             rv = EAI_SYSTEM;
938         }
939         endQueryLimiter(uid);
940     } else {
941         // Note that this error code is currently not passed down to the client.
942         // android_getaddrinfo_proxy() returns EAI_NODATA on any error.
943         rv = EAI_MEMORY;
944         LOG(ERROR) << "GetAddrInfoHandler::run: from UID " << uid
945                    << ", max concurrent queries reached";
946     }
947 
948     const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
949     event.set_latency_micros(latencyUs);
950     event.set_event_type(EVENT_GETADDRINFO);
951     event.set_hints_ai_flags((mHints ? mHints->ai_flags : 0));
952 
953     bool success = true;
954     if (rv) {
955         // getaddrinfo failed
956         success = !mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, &rv, sizeof(rv));
957     } else {
958         success = !mClient->sendCode(ResponseCode::DnsProxyQueryResult);
959         addrinfo* ai = result;
960         while (ai && success) {
961             success = sendBE32(mClient, 1) && sendaddrinfo(mClient, ai);
962             ai = ai->ai_next;
963         }
964         success = success && sendBE32(mClient, 0);
965     }
966 
967     if (!success) {
968         PLOG(WARNING) << "GetAddrInfoHandler::run: Error writing DNS result to client uid " << uid
969                       << " pid " << mClient->getPid();
970     }
971 
972     std::vector<std::string> ip_addrs;
973     const int total_ip_addr_count = extractGetAddrInfoAnswers(result, &ip_addrs);
974     reportDnsEvent(INetdEventListener::EVENT_GETADDRINFO, mNetContext, latencyUs, rv, event, mHost,
975                    isUidBlocked, ip_addrs, total_ip_addr_count);
976     freeaddrinfo(result);
977 }
978 
threadName()979 std::string DnsProxyListener::GetAddrInfoHandler::threadName() {
980     return makeThreadName(mNetContext.dns_netid, mClient->getUid());
981 }
982 
983 namespace {
984 
addIpAddrWithinLimit(std::vector<std::string> * ip_addrs,const sockaddr * addr,socklen_t addrlen)985 void addIpAddrWithinLimit(std::vector<std::string>* ip_addrs, const sockaddr* addr,
986                           socklen_t addrlen) {
987     // ipAddresses array is limited to first INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT
988     // addresses for A and AAAA. Total count of addresses is provided, to be able to tell whether
989     // some addresses didn't get logged.
990     if (ip_addrs->size() < INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT) {
991         char ip_addr[INET6_ADDRSTRLEN];
992         if (getnameinfo(addr, addrlen, ip_addr, sizeof(ip_addr), nullptr, 0, NI_NUMERICHOST) == 0) {
993             ip_addrs->push_back(std::string(ip_addr));
994         }
995     }
996 }
997 
998 }  // namespace
999 
GetAddrInfoCmd()1000 DnsProxyListener::GetAddrInfoCmd::GetAddrInfoCmd() : FrameworkCommand("getaddrinfo") {}
1001 
runCommand(SocketClient * cli,int argc,char ** argv)1002 int DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient* cli, int argc, char** argv) {
1003     logArguments(argc, argv);
1004 
1005     int ai_flags = 0;
1006     int ai_family = 0;
1007     int ai_socktype = 0;
1008     int ai_protocol = 0;
1009     unsigned netId = 0;
1010     std::string strErr = "GetAddrInfoCmd::runCommand: ";
1011 
1012     if (argc != 8) {
1013         strErr = strErr + "invalid number of arguments: " + std::to_string(argc);
1014         return HandleArgumentError(cli, ResponseCode::CommandParameterError, strErr, 0, NULL);
1015     }
1016 
1017     const std::string name = argv[1];
1018     const std::string service = argv[2];
1019     if (!ParseInt(argv[3], &ai_flags))
1020         return HandleArgumentError(cli, ResponseCode::CommandParameterError, strErr, argc, argv);
1021     if (!ParseInt(argv[4], &ai_family))
1022         return HandleArgumentError(cli, ResponseCode::CommandParameterError, strErr, argc, argv);
1023     if (!ParseInt(argv[5], &ai_socktype))
1024         return HandleArgumentError(cli, ResponseCode::CommandParameterError, strErr, argc, argv);
1025     if (!ParseInt(argv[6], &ai_protocol))
1026         return HandleArgumentError(cli, ResponseCode::CommandParameterError, strErr, argc, argv);
1027     if (!ParseUint(argv[7], &netId))
1028         return HandleArgumentError(cli, ResponseCode::CommandParameterError, strErr, argc, argv);
1029 
1030     const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
1031     const uid_t uid = cli->getUid();
1032 
1033     android_net_context netcontext;
1034     gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
1035 
1036     if (useLocalNameservers) {
1037         netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
1038     }
1039 
1040     std::unique_ptr<addrinfo> hints;
1041     if (ai_flags != -1 || ai_family != -1 || ai_socktype != -1 || ai_protocol != -1) {
1042         hints.reset((addrinfo*)calloc(1, sizeof(addrinfo)));
1043         hints->ai_flags = ai_flags;
1044         hints->ai_family = ai_family;
1045         hints->ai_socktype = ai_socktype;
1046         hints->ai_protocol = ai_protocol;
1047     }
1048 
1049     (new GetAddrInfoHandler(cli, name, service, std::move(hints), netcontext))->spawn();
1050     return 0;
1051 }
1052 
1053 /*******************************************************
1054  *                  ResNSendCommand                    *
1055  *******************************************************/
ResNSendCommand()1056 DnsProxyListener::ResNSendCommand::ResNSendCommand() : FrameworkCommand("resnsend") {}
1057 
runCommand(SocketClient * cli,int argc,char ** argv)1058 int DnsProxyListener::ResNSendCommand::runCommand(SocketClient* cli, int argc, char** argv) {
1059     logArguments(argc, argv);
1060 
1061     const uid_t uid = cli->getUid();
1062     if (argc != 4) {
1063         LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
1064                      << ", invalid number of arguments to resnsend: " << argc;
1065         sendBE32(cli, -EINVAL);
1066         return -1;
1067     }
1068 
1069     unsigned netId;
1070     if (!ParseUint(argv[1], &netId)) {
1071         LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
1072                      << ", invalid netId";
1073         sendBE32(cli, -EINVAL);
1074         return -1;
1075     }
1076 
1077     uint32_t flags;
1078     if (!ParseUint(argv[2], &flags)) {
1079         LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
1080                      << ", invalid flags";
1081         sendBE32(cli, -EINVAL);
1082         return -1;
1083     }
1084 
1085     const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
1086 
1087     android_net_context netcontext;
1088     gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
1089 
1090     if (useLocalNameservers) {
1091         netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
1092     }
1093 
1094     (new ResNSendHandler(cli, argv[3], flags, netcontext))->spawn();
1095     return 0;
1096 }
1097 
ResNSendHandler(SocketClient * c,std::string msg,uint32_t flags,const android_net_context & netcontext)1098 DnsProxyListener::ResNSendHandler::ResNSendHandler(SocketClient* c, std::string msg, uint32_t flags,
1099                                                    const android_net_context& netcontext)
1100     : Handler(c), mMsg(std::move(msg)), mFlags(flags), mNetContext(netcontext) {}
1101 
run()1102 void DnsProxyListener::ResNSendHandler::run() {
1103     LOG(INFO) << "ResNSendHandler::run: " << mFlags << " / {" << mNetContext.toString() << "}";
1104 
1105     Stopwatch s;
1106     maybeFixupNetContext(&mNetContext, mClient->getPid());
1107 
1108     // Decode
1109     std::vector<uint8_t> msg(MAXPACKET, 0);
1110 
1111     // Max length of mMsg is less than 1024 since the CMD_BUF_SIZE in FrameworkListener is 1024
1112     int msgLen = b64_pton(mMsg.c_str(), msg.data(), MAXPACKET);
1113     if (msgLen == -1) {
1114         // Decode fail
1115         sendBE32(mClient, -EILSEQ);
1116         return;
1117     }
1118 
1119     const uid_t uid = mClient->getUid();
1120     int rr_type = 0;
1121     std::string rr_name;
1122     uint16_t original_query_id = 0;
1123 
1124     // TODO: Handle the case which is msg contains more than one query
1125     if (!parseQuery(std::span(msg.data(), msgLen), &original_query_id, &rr_type, &rr_name) ||
1126         !setQueryId(std::span(msg.data(), msgLen), arc4random_uniform(65536))) {
1127         // If the query couldn't be parsed, block the request.
1128         LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid << ", invalid query";
1129         sendBE32(mClient, -EINVAL);
1130         return;
1131     }
1132 
1133     // Send DNS query
1134     std::vector<uint8_t> ansBuf(MAXPACKET, 0);
1135     int rcode = ns_r_noerror;
1136     int ansLen = -1;
1137     NetworkDnsEventReported event;
1138     initDnsEvent(&event, mNetContext);
1139     const bool isUidBlocked = isUidNetworkingBlocked(mNetContext.uid, mNetContext.dns_netid);
1140     if (isUidBlocked) {
1141         LOG(INFO) << "ResNSendHandler::run: network access blocked";
1142         ansLen = -ECONNREFUSED;
1143     } else if (startQueryLimiter(uid)) {
1144         if (evaluate_domain_name(mNetContext, rr_name.c_str())) {
1145             ansLen = resolv_res_nsend(&mNetContext, mClient->getSocket(),
1146                                       std::span(msg.data(), msgLen), ansBuf, &rcode,
1147                                       static_cast<ResNsendFlags>(mFlags), &event);
1148         } else {
1149             // TODO(b/307048182): It should return -errno.
1150             ansLen = -EAI_SYSTEM;
1151         }
1152         endQueryLimiter(uid);
1153     } else {
1154         LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid
1155                      << ", max concurrent queries reached";
1156         ansLen = -EBUSY;
1157     }
1158 
1159     const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
1160     event.set_latency_micros(latencyUs);
1161     event.set_event_type(EVENT_RES_NSEND);
1162     event.set_res_nsend_flags(static_cast<ResNsendFlags>(mFlags));
1163 
1164     // Fail, send -errno
1165     if (ansLen < 0) {
1166         if (!sendBE32(mClient, ansLen)) {
1167             PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send errno to uid " << uid
1168                           << " pid " << mClient->getPid();
1169         }
1170         if (rr_type == ns_t_a || rr_type == ns_t_aaaa) {
1171             reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs,
1172                            resNSendToAiError(ansLen, rcode), event, rr_name, isUidBlocked);
1173         }
1174         return;
1175     }
1176 
1177     // Send rcode
1178     if (!sendBE32(mClient, rcode)) {
1179         PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send rcode to uid " << uid
1180                       << " pid " << mClient->getPid();
1181         return;
1182     }
1183 
1184     // Restore query id
1185     if (!setQueryId(std::span(ansBuf.data(), ansLen), original_query_id)) {
1186         LOG(WARNING) << "ResNSendHandler::run: resnsend: failed to restore query id";
1187         return;
1188     }
1189 
1190     // Send answer
1191     if (!sendLenAndData(mClient, ansLen, ansBuf.data())) {
1192         PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send answer to uid " << uid
1193                       << " pid " << mClient->getPid();
1194         return;
1195     }
1196 
1197     if (rr_type == ns_t_a || rr_type == ns_t_aaaa) {
1198         std::vector<std::string> ip_addrs;
1199         const int total_ip_addr_count =
1200                 extractResNsendAnswers(std::span(ansBuf.data(), ansLen), rr_type, &ip_addrs);
1201         reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs,
1202                        resNSendToAiError(ansLen, rcode), event, rr_name, /*skipStats=*/false,
1203                        ip_addrs, total_ip_addr_count);
1204     }
1205 }
1206 
threadName()1207 std::string DnsProxyListener::ResNSendHandler::threadName() {
1208     return makeThreadName(mNetContext.dns_netid, mClient->getUid());
1209 }
1210 
1211 namespace {
1212 
sendCodeAndBe32(SocketClient * c,int code,int data)1213 bool sendCodeAndBe32(SocketClient* c, int code, int data) {
1214     return !c->sendCode(code) && sendBE32(c, data);
1215 }
1216 
1217 }  // namespace
1218 
1219 /*******************************************************
1220  *                  GetDnsNetId                        *
1221  *******************************************************/
GetDnsNetIdCommand()1222 DnsProxyListener::GetDnsNetIdCommand::GetDnsNetIdCommand() : FrameworkCommand("getdnsnetid") {}
1223 
runCommand(SocketClient * cli,int argc,char ** argv)1224 int DnsProxyListener::GetDnsNetIdCommand::runCommand(SocketClient* cli, int argc, char** argv) {
1225     logArguments(argc, argv);
1226 
1227     const uid_t uid = cli->getUid();
1228     if (argc != 2) {
1229         LOG(WARNING) << "GetDnsNetIdCommand::runCommand: getdnsnetid: from UID " << uid
1230                      << ", invalid number of arguments to getdnsnetid: " << argc;
1231         sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, -EINVAL);
1232         return -1;
1233     }
1234 
1235     unsigned netId;
1236     if (!ParseUint(argv[1], &netId)) {
1237         LOG(WARNING) << "GetDnsNetIdCommand::runCommand: getdnsnetid: from UID " << uid
1238                      << ", invalid netId";
1239         sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, -EINVAL);
1240         return -1;
1241     }
1242 
1243     const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
1244     android_net_context netcontext;
1245     gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
1246 
1247     if (useLocalNameservers) {
1248         netcontext.app_netid |= NETID_USE_LOCAL_NAMESERVERS;
1249     }
1250 
1251     const bool success =
1252             sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, netcontext.app_netid);
1253     if (!success) {
1254         PLOG(WARNING)
1255                 << "GetDnsNetIdCommand::runCommand: getdnsnetid: failed to send result to uid "
1256                 << uid << " pid " << cli->getPid();
1257     }
1258 
1259     return success ? 0 : -1;
1260 }
1261 
1262 /*******************************************************
1263  *                  GetHostByName                      *
1264  *******************************************************/
GetHostByNameCmd()1265 DnsProxyListener::GetHostByNameCmd::GetHostByNameCmd() : FrameworkCommand("gethostbyname") {}
1266 
runCommand(SocketClient * cli,int argc,char ** argv)1267 int DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient* cli, int argc, char** argv) {
1268     logArguments(argc, argv);
1269 
1270     unsigned netId = 0;
1271     int af = 0;
1272     std::string strErr = "GetHostByNameCmd::runCommand: ";
1273 
1274     if (argc != 4) {
1275         strErr = strErr + "invalid number of arguments: " + std::to_string(argc);
1276         return HandleArgumentError(cli, ResponseCode::CommandParameterError, strErr, 0, NULL);
1277     }
1278 
1279     if (!ParseUint(argv[1], &netId))
1280         return HandleArgumentError(cli, ResponseCode::CommandParameterError, strErr, argc, argv);
1281     std::string name = argv[2];
1282     if (!ParseInt(argv[3], &af))
1283         return HandleArgumentError(cli, ResponseCode::CommandParameterError, strErr, argc, argv);
1284     uid_t uid = cli->getUid();
1285     const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
1286 
1287     android_net_context netcontext;
1288     gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
1289 
1290     if (useLocalNameservers) {
1291         netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
1292     }
1293 
1294     (new GetHostByNameHandler(cli, name, af, netcontext))->spawn();
1295     return 0;
1296 }
1297 
GetHostByNameHandler(SocketClient * c,std::string name,int af,const android_net_context & netcontext)1298 DnsProxyListener::GetHostByNameHandler::GetHostByNameHandler(SocketClient* c, std::string name,
1299                                                              int af,
1300                                                              const android_net_context& netcontext)
1301     : Handler(c), mName(std::move(name)), mAf(af), mNetContext(netcontext) {}
1302 
doDns64Synthesis(int32_t * rv,hostent * hbuf,char * buf,size_t buflen,struct hostent ** hpp,NetworkDnsEventReported * event)1303 void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, hostent* hbuf, char* buf,
1304                                                               size_t buflen, struct hostent** hpp,
1305                                                               NetworkDnsEventReported* event) {
1306     // Don't have to consider family AF_UNSPEC case because gethostbyname{, 2} only supports
1307     // family AF_INET or AF_INET6.
1308     const bool ipv6WantedButNoData = (mAf == AF_INET6 && *rv == EAI_NODATA);
1309 
1310     if (!ipv6WantedButNoData) {
1311         return;
1312     }
1313 
1314     netdutils::IPPrefix prefix{};
1315     if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
1316         return;
1317     }
1318 
1319     // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis
1320     const char* name = mName.starts_with('^') ? nullptr : mName.c_str();
1321     *rv = resolv_gethostbyname(name, AF_INET, hbuf, buf, buflen, &mNetContext, mClient->getSocket(),
1322                                hpp, event);
1323     if (*rv) {
1324         *rv = EAI_NODATA;  // return original error code
1325         return;
1326     }
1327 
1328     if (!synthesizeNat64PrefixWithARecord(prefix, *hpp)) {
1329         // If caller wants IPv6 answers but no data and failed to synthesize IPv4 answers,
1330         // don't return the IPv4 answers.
1331         *hpp = nullptr;
1332     }
1333 }
1334 
run()1335 void DnsProxyListener::GetHostByNameHandler::run() {
1336     LOG(INFO) << "GetHostByNameHandler::run: {" << mNetContext.toString() << "}";
1337     Stopwatch s;
1338     maybeFixupNetContext(&mNetContext, mClient->getPid());
1339     const uid_t uid = mClient->getUid();
1340     hostent* hp = nullptr;
1341     hostent hbuf;
1342     char tmpbuf[MAXPACKET];
1343     int32_t rv = 0;
1344     NetworkDnsEventReported event;
1345     initDnsEvent(&event, mNetContext);
1346     const bool isUidBlocked = isUidNetworkingBlocked(mNetContext.uid, mNetContext.dns_netid);
1347     if (isUidBlocked) {
1348         LOG(INFO) << "GetHostByNameHandler::run: network access blocked";
1349         rv = EAI_FAIL;
1350     } else if (startQueryLimiter(uid)) {
1351         const char* name = mName.starts_with('^') ? nullptr : mName.c_str();
1352         if (evaluate_domain_name(mNetContext, name)) {
1353             rv = resolv_gethostbyname(name, mAf, &hbuf, tmpbuf, sizeof tmpbuf, &mNetContext,
1354                                       mClient->getSocket(), &hp, &event);
1355             doDns64Synthesis(&rv, &hbuf, tmpbuf, sizeof tmpbuf, &hp, &event);
1356         } else {
1357             rv = EAI_SYSTEM;
1358         }
1359         endQueryLimiter(uid);
1360     } else {
1361         rv = EAI_MEMORY;
1362         LOG(ERROR) << "GetHostByNameHandler::run: from UID " << uid
1363                    << ", max concurrent queries reached";
1364     }
1365 
1366     const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
1367     event.set_latency_micros(latencyUs);
1368     event.set_event_type(EVENT_GETHOSTBYNAME);
1369 
1370     if (rv) {
1371         LOG(DEBUG) << "GetHostByNameHandler::run: result failed: " << gai_strerror(rv);
1372     }
1373 
1374     bool success = true;
1375     if (hp) {
1376         // hp is not nullptr iff. rv is 0.
1377         success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
1378         success &= sendhostent(mClient, hp);
1379     } else {
1380         success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, nullptr, 0) == 0;
1381     }
1382 
1383     if (!success) {
1384         PLOG(WARNING) << "GetHostByNameHandler::run: Error writing DNS result to client uid " << uid
1385                       << " pid " << mClient->getPid();
1386     }
1387 
1388     std::vector<std::string> ip_addrs;
1389     const int total_ip_addr_count = extractGetHostByNameAnswers(hp, &ip_addrs);
1390     reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYNAME, mNetContext, latencyUs, rv, event,
1391                    mName, isUidBlocked, ip_addrs, total_ip_addr_count);
1392 }
1393 
threadName()1394 std::string DnsProxyListener::GetHostByNameHandler::threadName() {
1395     return makeThreadName(mNetContext.dns_netid, mClient->getUid());
1396 }
1397 
1398 /*******************************************************
1399  *                  GetHostByAddr                      *
1400  *******************************************************/
GetHostByAddrCmd()1401 DnsProxyListener::GetHostByAddrCmd::GetHostByAddrCmd() : FrameworkCommand("gethostbyaddr") {}
1402 
runCommand(SocketClient * cli,int argc,char ** argv)1403 int DnsProxyListener::GetHostByAddrCmd::runCommand(SocketClient* cli, int argc, char** argv) {
1404     logArguments(argc, argv);
1405     int addrLen = 0;
1406     int addrFamily = 0;
1407     unsigned netId = 0;
1408     std::string strErr = "GetHostByAddrCmd::runCommand: ";
1409 
1410     if (argc != 5) {
1411         strErr = strErr + "invalid number of arguments: " + std::to_string(argc);
1412         return HandleArgumentError(cli, ResponseCode::CommandParameterError, strErr, 0, NULL);
1413     }
1414 
1415     char* addrStr = argv[1];
1416     if (!ParseInt(argv[2], &addrLen))
1417         return HandleArgumentError(cli, ResponseCode::CommandParameterError, strErr, argc, argv);
1418     if (!ParseInt(argv[3], &addrFamily))
1419         return HandleArgumentError(cli, ResponseCode::CommandParameterError, strErr, argc, argv);
1420     if (!ParseUint(argv[4], &netId))
1421         return HandleArgumentError(cli, ResponseCode::CommandParameterError, strErr, argc, argv);
1422     uid_t uid = cli->getUid();
1423     const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
1424 
1425     in6_addr addr;
1426     errno = 0;
1427     int result = inet_pton(addrFamily, addrStr, &addr);
1428     if (result <= 0) {
1429         strErr = strErr + "inet_pton(\"" + addrStr + "\") failed " + strerror(errno);
1430         return HandleArgumentError(cli, ResponseCode::OperationFailed, strErr, 0, NULL);
1431     }
1432 
1433     android_net_context netcontext;
1434     gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
1435 
1436     if (useLocalNameservers) {
1437         netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
1438     }
1439 
1440     (new GetHostByAddrHandler(cli, addr, addrLen, addrFamily, netcontext))->spawn();
1441     return 0;
1442 }
1443 
GetHostByAddrHandler(SocketClient * c,in6_addr address,int addressLen,int addressFamily,const android_net_context & netcontext)1444 DnsProxyListener::GetHostByAddrHandler::GetHostByAddrHandler(SocketClient* c, in6_addr address,
1445                                                              int addressLen, int addressFamily,
1446                                                              const android_net_context& netcontext)
1447     : Handler(c),
1448       mAddress(address),
1449       mAddressLen(addressLen),
1450       mAddressFamily(addressFamily),
1451       mNetContext(netcontext) {}
1452 
doDns64ReverseLookup(hostent * hbuf,char * buf,size_t buflen,struct hostent ** hpp,NetworkDnsEventReported * event)1453 void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(hostent* hbuf, char* buf,
1454                                                                   size_t buflen,
1455                                                                   struct hostent** hpp,
1456                                                                   NetworkDnsEventReported* event) {
1457     if (*hpp != nullptr || mAddressFamily != AF_INET6) {
1458         return;
1459     }
1460 
1461     netdutils::IPPrefix prefix{};
1462     if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
1463         return;
1464     }
1465 
1466     if (!isValidNat64Prefix(prefix)) {
1467         return;
1468     }
1469 
1470     struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
1471     struct sockaddr_in6* v6prefix = (struct sockaddr_in6*)&ss;
1472     struct in6_addr v6addr = mAddress;
1473     // Check if address has NAT64 prefix. Only /96 IPv6 NAT64 prefixes are supported
1474     if ((v6addr.s6_addr32[0] != v6prefix->sin6_addr.s6_addr32[0]) ||
1475         (v6addr.s6_addr32[1] != v6prefix->sin6_addr.s6_addr32[1]) ||
1476         (v6addr.s6_addr32[2] != v6prefix->sin6_addr.s6_addr32[2])) {
1477         return;
1478     }
1479 
1480     // Remove NAT64 prefix and do reverse DNS query
1481     struct in_addr v4addr = {.s_addr = v6addr.s6_addr32[3]};
1482     resolv_gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET, hbuf, buf, buflen, &mNetContext,
1483                          mClient->getSocket(), hpp, event);
1484     if (*hpp && (*hpp)->h_addr_list[0]) {
1485         // Replace IPv4 address with original queried IPv6 address in place. The space has
1486         // reserved by dns_gethtbyaddr() and netbsd_gethostent_r() in
1487         // system/netd/resolv/gethnamaddr.cpp.
1488         // Note that resolv_gethostbyaddr() returns only one entry in result.
1489         char* addr = (*hpp)->h_addr_list[0];
1490         memcpy(addr, &v6addr, sizeof(v6addr));
1491         (*hpp)->h_addrtype = AF_INET6;
1492         (*hpp)->h_length = sizeof(struct in6_addr);
1493     } else {
1494         LOG(ERROR) << __func__ << ": hpp or (*hpp)->h_addr_list[0] is null";
1495     }
1496 }
1497 
run()1498 void DnsProxyListener::GetHostByAddrHandler::run() {
1499     LOG(INFO) << "GetHostByAddrHandler::run: {" << mNetContext.toString() << "}";
1500     Stopwatch s;
1501     maybeFixupNetContext(&mNetContext, mClient->getPid());
1502     const uid_t uid = mClient->getUid();
1503     hostent* hp = nullptr;
1504     hostent hbuf;
1505     char tmpbuf[MAXPACKET];
1506     int32_t rv = 0;
1507     NetworkDnsEventReported event;
1508     initDnsEvent(&event, mNetContext);
1509 
1510     const bool isUidBlocked = isUidNetworkingBlocked(mNetContext.uid, mNetContext.dns_netid);
1511     if (isUidBlocked) {
1512         LOG(INFO) << "GetHostByAddrHandler::run: network access blocked";
1513         rv = EAI_FAIL;
1514     } else if (startQueryLimiter(uid)) {
1515         // From Android U, evaluate_domain_name() is not only for OEM customization, but also tells
1516         // DNS resolver whether the UID can send DNS on the specified network. The function needs
1517         // to be called even when there is no domain name to evaluate (GetHostByAddr). This is
1518         // applied on U+ only so that the behavior won’t change on T- OEM devices.
1519         // TODO: pass the actual name into evaluate_domain_name, e.g., 238.26.217.172.in-addr.arpa
1520         //       when the lookup address is 172.217.26.238.
1521         if (isAtLeastU() && !evaluate_domain_name(mNetContext, nullptr)) {
1522             rv = EAI_SYSTEM;
1523         } else {
1524             rv = resolv_gethostbyaddr(&mAddress, mAddressLen, mAddressFamily, &hbuf, tmpbuf,
1525                                       sizeof tmpbuf, &mNetContext, mClient->getSocket(), &hp,
1526                                       &event);
1527             doDns64ReverseLookup(&hbuf, tmpbuf, sizeof tmpbuf, &hp, &event);
1528         }
1529         endQueryLimiter(uid);
1530     } else {
1531         rv = EAI_MEMORY;
1532         LOG(ERROR) << "GetHostByAddrHandler::run: from UID " << uid
1533                    << ", max concurrent queries reached";
1534     }
1535 
1536     const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
1537     event.set_latency_micros(latencyUs);
1538     event.set_event_type(EVENT_GETHOSTBYADDR);
1539 
1540     if (rv) {
1541         LOG(DEBUG) << "GetHostByAddrHandler::run: result failed: " << gai_strerror(rv);
1542     }
1543 
1544     bool success = true;
1545     if (hp) {
1546         success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
1547         success &= sendhostent(mClient, hp);
1548     } else {
1549         success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, nullptr, 0) == 0;
1550     }
1551 
1552     if (!success) {
1553         PLOG(WARNING) << "GetHostByAddrHandler::run: Error writing DNS result to client uid " << uid
1554                       << " pid " << mClient->getPid();
1555     }
1556 
1557     reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYADDR, mNetContext, latencyUs, rv, event,
1558                    (hp && hp->h_name) ? hp->h_name : "null", isUidBlocked, {}, 0);
1559 }
1560 
threadName()1561 std::string DnsProxyListener::GetHostByAddrHandler::threadName() {
1562     return makeThreadName(mNetContext.dns_netid, mClient->getUid());
1563 }
1564 
1565 }  // namespace net
1566 }  // namespace android
1567