DnsProxyListener.cpp revision d2617936acc15567fc5111bbdb4dde20845c3cba
1007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick/* 2007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick * Copyright (C) 2010 The Android Open Source Project 3007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick * 4007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick * Licensed under the Apache License, Version 2.0 (the "License"); 5007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick * you may not use this file except in compliance with the License. 6007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick * You may obtain a copy of the License at 7007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick * 8007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick * http://www.apache.org/licenses/LICENSE-2.0 9007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick * 10007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick * Unless required by applicable law or agreed to in writing, software 11007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick * distributed under the License is distributed on an "AS IS" BASIS, 12007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick * See the License for the specific language governing permissions and 14007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick * limitations under the License. 15007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick */ 16007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 17007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#include <arpa/inet.h> 18007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#include <dirent.h> 19007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#include <errno.h> 20007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#include <linux/if.h> 21007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#include <netdb.h> 22007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#include <netinet/in.h> 23007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#include <stdlib.h> 24007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#include <sys/socket.h> 25007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#include <sys/types.h> 26ff2c0d8c13457e43f0d4bf06d3177271aac104c1Olivier Bailly#include <string.h> 270cdb680c7648b0f48e6513926cb0a06d290a5cbeJurijs Oniscuks#include <pthread.h> 282d4610ec34cc78799a3353638fa05ee53276892aMattias Falk#include <resolv_iface.h> 292d4610ec34cc78799a3353638fa05ee53276892aMattias Falk#include <net/if.h> 30007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 31007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#define LOG_TAG "DnsProxyListener" 32007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#define DBG 0 332d4610ec34cc78799a3353638fa05ee53276892aMattias Falk#define VDBG 0 34007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 35007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#include <cutils/log.h> 36007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#include <sysutils/SocketClient.h> 37007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 38d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker#include "NetdConstants.h" 39007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#include "DnsProxyListener.h" 40ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun#include "ResponseCode.h" 41007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 42d2617936acc15567fc5111bbdb4dde20845c3cbaChad BrubakerDnsProxyListener::DnsProxyListener(UidMarkMap *map) : 43007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick FrameworkListener("dnsproxyd") { 44d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker registerCmd(new GetAddrInfoCmd(map)); 45d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker registerCmd(new GetHostByAddrCmd(map)); 46d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker registerCmd(new GetHostByNameCmd(map)); 47d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker mUidMarkMap = map; 482d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 492d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 502d4610ec34cc78799a3353638fa05ee53276892aMattias FalkDnsProxyListener::GetAddrInfoHandler::GetAddrInfoHandler(SocketClient *c, 512d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char* host, 522d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char* service, 532d4610ec34cc78799a3353638fa05ee53276892aMattias Falk struct addrinfo* hints, 542d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char* iface, 553acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker pid_t pid, 56d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker uid_t uid, 57d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker int mark) 582d4610ec34cc78799a3353638fa05ee53276892aMattias Falk : mClient(c), 592d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mHost(host), 602d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mService(service), 612d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mHints(hints), 622d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mIface(iface), 633acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker mPid(pid), 64d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker mUid(uid), 65d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker mMark(mark) { 66007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 67007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 68007e987fee7e815e0c4bc820f434a632b7a69a9dBrad FitzpatrickDnsProxyListener::GetAddrInfoHandler::~GetAddrInfoHandler() { 69007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick free(mHost); 70007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick free(mService); 71007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick free(mHints); 722d4610ec34cc78799a3353638fa05ee53276892aMattias Falk free(mIface); 73007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 74007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 75007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrickvoid DnsProxyListener::GetAddrInfoHandler::start() { 760cdb680c7648b0f48e6513926cb0a06d290a5cbeJurijs Oniscuks pthread_t thread; 770cdb680c7648b0f48e6513926cb0a06d290a5cbeJurijs Oniscuks pthread_create(&thread, NULL, 78007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick DnsProxyListener::GetAddrInfoHandler::threadStart, this); 792d4610ec34cc78799a3353638fa05ee53276892aMattias Falk pthread_detach(thread); 80007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 81007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 82007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrickvoid* DnsProxyListener::GetAddrInfoHandler::threadStart(void* obj) { 83007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick GetAddrInfoHandler* handler = reinterpret_cast<GetAddrInfoHandler*>(obj); 84007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick handler->run(); 85007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick delete handler; 86007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick pthread_exit(NULL); 87007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick return NULL; 88007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 89007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 90007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick// Sends 4 bytes of big-endian length, followed by the data. 91007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick// Returns true on success. 92007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrickstatic bool sendLenAndData(SocketClient *c, const int len, const void* data) { 93007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick uint32_t len_be = htonl(len); 94e6a3a58d6aa4b551e38e1e19fdfea2c0d2841b85Brad Fitzpatrick return c->sendData(&len_be, 4) == 0 && 95e6a3a58d6aa4b551e38e1e19fdfea2c0d2841b85Brad Fitzpatrick (len == 0 || c->sendData(data, len) == 0); 96007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 97007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 982d4610ec34cc78799a3353638fa05ee53276892aMattias Falk// Returns true on success 992d4610ec34cc78799a3353638fa05ee53276892aMattias Falkstatic bool sendhostent(SocketClient *c, struct hostent *hp) { 1002d4610ec34cc78799a3353638fa05ee53276892aMattias Falk bool success = true; 1012d4610ec34cc78799a3353638fa05ee53276892aMattias Falk int i; 1022d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (hp->h_name != NULL) { 1032d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendLenAndData(c, strlen(hp->h_name)+1, hp->h_name); 1042d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } else { 1052d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendLenAndData(c, 0, "") == 0; 1062d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 1072d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 1082d4610ec34cc78799a3353638fa05ee53276892aMattias Falk for (i=0; hp->h_aliases[i] != NULL; i++) { 1092d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendLenAndData(c, strlen(hp->h_aliases[i])+1, hp->h_aliases[i]); 1102d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 1112d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendLenAndData(c, 0, ""); // null to indicate we're done 1122d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 1132d4610ec34cc78799a3353638fa05ee53276892aMattias Falk uint32_t buf = htonl(hp->h_addrtype); 1142d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= c->sendData(&buf, sizeof(buf)) == 0; 1152d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 1162d4610ec34cc78799a3353638fa05ee53276892aMattias Falk buf = htonl(hp->h_length); 1172d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= c->sendData(&buf, sizeof(buf)) == 0; 1182d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 1192d4610ec34cc78799a3353638fa05ee53276892aMattias Falk for (i=0; hp->h_addr_list[i] != NULL; i++) { 1202d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendLenAndData(c, 16, hp->h_addr_list[i]); 1212d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 1222d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendLenAndData(c, 0, ""); // null to indicate we're done 1232d4610ec34cc78799a3353638fa05ee53276892aMattias Falk return success; 1242d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 1252d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 126007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrickvoid DnsProxyListener::GetAddrInfoHandler::run() { 127007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (DBG) { 1282d4610ec34cc78799a3353638fa05ee53276892aMattias Falk ALOGD("GetAddrInfoHandler, now for %s / %s / %s", mHost, mService, mIface); 1292d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 1302d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 1312d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char tmp[IF_NAMESIZE + 1]; 1322d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (mIface == NULL) { 1333acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker //fall back to the per uid interface if no per pid interface exists 1343acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker if(!_resolv_get_pids_associated_interface(mPid, tmp, sizeof(tmp))) 1353acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker _resolv_get_uids_associated_interface(mUid, tmp, sizeof(tmp)); 136007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 137007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 138007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick struct addrinfo* result = NULL; 1392d4610ec34cc78799a3353638fa05ee53276892aMattias Falk uint32_t rv = android_getaddrinfoforiface(mHost, mService, mHints, mIface ? mIface : tmp, 140d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker mMark, &result); 141ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun if (rv) { 142ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun // getaddrinfo failed 14340e0c13d6b77a9260b6da4c9e11cca8a5f994ea2Selim Gurun mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, &rv, sizeof(rv)); 144ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun } else { 145ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun bool success = !mClient->sendCode(ResponseCode::DnsProxyQueryResult); 146007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick struct addrinfo* ai = result; 147007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick while (ai && success) { 148007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick success = sendLenAndData(mClient, sizeof(struct addrinfo), ai) 149007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick && sendLenAndData(mClient, ai->ai_addrlen, ai->ai_addr) 150007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick && sendLenAndData(mClient, 151007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0, 152007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick ai->ai_canonname); 153007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick ai = ai->ai_next; 154007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 155007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick success = success && sendLenAndData(mClient, 0, ""); 156ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun if (!success) { 157ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun ALOGW("Error writing DNS result to client"); 158ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun } 159007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 160007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (result) { 161007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick freeaddrinfo(result); 162007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 16334ffd85aed3838d53bd1136c751a7825de1940e0Brad Fitzpatrick mClient->decRef(); 164007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 165007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 166d2617936acc15567fc5111bbdb4dde20845c3cbaChad BrubakerDnsProxyListener::GetAddrInfoCmd::GetAddrInfoCmd(UidMarkMap *uidMarkMap) : 167007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick NetdCommand("getaddrinfo") { 168d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker mUidMarkMap = uidMarkMap; 169007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 170007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 171007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrickint DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient *cli, 172007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick int argc, char **argv) { 1730475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom if (DBG) { 1740475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom for (int i = 0; i < argc; i++) { 1757b984e3f7e724f8a3547a707210319f3d479f261Steve Block ALOGD("argv[%i]=%s", i, argv[i]); 1760475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom } 1770475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom } 17852b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich if (argc != 8) { 179ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun char* msg = NULL; 180ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun asprintf( &msg, "Invalid number of arguments to getaddrinfo: %i", argc); 181ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun ALOGW("%s", msg); 182ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun cli->sendMsg(ResponseCode::CommandParameterError, msg, false); 183ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun free(msg); 1840475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom return -1; 185007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 186007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 187007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick char* name = argv[1]; 188007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (strcmp("^", name) == 0) { 189007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick name = NULL; 190007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } else { 191007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick name = strdup(name); 192007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 193007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 194007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick char* service = argv[2]; 195007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (strcmp("^", service) == 0) { 196007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick service = NULL; 197007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } else { 198007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick service = strdup(service); 199007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 200007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 2012d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char* iface = argv[7]; 2022d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (strcmp(iface, "^") == 0) { 2032d4610ec34cc78799a3353638fa05ee53276892aMattias Falk iface = NULL; 2042d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } else { 2052d4610ec34cc78799a3353638fa05ee53276892aMattias Falk iface = strdup(iface); 2062d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 2072d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 208007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick struct addrinfo* hints = NULL; 209007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick int ai_flags = atoi(argv[3]); 210007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick int ai_family = atoi(argv[4]); 211007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick int ai_socktype = atoi(argv[5]); 212007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick int ai_protocol = atoi(argv[6]); 21352b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich pid_t pid = cli->getPid(); 2143acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker uid_t uid = cli->getUid(); 2152d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 216007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (ai_flags != -1 || ai_family != -1 || 217007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick ai_socktype != -1 || ai_protocol != -1) { 218007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick hints = (struct addrinfo*) calloc(1, sizeof(struct addrinfo)); 219007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick hints->ai_flags = ai_flags; 220007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick hints->ai_family = ai_family; 221007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick hints->ai_socktype = ai_socktype; 222007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick hints->ai_protocol = ai_protocol; 223007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 224007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 225007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (DBG) { 2263acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker ALOGD("GetAddrInfoHandler for %s / %s / %s / %d / %d", 227007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick name ? name : "[nullhost]", 2282d4610ec34cc78799a3353638fa05ee53276892aMattias Falk service ? service : "[nullservice]", 2292d4610ec34cc78799a3353638fa05ee53276892aMattias Falk iface ? iface : "[nulliface]", 2303acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker pid, uid); 231007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 232007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 23334ffd85aed3838d53bd1136c751a7825de1940e0Brad Fitzpatrick cli->incRef(); 234007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick DnsProxyListener::GetAddrInfoHandler* handler = 235d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker new DnsProxyListener::GetAddrInfoHandler(cli, name, service, hints, iface, pid, uid, 236d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker mUidMarkMap->getMark(uid)); 237007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick handler->start(); 238007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 239007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick return 0; 240007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 2411dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 2421dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk/******************************************************* 2432d4610ec34cc78799a3353638fa05ee53276892aMattias Falk * GetHostByName * 2442d4610ec34cc78799a3353638fa05ee53276892aMattias Falk *******************************************************/ 245d2617936acc15567fc5111bbdb4dde20845c3cbaChad BrubakerDnsProxyListener::GetHostByNameCmd::GetHostByNameCmd(UidMarkMap *uidMarkMap) : 2462d4610ec34cc78799a3353638fa05ee53276892aMattias Falk NetdCommand("gethostbyname") { 247d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker mUidMarkMap = uidMarkMap; 2482d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 2492d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 2502d4610ec34cc78799a3353638fa05ee53276892aMattias Falkint DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient *cli, 2512d4610ec34cc78799a3353638fa05ee53276892aMattias Falk int argc, char **argv) { 2522d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (DBG) { 2532d4610ec34cc78799a3353638fa05ee53276892aMattias Falk for (int i = 0; i < argc; i++) { 2542d4610ec34cc78799a3353638fa05ee53276892aMattias Falk ALOGD("argv[%i]=%s", i, argv[i]); 2552d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 2562d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 25752b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich if (argc != 4) { 2582d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char* msg = NULL; 2592d4610ec34cc78799a3353638fa05ee53276892aMattias Falk asprintf(&msg, "Invalid number of arguments to gethostbyname: %i", argc); 2602d4610ec34cc78799a3353638fa05ee53276892aMattias Falk ALOGW("%s", msg); 2612d4610ec34cc78799a3353638fa05ee53276892aMattias Falk cli->sendMsg(ResponseCode::CommandParameterError, msg, false); 2622d4610ec34cc78799a3353638fa05ee53276892aMattias Falk free(msg); 2632d4610ec34cc78799a3353638fa05ee53276892aMattias Falk return -1; 2642d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 2652d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 26652b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich pid_t pid = cli->getPid(); 2673acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker uid_t uid = cli->getUid(); 26852b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich char* iface = argv[1]; 26952b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich char* name = argv[2]; 27052b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich int af = atoi(argv[3]); 2712d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 2722d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (strcmp(iface, "^") == 0) { 2732d4610ec34cc78799a3353638fa05ee53276892aMattias Falk iface = NULL; 2742d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } else { 2752d4610ec34cc78799a3353638fa05ee53276892aMattias Falk iface = strdup(iface); 2762d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 2772d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 2782d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (strcmp(name, "^") == 0) { 2792d4610ec34cc78799a3353638fa05ee53276892aMattias Falk name = NULL; 2802d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } else { 2812d4610ec34cc78799a3353638fa05ee53276892aMattias Falk name = strdup(name); 2822d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 2832d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 2842d4610ec34cc78799a3353638fa05ee53276892aMattias Falk cli->incRef(); 2852d4610ec34cc78799a3353638fa05ee53276892aMattias Falk DnsProxyListener::GetHostByNameHandler* handler = 286d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker new DnsProxyListener::GetHostByNameHandler(cli, pid, uid, iface, name, af, 287d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker mUidMarkMap->getMark(uid)); 2882d4610ec34cc78799a3353638fa05ee53276892aMattias Falk handler->start(); 2892d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 2902d4610ec34cc78799a3353638fa05ee53276892aMattias Falk return 0; 2912d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 2922d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 2932d4610ec34cc78799a3353638fa05ee53276892aMattias FalkDnsProxyListener::GetHostByNameHandler::GetHostByNameHandler(SocketClient* c, 29452b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich pid_t pid, 2953acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker uid_t uid, 2962d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char* iface, 2972d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char* name, 298d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker int af, 299d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker int mark) 3002d4610ec34cc78799a3353638fa05ee53276892aMattias Falk : mClient(c), 3012d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mPid(pid), 3023acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker mUid(uid), 3032d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mIface(iface), 3042d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mName(name), 305d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker mAf(af), 306d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker mMark(mark) { 3072d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 3082d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3092d4610ec34cc78799a3353638fa05ee53276892aMattias FalkDnsProxyListener::GetHostByNameHandler::~GetHostByNameHandler() { 3102d4610ec34cc78799a3353638fa05ee53276892aMattias Falk free(mIface); 3112d4610ec34cc78799a3353638fa05ee53276892aMattias Falk free(mName); 3122d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 3132d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3142d4610ec34cc78799a3353638fa05ee53276892aMattias Falkvoid DnsProxyListener::GetHostByNameHandler::start() { 3152d4610ec34cc78799a3353638fa05ee53276892aMattias Falk pthread_t thread; 3162d4610ec34cc78799a3353638fa05ee53276892aMattias Falk pthread_create(&thread, NULL, 3172d4610ec34cc78799a3353638fa05ee53276892aMattias Falk DnsProxyListener::GetHostByNameHandler::threadStart, this); 3182d4610ec34cc78799a3353638fa05ee53276892aMattias Falk pthread_detach(thread); 3192d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 3202d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3212d4610ec34cc78799a3353638fa05ee53276892aMattias Falkvoid* DnsProxyListener::GetHostByNameHandler::threadStart(void* obj) { 3222d4610ec34cc78799a3353638fa05ee53276892aMattias Falk GetHostByNameHandler* handler = reinterpret_cast<GetHostByNameHandler*>(obj); 3232d4610ec34cc78799a3353638fa05ee53276892aMattias Falk handler->run(); 3242d4610ec34cc78799a3353638fa05ee53276892aMattias Falk delete handler; 3252d4610ec34cc78799a3353638fa05ee53276892aMattias Falk pthread_exit(NULL); 3262d4610ec34cc78799a3353638fa05ee53276892aMattias Falk return NULL; 3272d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 3282d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3292d4610ec34cc78799a3353638fa05ee53276892aMattias Falkvoid DnsProxyListener::GetHostByNameHandler::run() { 3302d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (DBG) { 3312d4610ec34cc78799a3353638fa05ee53276892aMattias Falk ALOGD("DnsProxyListener::GetHostByNameHandler::run\n"); 3322d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 3332d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3342d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char iface[IF_NAMESIZE + 1]; 3352d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (mIface == NULL) { 3363acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker //fall back to the per uid interface if no per pid interface exists 3373acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker if(!_resolv_get_pids_associated_interface(mPid, iface, sizeof(iface))) 3383acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker _resolv_get_uids_associated_interface(mUid, iface, sizeof(iface)); 3392d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 3402d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3412d4610ec34cc78799a3353638fa05ee53276892aMattias Falk struct hostent* hp; 3422d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 343d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker hp = android_gethostbynameforiface(mName, mAf, mIface ? mIface : iface, mMark); 3442d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3452d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (DBG) { 3462d4610ec34cc78799a3353638fa05ee53276892aMattias Falk ALOGD("GetHostByNameHandler::run gethostbyname errno: %s hp->h_name = %s, name_len = %d\n", 3472d4610ec34cc78799a3353638fa05ee53276892aMattias Falk hp ? "success" : strerror(errno), 3482d4610ec34cc78799a3353638fa05ee53276892aMattias Falk (hp && hp->h_name) ? hp->h_name: "null", 3492d4610ec34cc78799a3353638fa05ee53276892aMattias Falk (hp && hp->h_name) ? strlen(hp->h_name)+ 1 : 0); 3502d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 3512d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3522d4610ec34cc78799a3353638fa05ee53276892aMattias Falk bool success = true; 3532d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (hp) { 3542d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0; 3552d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendhostent(mClient, hp); 3562d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } else { 3572d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, NULL, 0) == 0; 3582d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 3592d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3602d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (!success) { 3612d4610ec34cc78799a3353638fa05ee53276892aMattias Falk ALOGW("GetHostByNameHandler: Error writing DNS result to client\n"); 3622d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 3632d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mClient->decRef(); 3642d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 3652d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3662d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3672d4610ec34cc78799a3353638fa05ee53276892aMattias Falk/******************************************************* 3682d4610ec34cc78799a3353638fa05ee53276892aMattias Falk * GetHostByAddr * 3691dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk *******************************************************/ 370d2617936acc15567fc5111bbdb4dde20845c3cbaChad BrubakerDnsProxyListener::GetHostByAddrCmd::GetHostByAddrCmd(UidMarkMap *uidMarkMap) : 3711dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk NetdCommand("gethostbyaddr") { 372d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker mUidMarkMap = uidMarkMap; 3731dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk} 3741dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 3751dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falkint DnsProxyListener::GetHostByAddrCmd::runCommand(SocketClient *cli, 3761dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk int argc, char **argv) { 3770475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom if (DBG) { 3780475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom for (int i = 0; i < argc; i++) { 3797b984e3f7e724f8a3547a707210319f3d479f261Steve Block ALOGD("argv[%i]=%s", i, argv[i]); 3800475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom } 3810475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom } 38252b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich if (argc != 5) { 383ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun char* msg = NULL; 384ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun asprintf(&msg, "Invalid number of arguments to gethostbyaddr: %i", argc); 385ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun ALOGW("%s", msg); 386ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun cli->sendMsg(ResponseCode::CommandParameterError, msg, false); 387ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun free(msg); 3880475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom return -1; 3891dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk } 3901dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 3910475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom char* addrStr = argv[1]; 3921dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk int addrLen = atoi(argv[2]); 3931dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk int addrFamily = atoi(argv[3]); 39452b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich pid_t pid = cli->getPid(); 3953acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker uid_t uid = cli->getUid(); 39652b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich char* iface = argv[4]; 3972d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3982d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (strcmp(iface, "^") == 0) { 3992d4610ec34cc78799a3353638fa05ee53276892aMattias Falk iface = NULL; 4002d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } else { 4012d4610ec34cc78799a3353638fa05ee53276892aMattias Falk iface = strdup(iface); 4022d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 4031dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4040475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom void* addr = malloc(sizeof(struct in6_addr)); 4050475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom errno = 0; 4060475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom int result = inet_pton(addrFamily, addrStr, addr); 4070475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom if (result <= 0) { 408ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun char* msg = NULL; 409ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun asprintf(&msg, "inet_pton(\"%s\") failed %s", addrStr, strerror(errno)); 410ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun ALOGW("%s", msg); 411ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun cli->sendMsg(ResponseCode::OperationFailed, msg, false); 4120475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom free(addr); 413ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun free(msg); 4140475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom return -1; 4150475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom } 4160475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom 41734ffd85aed3838d53bd1136c751a7825de1940e0Brad Fitzpatrick cli->incRef(); 4181dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk DnsProxyListener::GetHostByAddrHandler* handler = 419d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker new DnsProxyListener::GetHostByAddrHandler(cli, addr, addrLen, addrFamily, iface, pid, 420d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker uid, mUidMarkMap->getMark(uid)); 4211dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk handler->start(); 4221dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4231dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk return 0; 4241dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk} 4251dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4262d4610ec34cc78799a3353638fa05ee53276892aMattias FalkDnsProxyListener::GetHostByAddrHandler::GetHostByAddrHandler(SocketClient* c, 4272d4610ec34cc78799a3353638fa05ee53276892aMattias Falk void* address, 4282d4610ec34cc78799a3353638fa05ee53276892aMattias Falk int addressLen, 4292d4610ec34cc78799a3353638fa05ee53276892aMattias Falk int addressFamily, 4302d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char* iface, 4313acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker pid_t pid, 432d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker uid_t uid, 433d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker int mark) 4342d4610ec34cc78799a3353638fa05ee53276892aMattias Falk : mClient(c), 4352d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mAddress(address), 4362d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mAddressLen(addressLen), 4372d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mAddressFamily(addressFamily), 4382d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mIface(iface), 4393acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker mPid(pid), 440d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker mUid(uid), 441d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker mMark(mark) { 4422d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 4432d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 4441dbd6cf148ea3fab57ec0644c336e94c78a488beMattias FalkDnsProxyListener::GetHostByAddrHandler::~GetHostByAddrHandler() { 4451dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk free(mAddress); 4462d4610ec34cc78799a3353638fa05ee53276892aMattias Falk free(mIface); 4471dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk} 4481dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4491dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falkvoid DnsProxyListener::GetHostByAddrHandler::start() { 4500cdb680c7648b0f48e6513926cb0a06d290a5cbeJurijs Oniscuks pthread_t thread; 4510cdb680c7648b0f48e6513926cb0a06d290a5cbeJurijs Oniscuks pthread_create(&thread, NULL, 4521dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk DnsProxyListener::GetHostByAddrHandler::threadStart, this); 4532d4610ec34cc78799a3353638fa05ee53276892aMattias Falk pthread_detach(thread); 4541dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk} 4551dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4561dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falkvoid* DnsProxyListener::GetHostByAddrHandler::threadStart(void* obj) { 4571dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk GetHostByAddrHandler* handler = reinterpret_cast<GetHostByAddrHandler*>(obj); 4581dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk handler->run(); 4591dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk delete handler; 4601dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk pthread_exit(NULL); 4611dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk return NULL; 4621dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk} 4631dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4641dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falkvoid DnsProxyListener::GetHostByAddrHandler::run() { 4651dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk if (DBG) { 4667b984e3f7e724f8a3547a707210319f3d479f261Steve Block ALOGD("DnsProxyListener::GetHostByAddrHandler::run\n"); 4671dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk } 4681dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4692d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char tmp[IF_NAMESIZE + 1]; 4702d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (mIface == NULL) { 4713acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker //fall back to the per uid interface if no per pid interface exists 4723acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker if(!_resolv_get_pids_associated_interface(mPid, tmp, sizeof(tmp))) 4733acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker _resolv_get_uids_associated_interface(mUid, tmp, sizeof(tmp)); 4742d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 4751dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk struct hostent* hp; 4761dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4770475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom // NOTE gethostbyaddr should take a void* but bionic thinks it should be char* 4782d4610ec34cc78799a3353638fa05ee53276892aMattias Falk hp = android_gethostbyaddrforiface((char*)mAddress, mAddressLen, mAddressFamily, 479d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker mIface ? mIface : tmp, mMark); 4801dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4811dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk if (DBG) { 4827b984e3f7e724f8a3547a707210319f3d479f261Steve Block ALOGD("GetHostByAddrHandler::run gethostbyaddr errno: %s hp->h_name = %s, name_len = %d\n", 4831dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk hp ? "success" : strerror(errno), 4841dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk (hp && hp->h_name) ? hp->h_name: "null", 4851dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk (hp && hp->h_name) ? strlen(hp->h_name)+ 1 : 0); 4861dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk } 4871dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4882d4610ec34cc78799a3353638fa05ee53276892aMattias Falk bool success = true; 489ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun if (hp) { 4902d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0; 4912d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendhostent(mClient, hp); 492ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun } else { 4932d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, NULL, 0) == 0; 494ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun } 4951dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4962d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (!success) { 4970e76b761a1514d5182675dd7b7d33725f62d6bc5Steve Block ALOGW("GetHostByAddrHandler: Error writing DNS result to client\n"); 4981dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk } 49934ffd85aed3838d53bd1136c751a7825de1940e0Brad Fitzpatrick mClient->decRef(); 5001dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk} 501