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