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 <chrono>
37 #include <vector>
38 
39 #include <cutils/log.h>
40 #include <utils/String16.h>
41 #include <sysutils/SocketClient.h>
42 
43 #include "Fwmark.h"
44 #include "DnsProxyListener.h"
45 #include "NetdConstants.h"
46 #include "NetworkController.h"
47 #include "ResponseCode.h"
48 #include "Stopwatch.h"
49 #include "android/net/metrics/INetdEventListener.h"
50 
51 using android::String16;
52 using android::net::metrics::INetdEventListener;
53 
54 namespace android {
55 namespace net {
56 
57 namespace {
58 
59 template<typename T>
threadMain(void * obj)60 void* threadMain(void* obj) {
61     std::unique_ptr<T> handler(reinterpret_cast<T*>(obj));
62     handler->run();
63     return nullptr;
64 }
65 
66 struct scoped_pthread_attr {
scoped_pthread_attrandroid::net::__anon12339bd10111::scoped_pthread_attr67     scoped_pthread_attr() { pthread_attr_init(&attr); }
~scoped_pthread_attrandroid::net::__anon12339bd10111::scoped_pthread_attr68     ~scoped_pthread_attr() { pthread_attr_destroy(&attr); }
69 
detachandroid::net::__anon12339bd10111::scoped_pthread_attr70     int detach() {
71         return pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
72     }
73 
74     pthread_attr_t attr;
75 };
76 
77 template<typename T>
threadLaunch(T * self)78 int threadLaunch(T* self) {
79     if (self == nullptr) { return -EINVAL;}
80 
81     scoped_pthread_attr scoped_attr;
82 
83     int rval = scoped_attr.detach();
84     if (rval != 0) { return -errno; }
85 
86     pthread_t thread;
87     rval = pthread_create(&thread, &scoped_attr.attr, &threadMain<T>, self);
88     if (rval != 0) {
89         ALOGW("pthread_create failed: %d", errno);
90         return -errno;
91     }
92 
93     return rval;
94 }
95 
96 template<typename T>
tryThreadOrError(SocketClient * cli,T * handler)97 void tryThreadOrError(SocketClient* cli, T* handler) {
98     cli->incRef();
99 
100     const int rval = threadLaunch(handler);
101     if (rval == 0) {
102         // SocketClient decRef() happens in the handler's run() method.
103         return;
104     }
105 
106     char* msg = NULL;
107     asprintf(&msg, "%s (%d)", strerror(-rval), -rval);
108     cli->sendMsg(ResponseCode::OperationFailed, msg, false);
109     free(msg);
110 
111     delete handler;
112     cli->decRef();
113 }
114 
115 }  // namespace
116 
DnsProxyListener(const NetworkController * netCtrl,EventReporter * eventReporter)117 DnsProxyListener::DnsProxyListener(const NetworkController* netCtrl, EventReporter* eventReporter) :
118         FrameworkListener("dnsproxyd"), mNetCtrl(netCtrl), mEventReporter(eventReporter) {
119     registerCmd(new GetAddrInfoCmd(this));
120     registerCmd(new GetHostByAddrCmd(this));
121     registerCmd(new GetHostByNameCmd(this));
122 }
123 
GetAddrInfoHandler(SocketClient * c,char * host,char * service,struct addrinfo * hints,const struct android_net_context & netcontext,const int reportingLevel,const android::sp<android::net::metrics::INetdEventListener> & netdEventListener)124 DnsProxyListener::GetAddrInfoHandler::GetAddrInfoHandler(
125         SocketClient *c, char* host, char* service, struct addrinfo* hints,
126         const struct android_net_context& netcontext, const int reportingLevel,
127         const android::sp<android::net::metrics::INetdEventListener>& netdEventListener)
128         : mClient(c),
129           mHost(host),
130           mService(service),
131           mHints(hints),
132           mNetContext(netcontext),
133           mReportingLevel(reportingLevel),
134           mNetdEventListener(netdEventListener) {
135 }
136 
~GetAddrInfoHandler()137 DnsProxyListener::GetAddrInfoHandler::~GetAddrInfoHandler() {
138     free(mHost);
139     free(mService);
140     free(mHints);
141 }
142 
sendBE32(SocketClient * c,uint32_t data)143 static bool sendBE32(SocketClient* c, uint32_t data) {
144     uint32_t be_data = htonl(data);
145     return c->sendData(&be_data, sizeof(be_data)) == 0;
146 }
147 
148 // Sends 4 bytes of big-endian length, followed by the data.
149 // Returns true on success.
sendLenAndData(SocketClient * c,const int len,const void * data)150 static bool sendLenAndData(SocketClient* c, const int len, const void* data) {
151     return sendBE32(c, len) && (len == 0 || c->sendData(data, len) == 0);
152 }
153 
154 // Returns true on success
sendhostent(SocketClient * c,struct hostent * hp)155 static bool sendhostent(SocketClient *c, struct hostent *hp) {
156     bool success = true;
157     int i;
158     if (hp->h_name != NULL) {
159         success &= sendLenAndData(c, strlen(hp->h_name)+1, hp->h_name);
160     } else {
161         success &= sendLenAndData(c, 0, "") == 0;
162     }
163 
164     for (i=0; hp->h_aliases[i] != NULL; i++) {
165         success &= sendLenAndData(c, strlen(hp->h_aliases[i])+1, hp->h_aliases[i]);
166     }
167     success &= sendLenAndData(c, 0, ""); // null to indicate we're done
168 
169     uint32_t buf = htonl(hp->h_addrtype);
170     success &= c->sendData(&buf, sizeof(buf)) == 0;
171 
172     buf = htonl(hp->h_length);
173     success &= c->sendData(&buf, sizeof(buf)) == 0;
174 
175     for (i=0; hp->h_addr_list[i] != NULL; i++) {
176         success &= sendLenAndData(c, 16, hp->h_addr_list[i]);
177     }
178     success &= sendLenAndData(c, 0, ""); // null to indicate we're done
179     return success;
180 }
181 
sendaddrinfo(SocketClient * c,struct addrinfo * ai)182 static bool sendaddrinfo(SocketClient* c, struct addrinfo* ai) {
183     // struct addrinfo {
184     //      int     ai_flags;       /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
185     //      int     ai_family;      /* PF_xxx */
186     //      int     ai_socktype;    /* SOCK_xxx */
187     //      int     ai_protocol;    /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
188     //      socklen_t ai_addrlen;   /* length of ai_addr */
189     //      char    *ai_canonname;  /* canonical name for hostname */
190     //      struct  sockaddr *ai_addr;      /* binary address */
191     //      struct  addrinfo *ai_next;      /* next structure in linked list */
192     // };
193 
194     // Write the struct piece by piece because we might be a 64-bit netd
195     // talking to a 32-bit process.
196     bool success =
197             sendBE32(c, ai->ai_flags) &&
198             sendBE32(c, ai->ai_family) &&
199             sendBE32(c, ai->ai_socktype) &&
200             sendBE32(c, ai->ai_protocol);
201     if (!success) {
202         return false;
203     }
204 
205     // ai_addrlen and ai_addr.
206     if (!sendLenAndData(c, ai->ai_addrlen, ai->ai_addr)) {
207         return false;
208     }
209 
210     // strlen(ai_canonname) and ai_canonname.
211     if (!sendLenAndData(c, ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0, ai->ai_canonname)) {
212         return false;
213     }
214 
215     return true;
216 }
217 
run()218 void DnsProxyListener::GetAddrInfoHandler::run() {
219     if (DBG) {
220         ALOGD("GetAddrInfoHandler, now for %s / %s / {%u,%u,%u,%u,%u}", mHost, mService,
221                 mNetContext.app_netid, mNetContext.app_mark,
222                 mNetContext.dns_netid, mNetContext.dns_mark,
223                 mNetContext.uid);
224     }
225 
226     struct addrinfo* result = NULL;
227     Stopwatch s;
228     uint32_t rv = android_getaddrinfofornetcontext(mHost, mService, mHints, &mNetContext, &result);
229     const int latencyMs = lround(s.timeTaken());
230 
231     if (rv) {
232         // getaddrinfo failed
233         mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, &rv, sizeof(rv));
234     } else {
235         bool success = !mClient->sendCode(ResponseCode::DnsProxyQueryResult);
236         struct addrinfo* ai = result;
237         while (ai && success) {
238             success = sendBE32(mClient, 1) && sendaddrinfo(mClient, ai);
239             ai = ai->ai_next;
240         }
241         success = success && sendBE32(mClient, 0);
242         if (!success) {
243             ALOGW("Error writing DNS result to client");
244         }
245     }
246     std::vector<String16> ip_addrs;
247     int total_ip_addr_count = 0;
248     if (result) {
249         if (mNetdEventListener != nullptr
250                 && mReportingLevel == INetdEventListener::REPORTING_LEVEL_FULL) {
251             for (addrinfo* ai = result; ai; ai = ai->ai_next) {
252                 sockaddr* ai_addr = ai->ai_addr;
253                 if (ai_addr) {
254                     addIpAddrWithinLimit(ip_addrs, ai_addr, ai->ai_addrlen);
255                     total_ip_addr_count++;
256                 }
257             }
258         }
259         freeaddrinfo(result);
260     }
261     mClient->decRef();
262     if (mNetdEventListener != nullptr) {
263         switch (mReportingLevel) {
264             case INetdEventListener::REPORTING_LEVEL_NONE:
265                 // Skip reporting.
266                 break;
267             case INetdEventListener::REPORTING_LEVEL_METRICS:
268                 // Metrics reporting is on. Send metrics.
269                 mNetdEventListener->onDnsEvent(mNetContext.dns_netid,
270                                                INetdEventListener::EVENT_GETADDRINFO, (int32_t) rv,
271                                                latencyMs, String16(""), {}, -1, -1);
272                 break;
273             case INetdEventListener::REPORTING_LEVEL_FULL:
274                 // Full event info reporting is on. Send full info.
275                 mNetdEventListener->onDnsEvent(mNetContext.dns_netid,
276                                                INetdEventListener::EVENT_GETADDRINFO, (int32_t) rv,
277                                                latencyMs, String16(mHost), ip_addrs,
278                                                total_ip_addr_count, mNetContext.uid);
279                 break;
280         }
281     } else {
282         ALOGW("Netd event listener is not available; skipping.");
283     }
284 }
285 
addIpAddrWithinLimit(std::vector<android::String16> & ip_addrs,const sockaddr * addr,socklen_t addrlen)286 void DnsProxyListener::addIpAddrWithinLimit(std::vector<android::String16>& ip_addrs,
287         const sockaddr* addr, socklen_t addrlen) {
288     // ipAddresses array is limited to first INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT
289     // addresses for A and AAAA. Total count of addresses is provided, to be able to tell whether
290     // some addresses didn't get logged.
291     if (ip_addrs.size() < INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT) {
292         char ip_addr[INET6_ADDRSTRLEN];
293         if (getnameinfo(addr, addrlen, ip_addr, sizeof(ip_addr), nullptr, 0, NI_NUMERICHOST) == 0) {
294             ip_addrs.push_back(String16(ip_addr));
295         }
296     }
297 }
298 
GetAddrInfoCmd(DnsProxyListener * dnsProxyListener)299 DnsProxyListener::GetAddrInfoCmd::GetAddrInfoCmd(DnsProxyListener* dnsProxyListener) :
300     NetdCommand("getaddrinfo"),
301     mDnsProxyListener(dnsProxyListener) {
302 }
303 
runCommand(SocketClient * cli,int argc,char ** argv)304 int DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient *cli,
305                                             int argc, char **argv) {
306     if (DBG) {
307         for (int i = 0; i < argc; i++) {
308             ALOGD("argv[%i]=%s", i, argv[i]);
309         }
310     }
311     if (argc != 8) {
312         char* msg = NULL;
313         asprintf( &msg, "Invalid number of arguments to getaddrinfo: %i", argc);
314         ALOGW("%s", msg);
315         cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
316         free(msg);
317         return -1;
318     }
319 
320     char* name = argv[1];
321     if (strcmp("^", name) == 0) {
322         name = NULL;
323     } else {
324         name = strdup(name);
325     }
326 
327     char* service = argv[2];
328     if (strcmp("^", service) == 0) {
329         service = NULL;
330     } else {
331         service = strdup(service);
332     }
333 
334     struct addrinfo* hints = NULL;
335     int ai_flags = atoi(argv[3]);
336     int ai_family = atoi(argv[4]);
337     int ai_socktype = atoi(argv[5]);
338     int ai_protocol = atoi(argv[6]);
339     unsigned netId = strtoul(argv[7], NULL, 10);
340     uid_t uid = cli->getUid();
341 
342     struct android_net_context netcontext;
343     mDnsProxyListener->mNetCtrl->getNetworkContext(netId, uid, &netcontext);
344 
345     if (ai_flags != -1 || ai_family != -1 ||
346         ai_socktype != -1 || ai_protocol != -1) {
347         hints = (struct addrinfo*) calloc(1, sizeof(struct addrinfo));
348         hints->ai_flags = ai_flags;
349         hints->ai_family = ai_family;
350         hints->ai_socktype = ai_socktype;
351         hints->ai_protocol = ai_protocol;
352     }
353 
354     if (DBG) {
355         ALOGD("GetAddrInfoHandler for %s / %s / {%u,%u,%u,%u,%u}",
356              name ? name : "[nullhost]",
357              service ? service : "[nullservice]",
358              netcontext.app_netid, netcontext.app_mark,
359              netcontext.dns_netid, netcontext.dns_mark,
360              netcontext.uid);
361     }
362 
363     const int metricsLevel = mDnsProxyListener->mEventReporter->getMetricsReportingLevel();
364 
365     DnsProxyListener::GetAddrInfoHandler* handler =
366             new DnsProxyListener::GetAddrInfoHandler(cli, name, service, hints, netcontext,
367                     metricsLevel, mDnsProxyListener->mEventReporter->getNetdEventListener());
368     tryThreadOrError(cli, handler);
369     return 0;
370 }
371 
372 /*******************************************************
373  *                  GetHostByName                      *
374  *******************************************************/
GetHostByNameCmd(DnsProxyListener * dnsProxyListener)375 DnsProxyListener::GetHostByNameCmd::GetHostByNameCmd(DnsProxyListener* dnsProxyListener) :
376       NetdCommand("gethostbyname"),
377       mDnsProxyListener(dnsProxyListener) {
378 }
379 
runCommand(SocketClient * cli,int argc,char ** argv)380 int DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient *cli,
381                                             int argc, char **argv) {
382     if (DBG) {
383         for (int i = 0; i < argc; i++) {
384             ALOGD("argv[%i]=%s", i, argv[i]);
385         }
386     }
387     if (argc != 4) {
388         char* msg = NULL;
389         asprintf(&msg, "Invalid number of arguments to gethostbyname: %i", argc);
390         ALOGW("%s", msg);
391         cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
392         free(msg);
393         return -1;
394     }
395 
396     uid_t uid = cli->getUid();
397     unsigned netId = strtoul(argv[1], NULL, 10);
398     char* name = argv[2];
399     int af = atoi(argv[3]);
400 
401     if (strcmp(name, "^") == 0) {
402         name = NULL;
403     } else {
404         name = strdup(name);
405     }
406 
407     uint32_t mark = mDnsProxyListener->mNetCtrl->getNetworkForDns(&netId, uid);
408     const int metricsLevel = mDnsProxyListener->mEventReporter->getMetricsReportingLevel();
409 
410     DnsProxyListener::GetHostByNameHandler* handler =
411             new DnsProxyListener::GetHostByNameHandler(cli, name, af, netId, mark, metricsLevel,
412                     mDnsProxyListener->mEventReporter->getNetdEventListener());
413     tryThreadOrError(cli, handler);
414     return 0;
415 }
416 
GetHostByNameHandler(SocketClient * c,char * name,int af,unsigned netId,uint32_t mark,const int metricsLevel,const android::sp<android::net::metrics::INetdEventListener> & netdEventListener)417 DnsProxyListener::GetHostByNameHandler::GetHostByNameHandler(
418         SocketClient* c, char* name, int af, unsigned netId, uint32_t mark, const int metricsLevel,
419         const android::sp<android::net::metrics::INetdEventListener>& netdEventListener)
420         : mClient(c),
421           mName(name),
422           mAf(af),
423           mNetId(netId),
424           mMark(mark),
425           mReportingLevel(metricsLevel),
426           mNetdEventListener(netdEventListener) {
427 }
428 
~GetHostByNameHandler()429 DnsProxyListener::GetHostByNameHandler::~GetHostByNameHandler() {
430     free(mName);
431 }
432 
run()433 void DnsProxyListener::GetHostByNameHandler::run() {
434     if (DBG) {
435         ALOGD("DnsProxyListener::GetHostByNameHandler::run\n");
436     }
437 
438     Stopwatch s;
439     struct hostent* hp = android_gethostbynamefornet(mName, mAf, mNetId, mMark);
440     const int latencyMs = lround(s.timeTaken());
441 
442     if (DBG) {
443         ALOGD("GetHostByNameHandler::run gethostbyname errno: %s hp->h_name = %s, name_len = %zu\n",
444                 hp ? "success" : strerror(errno),
445                 (hp && hp->h_name) ? hp->h_name : "null",
446                 (hp && hp->h_name) ? strlen(hp->h_name) + 1 : 0);
447     }
448 
449     bool success = true;
450     if (hp) {
451         success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
452         success &= sendhostent(mClient, hp);
453     } else {
454         success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, NULL, 0) == 0;
455     }
456 
457     if (!success) {
458         ALOGW("GetHostByNameHandler: Error writing DNS result to client\n");
459     }
460 
461     if (mNetdEventListener != nullptr) {
462         std::vector<String16> ip_addrs;
463         int total_ip_addr_count = 0;
464         if (mReportingLevel == INetdEventListener::REPORTING_LEVEL_FULL) {
465             if (hp != nullptr && hp->h_addrtype == AF_INET) {
466                 in_addr** list = (in_addr**) hp->h_addr_list;
467                 for (int i = 0; list[i] != NULL; i++) {
468                     sockaddr_in sin = { .sin_family = AF_INET, .sin_addr = *list[i] };
469                     addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin, sizeof(sin));
470                     total_ip_addr_count++;
471                 }
472             } else if (hp != nullptr && hp->h_addrtype == AF_INET6) {
473                 in6_addr** list = (in6_addr**) hp->h_addr_list;
474                 for (int i = 0; list[i] != NULL; i++) {
475                     sockaddr_in6 sin6 = { .sin6_family = AF_INET6, .sin6_addr = *list[i] };
476                     addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin6, sizeof(sin6));
477                     total_ip_addr_count++;
478                 }
479             }
480         }
481         switch (mReportingLevel) {
482             case INetdEventListener::REPORTING_LEVEL_NONE:
483                 // Reporting is off.
484                 break;
485             case INetdEventListener::REPORTING_LEVEL_METRICS:
486                 // Metrics reporting is on. Send metrics.
487                 mNetdEventListener->onDnsEvent(mNetId, INetdEventListener::EVENT_GETHOSTBYNAME,
488                                                h_errno, latencyMs, String16(""), {}, -1, -1);
489                 break;
490             case INetdEventListener::REPORTING_LEVEL_FULL:
491                 // Full event info reporting is on. Send full info.
492                 mNetdEventListener->onDnsEvent(mNetId, INetdEventListener::EVENT_GETHOSTBYNAME,
493                                                h_errno, latencyMs, String16(mName), ip_addrs,
494                                                total_ip_addr_count, mClient->getUid());
495                 break;
496         }
497     }
498 
499     mClient->decRef();
500 }
501 
502 
503 /*******************************************************
504  *                  GetHostByAddr                      *
505  *******************************************************/
GetHostByAddrCmd(const DnsProxyListener * dnsProxyListener)506 DnsProxyListener::GetHostByAddrCmd::GetHostByAddrCmd(const DnsProxyListener* dnsProxyListener) :
507         NetdCommand("gethostbyaddr"),
508         mDnsProxyListener(dnsProxyListener) {
509 }
510 
runCommand(SocketClient * cli,int argc,char ** argv)511 int DnsProxyListener::GetHostByAddrCmd::runCommand(SocketClient *cli,
512                                             int argc, char **argv) {
513     if (DBG) {
514         for (int i = 0; i < argc; i++) {
515             ALOGD("argv[%i]=%s", i, argv[i]);
516         }
517     }
518     if (argc != 5) {
519         char* msg = NULL;
520         asprintf(&msg, "Invalid number of arguments to gethostbyaddr: %i", argc);
521         ALOGW("%s", msg);
522         cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
523         free(msg);
524         return -1;
525     }
526 
527     char* addrStr = argv[1];
528     int addrLen = atoi(argv[2]);
529     int addrFamily = atoi(argv[3]);
530     uid_t uid = cli->getUid();
531     unsigned netId = strtoul(argv[4], NULL, 10);
532 
533     void* addr = malloc(sizeof(struct in6_addr));
534     errno = 0;
535     int result = inet_pton(addrFamily, addrStr, addr);
536     if (result <= 0) {
537         char* msg = NULL;
538         asprintf(&msg, "inet_pton(\"%s\") failed %s", addrStr, strerror(errno));
539         ALOGW("%s", msg);
540         cli->sendMsg(ResponseCode::OperationFailed, msg, false);
541         free(addr);
542         free(msg);
543         return -1;
544     }
545 
546     uint32_t mark = mDnsProxyListener->mNetCtrl->getNetworkForDns(&netId, uid);
547 
548     DnsProxyListener::GetHostByAddrHandler* handler =
549             new DnsProxyListener::GetHostByAddrHandler(cli, addr, addrLen, addrFamily, netId, mark);
550     tryThreadOrError(cli, handler);
551     return 0;
552 }
553 
GetHostByAddrHandler(SocketClient * c,void * address,int addressLen,int addressFamily,unsigned netId,uint32_t mark)554 DnsProxyListener::GetHostByAddrHandler::GetHostByAddrHandler(SocketClient* c,
555                                                              void* address,
556                                                              int   addressLen,
557                                                              int   addressFamily,
558                                                              unsigned netId,
559                                                              uint32_t mark)
560         : mClient(c),
561           mAddress(address),
562           mAddressLen(addressLen),
563           mAddressFamily(addressFamily),
564           mNetId(netId),
565           mMark(mark) {
566 }
567 
~GetHostByAddrHandler()568 DnsProxyListener::GetHostByAddrHandler::~GetHostByAddrHandler() {
569     free(mAddress);
570 }
571 
run()572 void DnsProxyListener::GetHostByAddrHandler::run() {
573     if (DBG) {
574         ALOGD("DnsProxyListener::GetHostByAddrHandler::run\n");
575     }
576     struct hostent* hp;
577 
578     // NOTE gethostbyaddr should take a void* but bionic thinks it should be char*
579     hp = android_gethostbyaddrfornet((char*)mAddress, mAddressLen, mAddressFamily, mNetId, mMark);
580 
581     if (DBG) {
582         ALOGD("GetHostByAddrHandler::run gethostbyaddr errno: %s hp->h_name = %s, name_len = %zu\n",
583                 hp ? "success" : strerror(errno),
584                 (hp && hp->h_name) ? hp->h_name : "null",
585                 (hp && hp->h_name) ? strlen(hp->h_name) + 1 : 0);
586     }
587 
588     bool success = true;
589     if (hp) {
590         success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
591         success &= sendhostent(mClient, hp);
592     } else {
593         success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, NULL, 0) == 0;
594     }
595 
596     if (!success) {
597         ALOGW("GetHostByAddrHandler: Error writing DNS result to client\n");
598     }
599     mClient->decRef();
600 }
601 
602 }  // namespace net
603 }  // namespace android
604