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