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