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 <arpa/inet.h>
18 #include <dirent.h>
19 #include <errno.h>
20 #include <linux/if.h>
21 #include <math.h>
22 #include <netdb.h>
23 #include <netinet/in.h>
24 #include <stdlib.h>
25 #include <sys/socket.h>
26 #include <sys/types.h>
27 #include <string.h>
28 #include <pthread.h>
29 #include <resolv_netid.h>
30 #include <net/if.h>
31 
32 #define LOG_TAG "DnsProxyListener"
33 #define DBG 0
34 #define VDBG 0
35 
36 #include <algorithm>
37 #include <chrono>
38 #include <list>
39 #include <vector>
40 
41 #include <cutils/log.h>
42 #include <cutils/misc.h>
43 #include <netdutils/Slice.h>
44 #include <netdutils/OperationLimiter.h>
45 #include <utils/String16.h>
46 #include <sysutils/SocketClient.h>
47 
48 #include <binder/IServiceManager.h>
49 
50 #include "Controllers.h"
51 #include "Fwmark.h"
52 #include "DnsProxyListener.h"
53 #include "dns/DnsTlsDispatcher.h"
54 #include "dns/DnsTlsTransport.h"
55 #include "dns/DnsTlsServer.h"
56 #include "NetdClient.h"
57 #include "NetdConstants.h"
58 #include "NetworkController.h"
59 #include "ResponseCode.h"
60 #include "Stopwatch.h"
61 #include "thread_util.h"
62 #include "android/net/metrics/INetdEventListener.h"
63 
64 using android::String16;
65 using android::net::metrics::INetdEventListener;
66 
67 namespace android {
68 namespace net {
69 
70 namespace {
71 
72 // TODO: move to a separate file (with other constants from FwmarkService and NetdNativeService)
73 constexpr const char CONNECTIVITY_USE_RESTRICTED_NETWORKS[] =
74     "android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS";
75 constexpr const char NETWORK_BYPASS_PRIVATE_DNS[] =
76     "android.permission.NETWORK_BYPASS_PRIVATE_DNS";
77 
78 // Limits the number of outstanding DNS queries by client UID.
79 constexpr int MAX_QUERIES_PER_UID = 256;
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     for (int i = 0; i < argc; i++) {
84         ALOGD("argv[%i]=%s", i, argv[i]);
85     }
86 }
87 
88 template<typename T>
tryThreadOrError(SocketClient * cli,T * handler)89 void tryThreadOrError(SocketClient* cli, T* handler) {
90     cli->incRef();
91 
92     const int rval = threadLaunch(handler);
93     if (rval == 0) {
94         // SocketClient decRef() happens in the handler's run() method.
95         return;
96     }
97 
98     char* msg = NULL;
99     asprintf(&msg, "%s (%d)", strerror(-rval), -rval);
100     cli->sendMsg(ResponseCode::OperationFailed, msg, false);
101     free(msg);
102 
103     delete handler;
104     cli->decRef();
105 }
106 
checkAndClearUseLocalNameserversFlag(unsigned * netid)107 bool checkAndClearUseLocalNameserversFlag(unsigned* netid) {
108     if (netid == nullptr || ((*netid) & NETID_USE_LOCAL_NAMESERVERS) == 0) {
109         return false;
110     }
111     *netid = (*netid) & ~NETID_USE_LOCAL_NAMESERVERS;
112     return true;
113 }
114 
115 thread_local android_net_context thread_netcontext = {};
116 
117 DnsTlsDispatcher dnsTlsDispatcher;
118 
catnap()119 void catnap() {
120     using namespace std::chrono_literals;
121     std::this_thread::sleep_for(100ms);
122 }
123 
qhook(sockaddr * const *,const u_char ** buf,int * buflen,u_char * ans,int anssiz,int * resplen)124 res_sendhookact qhook(sockaddr* const * /*ns*/, const u_char** buf, int* buflen,
125                       u_char* ans, int anssiz, int* resplen) {
126     if (!thread_netcontext.qhook) {
127         ALOGE("qhook abort: thread qhook is null");
128         return res_goahead;
129     }
130     if (thread_netcontext.flags & NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS) {
131         return res_goahead;
132     }
133     if (!net::gCtls) {
134         ALOGE("qhook abort: gCtls is null");
135         return res_goahead;
136     }
137 
138     const auto privateDnsStatus =
139             net::gCtls->resolverCtrl.getPrivateDnsStatus(thread_netcontext.dns_netid);
140 
141     if (privateDnsStatus.mode == PrivateDnsMode::OFF) return res_goahead;
142 
143     if (privateDnsStatus.validatedServers.empty()) {
144         if (privateDnsStatus.mode == PrivateDnsMode::OPPORTUNISTIC) {
145             return res_goahead;
146         } else {
147             // Sleep and iterate some small number of times checking for the
148             // arrival of resolved and validated server IP addresses, instead
149             // of returning an immediate error.
150             catnap();
151             return res_modified;
152         }
153     }
154 
155     if (DBG) ALOGD("Performing query over TLS");
156 
157     Slice query = netdutils::Slice(const_cast<u_char*>(*buf), *buflen);
158     Slice answer = netdutils::Slice(const_cast<u_char*>(ans), anssiz);
159     const auto response = dnsTlsDispatcher.query(
160             privateDnsStatus.validatedServers, thread_netcontext.dns_mark,
161             query, answer, resplen);
162     if (response == DnsTlsTransport::Response::success) {
163         if (DBG) ALOGD("qhook success");
164         return res_done;
165     }
166 
167     if (DBG) {
168         ALOGW("qhook abort: TLS query failed: %d", (int)response);
169     }
170 
171     if (privateDnsStatus.mode == PrivateDnsMode::OPPORTUNISTIC) {
172         // In opportunistic mode, handle falling back to cleartext in some
173         // cases (DNS shouldn't fail if a validated opportunistic mode server
174         // becomes unreachable for some reason).
175         switch (response) {
176             case DnsTlsTransport::Response::network_error:
177             case DnsTlsTransport::Response::internal_error:
178                 // Note: this will cause cleartext queries to be emitted, with
179                 // all of the EDNS0 goodness enabled. Fingers crossed.  :-/
180                 return res_goahead;
181             default:
182                 break;
183         }
184     }
185 
186     // There was an internal error.  Fail hard.
187     return res_error;
188 }
189 
requestingUseLocalNameservers(unsigned flags)190 constexpr bool requestingUseLocalNameservers(unsigned flags) {
191     return (flags & NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS) != 0;
192 }
193 
queryingViaTls(unsigned dns_netid)194 inline bool queryingViaTls(unsigned dns_netid) {
195     const auto privateDnsStatus = net::gCtls->resolverCtrl.getPrivateDnsStatus(dns_netid);
196     switch (privateDnsStatus.mode) {
197         case PrivateDnsMode::OPPORTUNISTIC:
198            return !privateDnsStatus.validatedServers.empty();
199         case PrivateDnsMode::STRICT:
200             return true;
201         default:
202             return false;
203     }
204 }
205 
hasPermissionToBypassPrivateDns(uid_t uid)206 bool hasPermissionToBypassPrivateDns(uid_t uid) {
207     static_assert(AID_SYSTEM >= 0 && AID_SYSTEM < FIRST_APPLICATION_UID,
208         "Calls from AID_SYSTEM must not result in a permission check to avoid deadlock.");
209     if (uid >= 0 && uid < FIRST_APPLICATION_UID) {
210         return true;
211     }
212 
213     for (auto& permission : {CONNECTIVITY_USE_RESTRICTED_NETWORKS, NETWORK_BYPASS_PRIVATE_DNS}) {
214         if (checkCallingPermission(String16(permission))) {
215             return true;
216         }
217     }
218     return false;
219 }
220 
maybeFixupNetContext(android_net_context * ctx)221 void maybeFixupNetContext(android_net_context* ctx) {
222     if (requestingUseLocalNameservers(ctx->flags) && !hasPermissionToBypassPrivateDns(ctx->uid)) {
223         // Not permitted; clear the flag.
224         ctx->flags &= ~NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
225     }
226 
227     if (!requestingUseLocalNameservers(ctx->flags)) {
228         // If we're not explicitly bypassing DNS-over-TLS servers, check whether
229         // DNS-over-TLS is in use as an indicator for when to use more modern
230         // DNS resolution mechanics.
231         if (queryingViaTls(ctx->dns_netid)) {
232             ctx->flags |= NET_CONTEXT_FLAG_USE_EDNS;
233         }
234     }
235 
236     // Always set the qhook. An opportunistic mode server might have finished
237     // validating by the time the qhook runs. Note that this races with the
238     // queryingViaTls() check above, resulting in possibly sending queries over
239     // TLS without taking advantage of features like EDNS; c'est la guerre.
240     ctx->qhook = &qhook;
241 
242     // Store the android_net_context instance in a thread_local variable
243     // so that the static qhook can access other fields of the struct.
244     thread_netcontext = *ctx;
245 }
246 
247 }  // namespace
248 
DnsProxyListener(const NetworkController * netCtrl,EventReporter * eventReporter)249 DnsProxyListener::DnsProxyListener(const NetworkController* netCtrl, EventReporter* eventReporter) :
250         FrameworkListener(SOCKET_NAME), mNetCtrl(netCtrl), mEventReporter(eventReporter) {
251     registerCmd(new GetAddrInfoCmd(this));
252     registerCmd(new GetHostByAddrCmd(this));
253     registerCmd(new GetHostByNameCmd(this));
254 }
255 
GetAddrInfoHandler(SocketClient * c,char * host,char * service,struct addrinfo * hints,const android_net_context & netcontext,const int reportingLevel,const android::sp<android::net::metrics::INetdEventListener> & netdEventListener)256 DnsProxyListener::GetAddrInfoHandler::GetAddrInfoHandler(
257         SocketClient *c, char* host, char* service, struct addrinfo* hints,
258         const android_net_context& netcontext, const int reportingLevel,
259         const android::sp<android::net::metrics::INetdEventListener>& netdEventListener)
260         : mClient(c),
261           mHost(host),
262           mService(service),
263           mHints(hints),
264           mNetContext(netcontext),
265           mReportingLevel(reportingLevel),
266           mNetdEventListener(netdEventListener) {
267 }
268 
~GetAddrInfoHandler()269 DnsProxyListener::GetAddrInfoHandler::~GetAddrInfoHandler() {
270     free(mHost);
271     free(mService);
272     free(mHints);
273 }
274 
sendBE32(SocketClient * c,uint32_t data)275 static bool sendBE32(SocketClient* c, uint32_t data) {
276     uint32_t be_data = htonl(data);
277     return c->sendData(&be_data, sizeof(be_data)) == 0;
278 }
279 
280 // Sends 4 bytes of big-endian length, followed by the data.
281 // Returns true on success.
sendLenAndData(SocketClient * c,const int len,const void * data)282 static bool sendLenAndData(SocketClient* c, const int len, const void* data) {
283     return sendBE32(c, len) && (len == 0 || c->sendData(data, len) == 0);
284 }
285 
286 // Returns true on success
sendhostent(SocketClient * c,struct hostent * hp)287 static bool sendhostent(SocketClient *c, struct hostent *hp) {
288     bool success = true;
289     int i;
290     if (hp->h_name != NULL) {
291         success &= sendLenAndData(c, strlen(hp->h_name)+1, hp->h_name);
292     } else {
293         success &= sendLenAndData(c, 0, "") == 0;
294     }
295 
296     for (i=0; hp->h_aliases[i] != NULL; i++) {
297         success &= sendLenAndData(c, strlen(hp->h_aliases[i])+1, hp->h_aliases[i]);
298     }
299     success &= sendLenAndData(c, 0, ""); // null to indicate we're done
300 
301     uint32_t buf = htonl(hp->h_addrtype);
302     success &= c->sendData(&buf, sizeof(buf)) == 0;
303 
304     buf = htonl(hp->h_length);
305     success &= c->sendData(&buf, sizeof(buf)) == 0;
306 
307     for (i=0; hp->h_addr_list[i] != NULL; i++) {
308         success &= sendLenAndData(c, 16, hp->h_addr_list[i]);
309     }
310     success &= sendLenAndData(c, 0, ""); // null to indicate we're done
311     return success;
312 }
313 
sendaddrinfo(SocketClient * c,struct addrinfo * ai)314 static bool sendaddrinfo(SocketClient* c, struct addrinfo* ai) {
315     // struct addrinfo {
316     //      int     ai_flags;       /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
317     //      int     ai_family;      /* PF_xxx */
318     //      int     ai_socktype;    /* SOCK_xxx */
319     //      int     ai_protocol;    /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
320     //      socklen_t ai_addrlen;   /* length of ai_addr */
321     //      char    *ai_canonname;  /* canonical name for hostname */
322     //      struct  sockaddr *ai_addr;      /* binary address */
323     //      struct  addrinfo *ai_next;      /* next structure in linked list */
324     // };
325 
326     // Write the struct piece by piece because we might be a 64-bit netd
327     // talking to a 32-bit process.
328     bool success =
329             sendBE32(c, ai->ai_flags) &&
330             sendBE32(c, ai->ai_family) &&
331             sendBE32(c, ai->ai_socktype) &&
332             sendBE32(c, ai->ai_protocol);
333     if (!success) {
334         return false;
335     }
336 
337     // ai_addrlen and ai_addr.
338     if (!sendLenAndData(c, ai->ai_addrlen, ai->ai_addr)) {
339         return false;
340     }
341 
342     // strlen(ai_canonname) and ai_canonname.
343     if (!sendLenAndData(c, ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0, ai->ai_canonname)) {
344         return false;
345     }
346 
347     return true;
348 }
349 
run()350 void DnsProxyListener::GetAddrInfoHandler::run() {
351     if (DBG) {
352         ALOGD("GetAddrInfoHandler, now for %s / %s / {%u,%u,%u,%u,%u,%u}", mHost, mService,
353                 mNetContext.app_netid, mNetContext.app_mark,
354                 mNetContext.dns_netid, mNetContext.dns_mark,
355                 mNetContext.uid, mNetContext.flags);
356     }
357 
358     struct addrinfo* result = NULL;
359     Stopwatch s;
360     maybeFixupNetContext(&mNetContext);
361     const uid_t uid = mClient->getUid();
362     uint32_t rv = 0;
363     if (queryLimiter.start(uid)) {
364         rv = android_getaddrinfofornetcontext(mHost, mService, mHints, &mNetContext, &result);
365         queryLimiter.finish(uid);
366     } else {
367         // Note that this error code is currently not passed down to the client.
368         // android_getaddrinfo_proxy() returns EAI_NODATA on any error.
369         rv = EAI_MEMORY;
370         ALOGE("getaddrinfo: from UID %d, max concurrent queries reached", uid);
371     }
372     const int latencyMs = lround(s.timeTaken());
373 
374     if (rv) {
375         // getaddrinfo failed
376         mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, &rv, sizeof(rv));
377     } else {
378         bool success = !mClient->sendCode(ResponseCode::DnsProxyQueryResult);
379         struct addrinfo* ai = result;
380         while (ai && success) {
381             success = sendBE32(mClient, 1) && sendaddrinfo(mClient, ai);
382             ai = ai->ai_next;
383         }
384         success = success && sendBE32(mClient, 0);
385         if (!success) {
386             ALOGW("Error writing DNS result to client");
387         }
388     }
389     std::vector<String16> ip_addrs;
390     int total_ip_addr_count = 0;
391     if (result) {
392         if (mNetdEventListener != nullptr
393                 && mReportingLevel == INetdEventListener::REPORTING_LEVEL_FULL) {
394             for (addrinfo* ai = result; ai; ai = ai->ai_next) {
395                 sockaddr* ai_addr = ai->ai_addr;
396                 if (ai_addr) {
397                     addIpAddrWithinLimit(ip_addrs, ai_addr, ai->ai_addrlen);
398                     total_ip_addr_count++;
399                 }
400             }
401         }
402         freeaddrinfo(result);
403     }
404     mClient->decRef();
405     if (mNetdEventListener != nullptr) {
406         switch (mReportingLevel) {
407             case INetdEventListener::REPORTING_LEVEL_NONE:
408                 // Skip reporting.
409                 break;
410             case INetdEventListener::REPORTING_LEVEL_METRICS:
411                 // Metrics reporting is on. Send metrics.
412                 mNetdEventListener->onDnsEvent(mNetContext.dns_netid,
413                                                INetdEventListener::EVENT_GETADDRINFO, (int32_t) rv,
414                                                latencyMs, String16(""), {}, -1, -1);
415                 break;
416             case INetdEventListener::REPORTING_LEVEL_FULL:
417                 // Full event info reporting is on. Send full info.
418                 mNetdEventListener->onDnsEvent(mNetContext.dns_netid,
419                                                INetdEventListener::EVENT_GETADDRINFO, (int32_t) rv,
420                                                latencyMs, String16(mHost), ip_addrs,
421                                                total_ip_addr_count, mNetContext.uid);
422                 break;
423         }
424     } else {
425         ALOGW("Netd event listener is not available; skipping.");
426     }
427 }
428 
addIpAddrWithinLimit(std::vector<android::String16> & ip_addrs,const sockaddr * addr,socklen_t addrlen)429 void DnsProxyListener::addIpAddrWithinLimit(std::vector<android::String16>& ip_addrs,
430         const sockaddr* addr, socklen_t addrlen) {
431     // ipAddresses array is limited to first INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT
432     // addresses for A and AAAA. Total count of addresses is provided, to be able to tell whether
433     // some addresses didn't get logged.
434     if (ip_addrs.size() < INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT) {
435         char ip_addr[INET6_ADDRSTRLEN];
436         if (getnameinfo(addr, addrlen, ip_addr, sizeof(ip_addr), nullptr, 0, NI_NUMERICHOST) == 0) {
437             ip_addrs.push_back(String16(ip_addr));
438         }
439     }
440 }
441 
GetAddrInfoCmd(DnsProxyListener * dnsProxyListener)442 DnsProxyListener::GetAddrInfoCmd::GetAddrInfoCmd(DnsProxyListener* dnsProxyListener) :
443     NetdCommand("getaddrinfo"),
444     mDnsProxyListener(dnsProxyListener) {
445 }
446 
runCommand(SocketClient * cli,int argc,char ** argv)447 int DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient *cli,
448                                             int argc, char **argv) {
449     if (DBG) logArguments(argc, argv);
450 
451     if (argc != 8) {
452         char* msg = NULL;
453         asprintf( &msg, "Invalid number of arguments to getaddrinfo: %i", argc);
454         ALOGW("%s", msg);
455         cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
456         free(msg);
457         return -1;
458     }
459 
460     char* name = argv[1];
461     if (strcmp("^", name) == 0) {
462         name = NULL;
463     } else {
464         name = strdup(name);
465     }
466 
467     char* service = argv[2];
468     if (strcmp("^", service) == 0) {
469         service = NULL;
470     } else {
471         service = strdup(service);
472     }
473 
474     struct addrinfo* hints = NULL;
475     int ai_flags = atoi(argv[3]);
476     int ai_family = atoi(argv[4]);
477     int ai_socktype = atoi(argv[5]);
478     int ai_protocol = atoi(argv[6]);
479     unsigned netId = strtoul(argv[7], NULL, 10);
480     const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
481     const uid_t uid = cli->getUid();
482 
483     android_net_context netcontext;
484     mDnsProxyListener->mNetCtrl->getNetworkContext(netId, uid, &netcontext);
485     if (useLocalNameservers) {
486         netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
487     }
488 
489     if (ai_flags != -1 || ai_family != -1 ||
490         ai_socktype != -1 || ai_protocol != -1) {
491         hints = (struct addrinfo*) calloc(1, sizeof(struct addrinfo));
492         hints->ai_flags = ai_flags;
493         hints->ai_family = ai_family;
494         hints->ai_socktype = ai_socktype;
495         hints->ai_protocol = ai_protocol;
496     }
497 
498     if (DBG) {
499         ALOGD("GetAddrInfoHandler for %s / %s / {%u,%u,%u,%u,%u}",
500              name ? name : "[nullhost]",
501              service ? service : "[nullservice]",
502              netcontext.app_netid, netcontext.app_mark,
503              netcontext.dns_netid, netcontext.dns_mark,
504              netcontext.uid);
505     }
506 
507     const int metricsLevel = mDnsProxyListener->mEventReporter->getMetricsReportingLevel();
508 
509     DnsProxyListener::GetAddrInfoHandler* handler =
510             new DnsProxyListener::GetAddrInfoHandler(cli, name, service, hints, netcontext,
511                     metricsLevel, mDnsProxyListener->mEventReporter->getNetdEventListener());
512     tryThreadOrError(cli, handler);
513     return 0;
514 }
515 
516 /*******************************************************
517  *                  GetHostByName                      *
518  *******************************************************/
GetHostByNameCmd(DnsProxyListener * dnsProxyListener)519 DnsProxyListener::GetHostByNameCmd::GetHostByNameCmd(DnsProxyListener* dnsProxyListener) :
520       NetdCommand("gethostbyname"),
521       mDnsProxyListener(dnsProxyListener) {
522 }
523 
runCommand(SocketClient * cli,int argc,char ** argv)524 int DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient *cli,
525                                             int argc, char **argv) {
526     if (DBG) logArguments(argc, argv);
527 
528     if (argc != 4) {
529         char* msg = NULL;
530         asprintf(&msg, "Invalid number of arguments to gethostbyname: %i", argc);
531         ALOGW("%s", msg);
532         cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
533         free(msg);
534         return -1;
535     }
536 
537     uid_t uid = cli->getUid();
538     unsigned netId = strtoul(argv[1], NULL, 10);
539     const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
540     char* name = argv[2];
541     int af = atoi(argv[3]);
542 
543     if (strcmp(name, "^") == 0) {
544         name = NULL;
545     } else {
546         name = strdup(name);
547     }
548 
549     android_net_context netcontext;
550     mDnsProxyListener->mNetCtrl->getNetworkContext(netId, uid, &netcontext);
551     if (useLocalNameservers) {
552         netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
553     }
554 
555     const int metricsLevel = mDnsProxyListener->mEventReporter->getMetricsReportingLevel();
556 
557     DnsProxyListener::GetHostByNameHandler* handler =
558             new DnsProxyListener::GetHostByNameHandler(cli, name, af, netcontext, metricsLevel,
559                     mDnsProxyListener->mEventReporter->getNetdEventListener());
560     tryThreadOrError(cli, handler);
561     return 0;
562 }
563 
GetHostByNameHandler(SocketClient * c,char * name,int af,const android_net_context & netcontext,const int metricsLevel,const android::sp<android::net::metrics::INetdEventListener> & netdEventListener)564 DnsProxyListener::GetHostByNameHandler::GetHostByNameHandler(SocketClient* c, char* name, int af,
565         const android_net_context& netcontext, const int metricsLevel,
566         const android::sp<android::net::metrics::INetdEventListener>& netdEventListener)
567         : mClient(c),
568           mName(name),
569           mAf(af),
570           mNetContext(netcontext),
571           mReportingLevel(metricsLevel),
572           mNetdEventListener(netdEventListener) {
573 }
574 
~GetHostByNameHandler()575 DnsProxyListener::GetHostByNameHandler::~GetHostByNameHandler() {
576     free(mName);
577 }
578 
run()579 void DnsProxyListener::GetHostByNameHandler::run() {
580     if (DBG) {
581         ALOGD("DnsProxyListener::GetHostByNameHandler::run");
582     }
583 
584     Stopwatch s;
585     maybeFixupNetContext(&mNetContext);
586     const uid_t uid = mClient->getUid();
587     struct hostent* hp = nullptr;
588     if (queryLimiter.start(uid)) {
589         hp = android_gethostbynamefornetcontext(mName, mAf, &mNetContext);
590         queryLimiter.finish(uid);
591     } else {
592         ALOGE("gethostbyname: from UID %d, max concurrent queries reached", uid);
593     }
594     const int latencyMs = lround(s.timeTaken());
595 
596     if (DBG) {
597         ALOGD("GetHostByNameHandler::run gethostbyname errno: %s hp->h_name = %s, name_len = %zu",
598                 hp ? "success" : strerror(errno),
599                 (hp && hp->h_name) ? hp->h_name : "null",
600                 (hp && hp->h_name) ? strlen(hp->h_name) + 1 : 0);
601     }
602 
603     bool success = true;
604     if (hp) {
605         success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
606         success &= sendhostent(mClient, hp);
607     } else {
608         success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, NULL, 0) == 0;
609     }
610 
611     if (!success) {
612         ALOGW("GetHostByNameHandler: Error writing DNS result to client");
613     }
614 
615     if (mNetdEventListener != nullptr) {
616         std::vector<String16> ip_addrs;
617         int total_ip_addr_count = 0;
618         if (mReportingLevel == INetdEventListener::REPORTING_LEVEL_FULL) {
619             if (hp != nullptr && hp->h_addrtype == AF_INET) {
620                 in_addr** list = (in_addr**) hp->h_addr_list;
621                 for (int i = 0; list[i] != NULL; i++) {
622                     sockaddr_in sin = { .sin_family = AF_INET, .sin_addr = *list[i] };
623                     addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin, sizeof(sin));
624                     total_ip_addr_count++;
625                 }
626             } else if (hp != nullptr && hp->h_addrtype == AF_INET6) {
627                 in6_addr** list = (in6_addr**) hp->h_addr_list;
628                 for (int i = 0; list[i] != NULL; i++) {
629                     sockaddr_in6 sin6 = { .sin6_family = AF_INET6, .sin6_addr = *list[i] };
630                     addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin6, sizeof(sin6));
631                     total_ip_addr_count++;
632                 }
633             }
634         }
635         switch (mReportingLevel) {
636             case INetdEventListener::REPORTING_LEVEL_NONE:
637                 // Reporting is off.
638                 break;
639             case INetdEventListener::REPORTING_LEVEL_METRICS:
640                 // Metrics reporting is on. Send metrics.
641                 mNetdEventListener->onDnsEvent(mNetContext.dns_netid,
642                                                INetdEventListener::EVENT_GETHOSTBYNAME,
643                                                h_errno, latencyMs, String16(""), {}, -1, -1);
644                 break;
645             case INetdEventListener::REPORTING_LEVEL_FULL:
646                 // Full event info reporting is on. Send full info.
647                 mNetdEventListener->onDnsEvent(mNetContext.dns_netid,
648                                                INetdEventListener::EVENT_GETHOSTBYNAME,
649                                                h_errno, latencyMs, String16(mName), ip_addrs,
650                                                total_ip_addr_count, uid);
651                 break;
652         }
653     }
654 
655     mClient->decRef();
656 }
657 
658 
659 /*******************************************************
660  *                  GetHostByAddr                      *
661  *******************************************************/
GetHostByAddrCmd(const DnsProxyListener * dnsProxyListener)662 DnsProxyListener::GetHostByAddrCmd::GetHostByAddrCmd(const DnsProxyListener* dnsProxyListener) :
663         NetdCommand("gethostbyaddr"),
664         mDnsProxyListener(dnsProxyListener) {
665 }
666 
runCommand(SocketClient * cli,int argc,char ** argv)667 int DnsProxyListener::GetHostByAddrCmd::runCommand(SocketClient *cli,
668                                             int argc, char **argv) {
669     if (DBG) logArguments(argc, argv);
670 
671     if (argc != 5) {
672         char* msg = NULL;
673         asprintf(&msg, "Invalid number of arguments to gethostbyaddr: %i", argc);
674         ALOGW("%s", msg);
675         cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
676         free(msg);
677         return -1;
678     }
679 
680     char* addrStr = argv[1];
681     int addrLen = atoi(argv[2]);
682     int addrFamily = atoi(argv[3]);
683     uid_t uid = cli->getUid();
684     unsigned netId = strtoul(argv[4], NULL, 10);
685     const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
686 
687     void* addr = malloc(sizeof(struct in6_addr));
688     errno = 0;
689     int result = inet_pton(addrFamily, addrStr, addr);
690     if (result <= 0) {
691         char* msg = NULL;
692         asprintf(&msg, "inet_pton(\"%s\") failed %s", addrStr, strerror(errno));
693         ALOGW("%s", msg);
694         cli->sendMsg(ResponseCode::OperationFailed, msg, false);
695         free(addr);
696         free(msg);
697         return -1;
698     }
699 
700     android_net_context netcontext;
701     mDnsProxyListener->mNetCtrl->getNetworkContext(netId, uid, &netcontext);
702     if (useLocalNameservers) {
703         netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
704     }
705 
706     DnsProxyListener::GetHostByAddrHandler* handler =
707             new DnsProxyListener::GetHostByAddrHandler(cli, addr, addrLen, addrFamily, netcontext);
708     tryThreadOrError(cli, handler);
709     return 0;
710 }
711 
GetHostByAddrHandler(SocketClient * c,void * address,int addressLen,int addressFamily,const android_net_context & netcontext)712 DnsProxyListener::GetHostByAddrHandler::GetHostByAddrHandler(
713           SocketClient* c,
714           void* address,
715           int addressLen,
716           int addressFamily,
717           const android_net_context& netcontext)
718         : mClient(c),
719           mAddress(address),
720           mAddressLen(addressLen),
721           mAddressFamily(addressFamily),
722           mNetContext(netcontext) {
723 }
724 
~GetHostByAddrHandler()725 DnsProxyListener::GetHostByAddrHandler::~GetHostByAddrHandler() {
726     free(mAddress);
727 }
728 
run()729 void DnsProxyListener::GetHostByAddrHandler::run() {
730     if (DBG) {
731         ALOGD("DnsProxyListener::GetHostByAddrHandler::run");
732     }
733 
734     maybeFixupNetContext(&mNetContext);
735     const uid_t uid = mClient->getUid();
736     struct hostent* hp = nullptr;
737     if (queryLimiter.start(uid)) {
738         hp = android_gethostbyaddrfornetcontext(
739                 mAddress, mAddressLen, mAddressFamily, &mNetContext);
740         queryLimiter.finish(uid);
741     } else {
742         ALOGE("gethostbyaddr: from UID %d, max concurrent queries reached", uid);
743     }
744 
745     if (DBG) {
746         ALOGD("GetHostByAddrHandler::run gethostbyaddr errno: %s hp->h_name = %s, name_len = %zu",
747                 hp ? "success" : strerror(errno),
748                 (hp && hp->h_name) ? hp->h_name : "null",
749                 (hp && hp->h_name) ? strlen(hp->h_name) + 1 : 0);
750     }
751 
752     bool success = true;
753     if (hp) {
754         success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
755         success &= sendhostent(mClient, hp);
756     } else {
757         success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, NULL, 0) == 0;
758     }
759 
760     if (!success) {
761         ALOGW("GetHostByAddrHandler: Error writing DNS result to client");
762     }
763     mClient->decRef();
764 }
765 
766 }  // namespace net
767 }  // namespace android
768