DnsProxyListener.cpp revision 3acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3
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 38007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#include "DnsProxyListener.h" 39ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun#include "ResponseCode.h" 40007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 41007e987fee7e815e0c4bc820f434a632b7a69a9dBrad FitzpatrickDnsProxyListener::DnsProxyListener() : 42007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick FrameworkListener("dnsproxyd") { 43007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick registerCmd(new GetAddrInfoCmd()); 441dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk registerCmd(new GetHostByAddrCmd()); 452d4610ec34cc78799a3353638fa05ee53276892aMattias Falk registerCmd(new GetHostByNameCmd()); 462d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 472d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 482d4610ec34cc78799a3353638fa05ee53276892aMattias FalkDnsProxyListener::GetAddrInfoHandler::GetAddrInfoHandler(SocketClient *c, 492d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char* host, 502d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char* service, 512d4610ec34cc78799a3353638fa05ee53276892aMattias Falk struct addrinfo* hints, 522d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char* iface, 533acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker pid_t pid, 543acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker uid_t uid) 552d4610ec34cc78799a3353638fa05ee53276892aMattias Falk : mClient(c), 562d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mHost(host), 572d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mService(service), 582d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mHints(hints), 592d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mIface(iface), 603acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker mPid(pid), 613acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker mUid(uid) { 62007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 63007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 64007e987fee7e815e0c4bc820f434a632b7a69a9dBrad FitzpatrickDnsProxyListener::GetAddrInfoHandler::~GetAddrInfoHandler() { 65007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick free(mHost); 66007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick free(mService); 67007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick free(mHints); 682d4610ec34cc78799a3353638fa05ee53276892aMattias Falk free(mIface); 69007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 70007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 71007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrickvoid DnsProxyListener::GetAddrInfoHandler::start() { 720cdb680c7648b0f48e6513926cb0a06d290a5cbeJurijs Oniscuks pthread_t thread; 730cdb680c7648b0f48e6513926cb0a06d290a5cbeJurijs Oniscuks pthread_create(&thread, NULL, 74007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick DnsProxyListener::GetAddrInfoHandler::threadStart, this); 752d4610ec34cc78799a3353638fa05ee53276892aMattias Falk pthread_detach(thread); 76007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 77007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 78007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrickvoid* DnsProxyListener::GetAddrInfoHandler::threadStart(void* obj) { 79007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick GetAddrInfoHandler* handler = reinterpret_cast<GetAddrInfoHandler*>(obj); 80007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick handler->run(); 81007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick delete handler; 82007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick pthread_exit(NULL); 83007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick return NULL; 84007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 85007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 86007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick// Sends 4 bytes of big-endian length, followed by the data. 87007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick// Returns true on success. 88007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrickstatic bool sendLenAndData(SocketClient *c, const int len, const void* data) { 89007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick uint32_t len_be = htonl(len); 90e6a3a58d6aa4b551e38e1e19fdfea2c0d2841b85Brad Fitzpatrick return c->sendData(&len_be, 4) == 0 && 91e6a3a58d6aa4b551e38e1e19fdfea2c0d2841b85Brad Fitzpatrick (len == 0 || c->sendData(data, len) == 0); 92007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 93007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 942d4610ec34cc78799a3353638fa05ee53276892aMattias Falk// Returns true on success 952d4610ec34cc78799a3353638fa05ee53276892aMattias Falkstatic bool sendhostent(SocketClient *c, struct hostent *hp) { 962d4610ec34cc78799a3353638fa05ee53276892aMattias Falk bool success = true; 972d4610ec34cc78799a3353638fa05ee53276892aMattias Falk int i; 982d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (hp->h_name != NULL) { 992d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendLenAndData(c, strlen(hp->h_name)+1, hp->h_name); 1002d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } else { 1012d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendLenAndData(c, 0, "") == 0; 1022d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 1032d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 1042d4610ec34cc78799a3353638fa05ee53276892aMattias Falk for (i=0; hp->h_aliases[i] != NULL; i++) { 1052d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendLenAndData(c, strlen(hp->h_aliases[i])+1, hp->h_aliases[i]); 1062d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 1072d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendLenAndData(c, 0, ""); // null to indicate we're done 1082d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 1092d4610ec34cc78799a3353638fa05ee53276892aMattias Falk uint32_t buf = htonl(hp->h_addrtype); 1102d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= c->sendData(&buf, sizeof(buf)) == 0; 1112d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 1122d4610ec34cc78799a3353638fa05ee53276892aMattias Falk buf = htonl(hp->h_length); 1132d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= c->sendData(&buf, sizeof(buf)) == 0; 1142d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 1152d4610ec34cc78799a3353638fa05ee53276892aMattias Falk for (i=0; hp->h_addr_list[i] != NULL; i++) { 1162d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendLenAndData(c, 16, hp->h_addr_list[i]); 1172d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 1182d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendLenAndData(c, 0, ""); // null to indicate we're done 1192d4610ec34cc78799a3353638fa05ee53276892aMattias Falk return success; 1202d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 1212d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 122007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrickvoid DnsProxyListener::GetAddrInfoHandler::run() { 123007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (DBG) { 1242d4610ec34cc78799a3353638fa05ee53276892aMattias Falk ALOGD("GetAddrInfoHandler, now for %s / %s / %s", mHost, mService, mIface); 1252d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 1262d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 1272d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char tmp[IF_NAMESIZE + 1]; 1282d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (mIface == NULL) { 1293acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker //fall back to the per uid interface if no per pid interface exists 1303acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker if(!_resolv_get_pids_associated_interface(mPid, tmp, sizeof(tmp))) 1313acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker _resolv_get_uids_associated_interface(mUid, tmp, sizeof(tmp)); 132007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 133007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 134007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick struct addrinfo* result = NULL; 1352d4610ec34cc78799a3353638fa05ee53276892aMattias Falk uint32_t rv = android_getaddrinfoforiface(mHost, mService, mHints, mIface ? mIface : tmp, 1362d4610ec34cc78799a3353638fa05ee53276892aMattias Falk &result); 137ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun if (rv) { 138ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun // getaddrinfo failed 13940e0c13d6b77a9260b6da4c9e11cca8a5f994ea2Selim Gurun mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, &rv, sizeof(rv)); 140ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun } else { 141ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun bool success = !mClient->sendCode(ResponseCode::DnsProxyQueryResult); 142007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick struct addrinfo* ai = result; 143007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick while (ai && success) { 144007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick success = sendLenAndData(mClient, sizeof(struct addrinfo), ai) 145007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick && sendLenAndData(mClient, ai->ai_addrlen, ai->ai_addr) 146007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick && sendLenAndData(mClient, 147007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0, 148007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick ai->ai_canonname); 149007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick ai = ai->ai_next; 150007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 151007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick success = success && sendLenAndData(mClient, 0, ""); 152ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun if (!success) { 153ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun ALOGW("Error writing DNS result to client"); 154ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun } 155007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 156007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (result) { 157007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick freeaddrinfo(result); 158007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 15934ffd85aed3838d53bd1136c751a7825de1940e0Brad Fitzpatrick mClient->decRef(); 160007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 161007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 162007e987fee7e815e0c4bc820f434a632b7a69a9dBrad FitzpatrickDnsProxyListener::GetAddrInfoCmd::GetAddrInfoCmd() : 163007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick NetdCommand("getaddrinfo") { 164007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 165007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 166007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrickint DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient *cli, 167007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick int argc, char **argv) { 1680475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom if (DBG) { 1690475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom for (int i = 0; i < argc; i++) { 1707b984e3f7e724f8a3547a707210319f3d479f261Steve Block ALOGD("argv[%i]=%s", i, argv[i]); 1710475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom } 1720475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom } 17352b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich if (argc != 8) { 174ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun char* msg = NULL; 175ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun asprintf( &msg, "Invalid number of arguments to getaddrinfo: %i", argc); 176ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun ALOGW("%s", msg); 177ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun cli->sendMsg(ResponseCode::CommandParameterError, msg, false); 178ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun free(msg); 1790475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom return -1; 180007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 181007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 182007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick char* name = argv[1]; 183007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (strcmp("^", name) == 0) { 184007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick name = NULL; 185007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } else { 186007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick name = strdup(name); 187007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 188007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 189007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick char* service = argv[2]; 190007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (strcmp("^", service) == 0) { 191007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick service = NULL; 192007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } else { 193007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick service = strdup(service); 194007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 195007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 1962d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char* iface = argv[7]; 1972d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (strcmp(iface, "^") == 0) { 1982d4610ec34cc78799a3353638fa05ee53276892aMattias Falk iface = NULL; 1992d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } else { 2002d4610ec34cc78799a3353638fa05ee53276892aMattias Falk iface = strdup(iface); 2012d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 2022d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 203007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick struct addrinfo* hints = NULL; 204007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick int ai_flags = atoi(argv[3]); 205007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick int ai_family = atoi(argv[4]); 206007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick int ai_socktype = atoi(argv[5]); 207007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick int ai_protocol = atoi(argv[6]); 20852b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich pid_t pid = cli->getPid(); 2093acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker uid_t uid = cli->getUid(); 2102d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 211007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (ai_flags != -1 || ai_family != -1 || 212007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick ai_socktype != -1 || ai_protocol != -1) { 213007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick hints = (struct addrinfo*) calloc(1, sizeof(struct addrinfo)); 214007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick hints->ai_flags = ai_flags; 215007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick hints->ai_family = ai_family; 216007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick hints->ai_socktype = ai_socktype; 217007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick hints->ai_protocol = ai_protocol; 218007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 219007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 220007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (DBG) { 2213acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker ALOGD("GetAddrInfoHandler for %s / %s / %s / %d / %d", 222007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick name ? name : "[nullhost]", 2232d4610ec34cc78799a3353638fa05ee53276892aMattias Falk service ? service : "[nullservice]", 2242d4610ec34cc78799a3353638fa05ee53276892aMattias Falk iface ? iface : "[nulliface]", 2253acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker pid, uid); 226007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 227007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 22834ffd85aed3838d53bd1136c751a7825de1940e0Brad Fitzpatrick cli->incRef(); 229007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick DnsProxyListener::GetAddrInfoHandler* handler = 2303acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker new DnsProxyListener::GetAddrInfoHandler(cli, name, service, hints, iface, pid, uid); 231007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick handler->start(); 232007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 233007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick return 0; 234007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 2351dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 2361dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk/******************************************************* 2372d4610ec34cc78799a3353638fa05ee53276892aMattias Falk * GetHostByName * 2382d4610ec34cc78799a3353638fa05ee53276892aMattias Falk *******************************************************/ 2392d4610ec34cc78799a3353638fa05ee53276892aMattias FalkDnsProxyListener::GetHostByNameCmd::GetHostByNameCmd() : 2402d4610ec34cc78799a3353638fa05ee53276892aMattias Falk NetdCommand("gethostbyname") { 2412d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 2422d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 2432d4610ec34cc78799a3353638fa05ee53276892aMattias Falkint DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient *cli, 2442d4610ec34cc78799a3353638fa05ee53276892aMattias Falk int argc, char **argv) { 2452d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (DBG) { 2462d4610ec34cc78799a3353638fa05ee53276892aMattias Falk for (int i = 0; i < argc; i++) { 2472d4610ec34cc78799a3353638fa05ee53276892aMattias Falk ALOGD("argv[%i]=%s", i, argv[i]); 2482d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 2492d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 25052b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich if (argc != 4) { 2512d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char* msg = NULL; 2522d4610ec34cc78799a3353638fa05ee53276892aMattias Falk asprintf(&msg, "Invalid number of arguments to gethostbyname: %i", argc); 2532d4610ec34cc78799a3353638fa05ee53276892aMattias Falk ALOGW("%s", msg); 2542d4610ec34cc78799a3353638fa05ee53276892aMattias Falk cli->sendMsg(ResponseCode::CommandParameterError, msg, false); 2552d4610ec34cc78799a3353638fa05ee53276892aMattias Falk free(msg); 2562d4610ec34cc78799a3353638fa05ee53276892aMattias Falk return -1; 2572d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 2582d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 25952b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich pid_t pid = cli->getPid(); 2603acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker uid_t uid = cli->getUid(); 26152b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich char* iface = argv[1]; 26252b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich char* name = argv[2]; 26352b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich int af = atoi(argv[3]); 2642d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 2652d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (strcmp(iface, "^") == 0) { 2662d4610ec34cc78799a3353638fa05ee53276892aMattias Falk iface = NULL; 2672d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } else { 2682d4610ec34cc78799a3353638fa05ee53276892aMattias Falk iface = strdup(iface); 2692d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 2702d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 2712d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (strcmp(name, "^") == 0) { 2722d4610ec34cc78799a3353638fa05ee53276892aMattias Falk name = NULL; 2732d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } else { 2742d4610ec34cc78799a3353638fa05ee53276892aMattias Falk name = strdup(name); 2752d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 2762d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 2772d4610ec34cc78799a3353638fa05ee53276892aMattias Falk cli->incRef(); 2782d4610ec34cc78799a3353638fa05ee53276892aMattias Falk DnsProxyListener::GetHostByNameHandler* handler = 2793acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker new DnsProxyListener::GetHostByNameHandler(cli, pid, uid, iface, name, af); 2802d4610ec34cc78799a3353638fa05ee53276892aMattias Falk handler->start(); 2812d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 2822d4610ec34cc78799a3353638fa05ee53276892aMattias Falk return 0; 2832d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 2842d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 2852d4610ec34cc78799a3353638fa05ee53276892aMattias FalkDnsProxyListener::GetHostByNameHandler::GetHostByNameHandler(SocketClient* c, 28652b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich pid_t pid, 2873acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker uid_t uid, 2882d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char* iface, 2892d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char* name, 2902d4610ec34cc78799a3353638fa05ee53276892aMattias Falk int af) 2912d4610ec34cc78799a3353638fa05ee53276892aMattias Falk : mClient(c), 2922d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mPid(pid), 2933acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker mUid(uid), 2942d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mIface(iface), 2952d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mName(name), 2962d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mAf(af) { 2972d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 2982d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 2992d4610ec34cc78799a3353638fa05ee53276892aMattias FalkDnsProxyListener::GetHostByNameHandler::~GetHostByNameHandler() { 3002d4610ec34cc78799a3353638fa05ee53276892aMattias Falk free(mIface); 3012d4610ec34cc78799a3353638fa05ee53276892aMattias Falk free(mName); 3022d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 3032d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3042d4610ec34cc78799a3353638fa05ee53276892aMattias Falkvoid DnsProxyListener::GetHostByNameHandler::start() { 3052d4610ec34cc78799a3353638fa05ee53276892aMattias Falk pthread_t thread; 3062d4610ec34cc78799a3353638fa05ee53276892aMattias Falk pthread_create(&thread, NULL, 3072d4610ec34cc78799a3353638fa05ee53276892aMattias Falk DnsProxyListener::GetHostByNameHandler::threadStart, this); 3082d4610ec34cc78799a3353638fa05ee53276892aMattias Falk pthread_detach(thread); 3092d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 3102d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3112d4610ec34cc78799a3353638fa05ee53276892aMattias Falkvoid* DnsProxyListener::GetHostByNameHandler::threadStart(void* obj) { 3122d4610ec34cc78799a3353638fa05ee53276892aMattias Falk GetHostByNameHandler* handler = reinterpret_cast<GetHostByNameHandler*>(obj); 3132d4610ec34cc78799a3353638fa05ee53276892aMattias Falk handler->run(); 3142d4610ec34cc78799a3353638fa05ee53276892aMattias Falk delete handler; 3152d4610ec34cc78799a3353638fa05ee53276892aMattias Falk pthread_exit(NULL); 3162d4610ec34cc78799a3353638fa05ee53276892aMattias Falk return NULL; 3172d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 3182d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3192d4610ec34cc78799a3353638fa05ee53276892aMattias Falkvoid DnsProxyListener::GetHostByNameHandler::run() { 3202d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (DBG) { 3212d4610ec34cc78799a3353638fa05ee53276892aMattias Falk ALOGD("DnsProxyListener::GetHostByNameHandler::run\n"); 3222d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 3232d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3242d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char iface[IF_NAMESIZE + 1]; 3252d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (mIface == NULL) { 3263acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker //fall back to the per uid interface if no per pid interface exists 3273acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker if(!_resolv_get_pids_associated_interface(mPid, iface, sizeof(iface))) 3283acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker _resolv_get_uids_associated_interface(mUid, iface, sizeof(iface)); 3292d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 3302d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3312d4610ec34cc78799a3353638fa05ee53276892aMattias Falk struct hostent* hp; 3322d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3332d4610ec34cc78799a3353638fa05ee53276892aMattias Falk hp = android_gethostbynameforiface(mName, mAf, mIface ? mIface : iface); 3342d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3352d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (DBG) { 3362d4610ec34cc78799a3353638fa05ee53276892aMattias Falk ALOGD("GetHostByNameHandler::run gethostbyname errno: %s hp->h_name = %s, name_len = %d\n", 3372d4610ec34cc78799a3353638fa05ee53276892aMattias Falk hp ? "success" : strerror(errno), 3382d4610ec34cc78799a3353638fa05ee53276892aMattias Falk (hp && hp->h_name) ? hp->h_name: "null", 3392d4610ec34cc78799a3353638fa05ee53276892aMattias Falk (hp && hp->h_name) ? strlen(hp->h_name)+ 1 : 0); 3402d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 3412d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3422d4610ec34cc78799a3353638fa05ee53276892aMattias Falk bool success = true; 3432d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (hp) { 3442d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0; 3452d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendhostent(mClient, hp); 3462d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } else { 3472d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, NULL, 0) == 0; 3482d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 3492d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3502d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (!success) { 3512d4610ec34cc78799a3353638fa05ee53276892aMattias Falk ALOGW("GetHostByNameHandler: Error writing DNS result to client\n"); 3522d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 3532d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mClient->decRef(); 3542d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 3552d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3562d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3572d4610ec34cc78799a3353638fa05ee53276892aMattias Falk/******************************************************* 3582d4610ec34cc78799a3353638fa05ee53276892aMattias Falk * GetHostByAddr * 3591dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk *******************************************************/ 3601dbd6cf148ea3fab57ec0644c336e94c78a488beMattias FalkDnsProxyListener::GetHostByAddrCmd::GetHostByAddrCmd() : 3611dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk NetdCommand("gethostbyaddr") { 3621dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk} 3631dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 3641dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falkint DnsProxyListener::GetHostByAddrCmd::runCommand(SocketClient *cli, 3651dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk int argc, char **argv) { 3660475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom if (DBG) { 3670475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom for (int i = 0; i < argc; i++) { 3687b984e3f7e724f8a3547a707210319f3d479f261Steve Block ALOGD("argv[%i]=%s", i, argv[i]); 3690475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom } 3700475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom } 37152b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich if (argc != 5) { 372ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun char* msg = NULL; 373ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun asprintf(&msg, "Invalid number of arguments to gethostbyaddr: %i", argc); 374ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun ALOGW("%s", msg); 375ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun cli->sendMsg(ResponseCode::CommandParameterError, msg, false); 376ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun free(msg); 3770475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom return -1; 3781dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk } 3791dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 3800475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom char* addrStr = argv[1]; 3811dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk int addrLen = atoi(argv[2]); 3821dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk int addrFamily = atoi(argv[3]); 38352b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich pid_t pid = cli->getPid(); 3843acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker uid_t uid = cli->getUid(); 38552b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich char* iface = argv[4]; 3862d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3872d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (strcmp(iface, "^") == 0) { 3882d4610ec34cc78799a3353638fa05ee53276892aMattias Falk iface = NULL; 3892d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } else { 3902d4610ec34cc78799a3353638fa05ee53276892aMattias Falk iface = strdup(iface); 3912d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 3921dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 3930475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom void* addr = malloc(sizeof(struct in6_addr)); 3940475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom errno = 0; 3950475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom int result = inet_pton(addrFamily, addrStr, addr); 3960475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom if (result <= 0) { 397ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun char* msg = NULL; 398ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun asprintf(&msg, "inet_pton(\"%s\") failed %s", addrStr, strerror(errno)); 399ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun ALOGW("%s", msg); 400ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun cli->sendMsg(ResponseCode::OperationFailed, msg, false); 4010475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom free(addr); 402ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun free(msg); 4030475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom return -1; 4040475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom } 4050475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom 40634ffd85aed3838d53bd1136c751a7825de1940e0Brad Fitzpatrick cli->incRef(); 4071dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk DnsProxyListener::GetHostByAddrHandler* handler = 4083acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker new DnsProxyListener::GetHostByAddrHandler(cli, addr, addrLen, addrFamily, iface, pid, uid); 4091dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk handler->start(); 4101dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4111dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk return 0; 4121dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk} 4131dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4142d4610ec34cc78799a3353638fa05ee53276892aMattias FalkDnsProxyListener::GetHostByAddrHandler::GetHostByAddrHandler(SocketClient* c, 4152d4610ec34cc78799a3353638fa05ee53276892aMattias Falk void* address, 4162d4610ec34cc78799a3353638fa05ee53276892aMattias Falk int addressLen, 4172d4610ec34cc78799a3353638fa05ee53276892aMattias Falk int addressFamily, 4182d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char* iface, 4193acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker pid_t pid, 4203acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker uid_t uid) 4212d4610ec34cc78799a3353638fa05ee53276892aMattias Falk : mClient(c), 4222d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mAddress(address), 4232d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mAddressLen(addressLen), 4242d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mAddressFamily(addressFamily), 4252d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mIface(iface), 4263acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker mPid(pid), 4273acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker mUid(uid) { 4282d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 4292d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 4301dbd6cf148ea3fab57ec0644c336e94c78a488beMattias FalkDnsProxyListener::GetHostByAddrHandler::~GetHostByAddrHandler() { 4311dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk free(mAddress); 4322d4610ec34cc78799a3353638fa05ee53276892aMattias Falk free(mIface); 4331dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk} 4341dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4351dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falkvoid DnsProxyListener::GetHostByAddrHandler::start() { 4360cdb680c7648b0f48e6513926cb0a06d290a5cbeJurijs Oniscuks pthread_t thread; 4370cdb680c7648b0f48e6513926cb0a06d290a5cbeJurijs Oniscuks pthread_create(&thread, NULL, 4381dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk DnsProxyListener::GetHostByAddrHandler::threadStart, this); 4392d4610ec34cc78799a3353638fa05ee53276892aMattias Falk pthread_detach(thread); 4401dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk} 4411dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4421dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falkvoid* DnsProxyListener::GetHostByAddrHandler::threadStart(void* obj) { 4431dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk GetHostByAddrHandler* handler = reinterpret_cast<GetHostByAddrHandler*>(obj); 4441dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk handler->run(); 4451dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk delete handler; 4461dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk pthread_exit(NULL); 4471dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk return NULL; 4481dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk} 4491dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4501dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falkvoid DnsProxyListener::GetHostByAddrHandler::run() { 4511dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk if (DBG) { 4527b984e3f7e724f8a3547a707210319f3d479f261Steve Block ALOGD("DnsProxyListener::GetHostByAddrHandler::run\n"); 4531dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk } 4541dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4552d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char tmp[IF_NAMESIZE + 1]; 4562d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (mIface == NULL) { 4573acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker //fall back to the per uid interface if no per pid interface exists 4583acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker if(!_resolv_get_pids_associated_interface(mPid, tmp, sizeof(tmp))) 4593acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker _resolv_get_uids_associated_interface(mUid, tmp, sizeof(tmp)); 4602d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 4611dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk struct hostent* hp; 4621dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4630475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom // NOTE gethostbyaddr should take a void* but bionic thinks it should be char* 4642d4610ec34cc78799a3353638fa05ee53276892aMattias Falk hp = android_gethostbyaddrforiface((char*)mAddress, mAddressLen, mAddressFamily, 4652d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mIface ? mIface : tmp); 4661dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4671dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk if (DBG) { 4687b984e3f7e724f8a3547a707210319f3d479f261Steve Block ALOGD("GetHostByAddrHandler::run gethostbyaddr errno: %s hp->h_name = %s, name_len = %d\n", 4691dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk hp ? "success" : strerror(errno), 4701dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk (hp && hp->h_name) ? hp->h_name: "null", 4711dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk (hp && hp->h_name) ? strlen(hp->h_name)+ 1 : 0); 4721dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk } 4731dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4742d4610ec34cc78799a3353638fa05ee53276892aMattias Falk bool success = true; 475ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun if (hp) { 4762d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0; 4772d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendhostent(mClient, hp); 478ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun } else { 4792d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, NULL, 0) == 0; 480ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun } 4811dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4822d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (!success) { 4830e76b761a1514d5182675dd7b7d33725f62d6bc5Steve Block ALOGW("GetHostByAddrHandler: Error writing DNS result to client\n"); 4841dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk } 48534ffd85aed3838d53bd1136c751a7825de1940e0Brad Fitzpatrick mClient->decRef(); 4861dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk} 487