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