DnsProxyListener.cpp revision cea2d3455eb7c0d9ad1430607cbe98cc09251c1f
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> 28a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak#include <resolv_netid.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 387dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen#include "Fwmark.h" 39007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#include "DnsProxyListener.h" 407dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen#include "NetdConstants.h" 417dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen#include "NetworkController.h" 42ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun#include "ResponseCode.h" 43007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 44f4f6c8de3f091be4b91a5a9d7f14e8882ec6d502Sreeram RamachandranDnsProxyListener::DnsProxyListener(const NetworkController* netCtrl) : 45f4f6c8de3f091be4b91a5a9d7f14e8882ec6d502Sreeram Ramachandran FrameworkListener("dnsproxyd"), mNetCtrl(netCtrl) { 467dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen registerCmd(new GetAddrInfoCmd(this)); 477dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen registerCmd(new GetHostByAddrCmd(this)); 487dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen registerCmd(new GetHostByNameCmd(this)); 497dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen} 507dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen 51cea2d3455eb7c0d9ad1430607cbe98cc09251c1fErik KlineDnsProxyListener::GetAddrInfoHandler::GetAddrInfoHandler( 52cea2d3455eb7c0d9ad1430607cbe98cc09251c1fErik Kline SocketClient *c, char* host, char* service, struct addrinfo* hints, 53cea2d3455eb7c0d9ad1430607cbe98cc09251c1fErik Kline const struct android_net_context& netcontext) 542d4610ec34cc78799a3353638fa05ee53276892aMattias Falk : mClient(c), 552d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mHost(host), 562d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mService(service), 572d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mHints(hints), 58cea2d3455eb7c0d9ad1430607cbe98cc09251c1fErik Kline mNetContext(netcontext) { 59007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 60007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 61007e987fee7e815e0c4bc820f434a632b7a69a9dBrad FitzpatrickDnsProxyListener::GetAddrInfoHandler::~GetAddrInfoHandler() { 62007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick free(mHost); 63007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick free(mService); 64007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick free(mHints); 65007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 66007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 67007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrickvoid DnsProxyListener::GetAddrInfoHandler::start() { 680cdb680c7648b0f48e6513926cb0a06d290a5cbeJurijs Oniscuks pthread_t thread; 690cdb680c7648b0f48e6513926cb0a06d290a5cbeJurijs Oniscuks pthread_create(&thread, NULL, 70007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick DnsProxyListener::GetAddrInfoHandler::threadStart, this); 712d4610ec34cc78799a3353638fa05ee53276892aMattias Falk pthread_detach(thread); 72007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 73007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 74007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrickvoid* DnsProxyListener::GetAddrInfoHandler::threadStart(void* obj) { 75007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick GetAddrInfoHandler* handler = reinterpret_cast<GetAddrInfoHandler*>(obj); 76007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick handler->run(); 77007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick delete handler; 78007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick pthread_exit(NULL); 79007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick return NULL; 80007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 81007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 82fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughesstatic bool sendBE32(SocketClient* c, uint32_t data) { 83fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes uint32_t be_data = htonl(data); 84fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes return c->sendData(&be_data, sizeof(be_data)) == 0; 85fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes} 86fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes 87007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick// Sends 4 bytes of big-endian length, followed by the data. 88007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick// Returns true on success. 89fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughesstatic bool sendLenAndData(SocketClient* c, const int len, const void* data) { 90fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes return sendBE32(c, len) && (len == 0 || c->sendData(data, len) == 0); 91007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 92007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 932d4610ec34cc78799a3353638fa05ee53276892aMattias Falk// Returns true on success 942d4610ec34cc78799a3353638fa05ee53276892aMattias Falkstatic bool sendhostent(SocketClient *c, struct hostent *hp) { 952d4610ec34cc78799a3353638fa05ee53276892aMattias Falk bool success = true; 962d4610ec34cc78799a3353638fa05ee53276892aMattias Falk int i; 972d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (hp->h_name != NULL) { 982d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendLenAndData(c, strlen(hp->h_name)+1, hp->h_name); 992d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } else { 1002d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendLenAndData(c, 0, "") == 0; 1012d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 1022d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 1032d4610ec34cc78799a3353638fa05ee53276892aMattias Falk for (i=0; hp->h_aliases[i] != NULL; i++) { 1042d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendLenAndData(c, strlen(hp->h_aliases[i])+1, hp->h_aliases[i]); 1052d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 1062d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendLenAndData(c, 0, ""); // null to indicate we're done 1072d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 1082d4610ec34cc78799a3353638fa05ee53276892aMattias Falk uint32_t buf = htonl(hp->h_addrtype); 1092d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= c->sendData(&buf, sizeof(buf)) == 0; 1102d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 1112d4610ec34cc78799a3353638fa05ee53276892aMattias Falk buf = htonl(hp->h_length); 1122d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= c->sendData(&buf, sizeof(buf)) == 0; 1132d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 1142d4610ec34cc78799a3353638fa05ee53276892aMattias Falk for (i=0; hp->h_addr_list[i] != NULL; i++) { 1152d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendLenAndData(c, 16, hp->h_addr_list[i]); 1162d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 1172d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendLenAndData(c, 0, ""); // null to indicate we're done 1182d4610ec34cc78799a3353638fa05ee53276892aMattias Falk return success; 1192d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 1202d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 121fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughesstatic bool sendaddrinfo(SocketClient* c, struct addrinfo* ai) { 122fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes // struct addrinfo { 123fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes // int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */ 124fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes // int ai_family; /* PF_xxx */ 125fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes // int ai_socktype; /* SOCK_xxx */ 126fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes // int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ 127fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes // socklen_t ai_addrlen; /* length of ai_addr */ 128fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes // char *ai_canonname; /* canonical name for hostname */ 129fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes // struct sockaddr *ai_addr; /* binary address */ 130fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes // struct addrinfo *ai_next; /* next structure in linked list */ 131fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes // }; 132fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes 133fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes // Write the struct piece by piece because we might be a 64-bit netd 134fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes // talking to a 32-bit process. 135fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes bool success = 136fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes sendBE32(c, ai->ai_flags) && 137fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes sendBE32(c, ai->ai_family) && 138fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes sendBE32(c, ai->ai_socktype) && 139fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes sendBE32(c, ai->ai_protocol); 140fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes if (!success) { 141fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes return false; 142fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes } 143fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes 144fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes // ai_addrlen and ai_addr. 145fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes if (!sendLenAndData(c, ai->ai_addrlen, ai->ai_addr)) { 146fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes return false; 147fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes } 148fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes 149fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes // strlen(ai_canonname) and ai_canonname. 150fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes if (!sendLenAndData(c, ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0, ai->ai_canonname)) { 151fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes return false; 152fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes } 153fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes 154fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes return true; 155fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes} 156fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes 157007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrickvoid DnsProxyListener::GetAddrInfoHandler::run() { 158007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (DBG) { 159cea2d3455eb7c0d9ad1430607cbe98cc09251c1fErik Kline ALOGD("GetAddrInfoHandler, now for %s / %s / {%u,%u,%u,%u,%u}", mHost, mService, 160cea2d3455eb7c0d9ad1430607cbe98cc09251c1fErik Kline mNetContext.app_netid, mNetContext.app_mark, 161cea2d3455eb7c0d9ad1430607cbe98cc09251c1fErik Kline mNetContext.dns_netid, mNetContext.dns_mark, 162cea2d3455eb7c0d9ad1430607cbe98cc09251c1fErik Kline mNetContext.uid); 163007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 164007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 165007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick struct addrinfo* result = NULL; 166cea2d3455eb7c0d9ad1430607cbe98cc09251c1fErik Kline uint32_t rv = android_getaddrinfofornetcontext(mHost, mService, mHints, &mNetContext, &result); 167ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun if (rv) { 168ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun // getaddrinfo failed 16940e0c13d6b77a9260b6da4c9e11cca8a5f994ea2Selim Gurun mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, &rv, sizeof(rv)); 170ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun } else { 171ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun bool success = !mClient->sendCode(ResponseCode::DnsProxyQueryResult); 172007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick struct addrinfo* ai = result; 173007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick while (ai && success) { 174fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes success = sendBE32(mClient, 1) && sendaddrinfo(mClient, ai); 175007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick ai = ai->ai_next; 176007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 177fe743018ad6ce7fb61db7f6f2efbe9832e9599dcElliott Hughes success = success && sendBE32(mClient, 0); 178ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun if (!success) { 179ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun ALOGW("Error writing DNS result to client"); 180ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun } 181007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 182007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (result) { 183007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick freeaddrinfo(result); 184007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 18534ffd85aed3838d53bd1136c751a7825de1940e0Brad Fitzpatrick mClient->decRef(); 186007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 187007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 1887dd69a1b0b95e67c8b939884476f2cf888026eb7Paul JensenDnsProxyListener::GetAddrInfoCmd::GetAddrInfoCmd(const DnsProxyListener* dnsProxyListener) : 189a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak NetdCommand("getaddrinfo"), 1907dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen mDnsProxyListener(dnsProxyListener) { 191007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 192007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 193007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrickint DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient *cli, 194007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick int argc, char **argv) { 1950475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom if (DBG) { 1960475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom for (int i = 0; i < argc; i++) { 1977b984e3f7e724f8a3547a707210319f3d479f261Steve Block ALOGD("argv[%i]=%s", i, argv[i]); 1980475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom } 1990475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom } 20052b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich if (argc != 8) { 201ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun char* msg = NULL; 202ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun asprintf( &msg, "Invalid number of arguments to getaddrinfo: %i", argc); 203ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun ALOGW("%s", msg); 204ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun cli->sendMsg(ResponseCode::CommandParameterError, msg, false); 205ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun free(msg); 2060475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom return -1; 207007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 208007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 209007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick char* name = argv[1]; 210007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (strcmp("^", name) == 0) { 211007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick name = NULL; 212007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } else { 213007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick name = strdup(name); 214007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 215007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 216007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick char* service = argv[2]; 217007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (strcmp("^", service) == 0) { 218007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick service = NULL; 219007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } else { 220007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick service = strdup(service); 221007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 222007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 223007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick struct addrinfo* hints = NULL; 224007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick int ai_flags = atoi(argv[3]); 225007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick int ai_family = atoi(argv[4]); 226007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick int ai_socktype = atoi(argv[5]); 227007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick int ai_protocol = atoi(argv[6]); 228a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak unsigned netId = strtoul(argv[7], NULL, 10); 2293acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker uid_t uid = cli->getUid(); 2302d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 231cea2d3455eb7c0d9ad1430607cbe98cc09251c1fErik Kline struct android_net_context netcontext; 232cea2d3455eb7c0d9ad1430607cbe98cc09251c1fErik Kline mDnsProxyListener->mNetCtrl->getNetworkContext(netId, uid, &netcontext); 233be1e7d8c0e0abb37262770e2455176413a4b0f7fPaul Jensen 234007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (ai_flags != -1 || ai_family != -1 || 235007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick ai_socktype != -1 || ai_protocol != -1) { 236007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick hints = (struct addrinfo*) calloc(1, sizeof(struct addrinfo)); 237007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick hints->ai_flags = ai_flags; 238007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick hints->ai_family = ai_family; 239007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick hints->ai_socktype = ai_socktype; 240007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick hints->ai_protocol = ai_protocol; 241a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak 242a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak // Only implement AI_ADDRCONFIG if application is using default network since our 243a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak // implementation only works on the default network. 2447dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen if ((hints->ai_flags & AI_ADDRCONFIG) && 245cea2d3455eb7c0d9ad1430607cbe98cc09251c1fErik Kline netcontext.dns_netid != mDnsProxyListener->mNetCtrl->getDefaultNetwork()) { 246a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak hints->ai_flags &= ~AI_ADDRCONFIG; 247a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak } 248007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 249007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 250007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (DBG) { 251cea2d3455eb7c0d9ad1430607cbe98cc09251c1fErik Kline ALOGD("GetAddrInfoHandler for %s / %s / {%u,%u,%u,%u,%u}", 252007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick name ? name : "[nullhost]", 2532d4610ec34cc78799a3353638fa05ee53276892aMattias Falk service ? service : "[nullservice]", 254cea2d3455eb7c0d9ad1430607cbe98cc09251c1fErik Kline netcontext.app_netid, netcontext.app_mark, 255cea2d3455eb7c0d9ad1430607cbe98cc09251c1fErik Kline netcontext.dns_netid, netcontext.dns_mark, 256cea2d3455eb7c0d9ad1430607cbe98cc09251c1fErik Kline netcontext.uid); 257007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 258007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 25934ffd85aed3838d53bd1136c751a7825de1940e0Brad Fitzpatrick cli->incRef(); 260007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick DnsProxyListener::GetAddrInfoHandler* handler = 261cea2d3455eb7c0d9ad1430607cbe98cc09251c1fErik Kline new DnsProxyListener::GetAddrInfoHandler(cli, name, service, hints, netcontext); 262007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick handler->start(); 263007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 264007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick return 0; 265007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 2661dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 2671dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk/******************************************************* 2682d4610ec34cc78799a3353638fa05ee53276892aMattias Falk * GetHostByName * 2692d4610ec34cc78799a3353638fa05ee53276892aMattias Falk *******************************************************/ 2707dd69a1b0b95e67c8b939884476f2cf888026eb7Paul JensenDnsProxyListener::GetHostByNameCmd::GetHostByNameCmd(const DnsProxyListener* dnsProxyListener) : 271a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak NetdCommand("gethostbyname"), 2727dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen mDnsProxyListener(dnsProxyListener) { 2732d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 2742d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 2752d4610ec34cc78799a3353638fa05ee53276892aMattias Falkint DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient *cli, 2762d4610ec34cc78799a3353638fa05ee53276892aMattias Falk int argc, char **argv) { 2772d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (DBG) { 2782d4610ec34cc78799a3353638fa05ee53276892aMattias Falk for (int i = 0; i < argc; i++) { 2792d4610ec34cc78799a3353638fa05ee53276892aMattias Falk ALOGD("argv[%i]=%s", i, argv[i]); 2802d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 2812d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 28252b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich if (argc != 4) { 2832d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char* msg = NULL; 2842d4610ec34cc78799a3353638fa05ee53276892aMattias Falk asprintf(&msg, "Invalid number of arguments to gethostbyname: %i", argc); 2852d4610ec34cc78799a3353638fa05ee53276892aMattias Falk ALOGW("%s", msg); 2862d4610ec34cc78799a3353638fa05ee53276892aMattias Falk cli->sendMsg(ResponseCode::CommandParameterError, msg, false); 2872d4610ec34cc78799a3353638fa05ee53276892aMattias Falk free(msg); 2882d4610ec34cc78799a3353638fa05ee53276892aMattias Falk return -1; 2892d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 2902d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 2913acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker uid_t uid = cli->getUid(); 292a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak unsigned netId = strtoul(argv[1], NULL, 10); 29352b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich char* name = argv[2]; 29452b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich int af = atoi(argv[3]); 2952d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 2962d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (strcmp(name, "^") == 0) { 2972d4610ec34cc78799a3353638fa05ee53276892aMattias Falk name = NULL; 2982d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } else { 2992d4610ec34cc78799a3353638fa05ee53276892aMattias Falk name = strdup(name); 3002d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 3012d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3021011b4941d96d9fd90bc7243be387b63ec775936Sreeram Ramachandran uint32_t mark = mDnsProxyListener->mNetCtrl->getNetworkForDns(&netId, uid); 303a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak 3042d4610ec34cc78799a3353638fa05ee53276892aMattias Falk cli->incRef(); 3052d4610ec34cc78799a3353638fa05ee53276892aMattias Falk DnsProxyListener::GetHostByNameHandler* handler = 3067dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen new DnsProxyListener::GetHostByNameHandler(cli, name, af, netId, mark); 3072d4610ec34cc78799a3353638fa05ee53276892aMattias Falk handler->start(); 3082d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3092d4610ec34cc78799a3353638fa05ee53276892aMattias Falk return 0; 3102d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 3112d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3122d4610ec34cc78799a3353638fa05ee53276892aMattias FalkDnsProxyListener::GetHostByNameHandler::GetHostByNameHandler(SocketClient* c, 3132d4610ec34cc78799a3353638fa05ee53276892aMattias Falk char* name, 314d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker int af, 3157dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen unsigned netId, 3167dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen uint32_t mark) 3172d4610ec34cc78799a3353638fa05ee53276892aMattias Falk : mClient(c), 3182d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mName(name), 319d2617936acc15567fc5111bbdb4dde20845c3cbaChad Brubaker mAf(af), 3207dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen mNetId(netId), 3217dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen mMark(mark) { 3222d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 3232d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3242d4610ec34cc78799a3353638fa05ee53276892aMattias FalkDnsProxyListener::GetHostByNameHandler::~GetHostByNameHandler() { 3252d4610ec34cc78799a3353638fa05ee53276892aMattias Falk free(mName); 3262d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 3272d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3282d4610ec34cc78799a3353638fa05ee53276892aMattias Falkvoid DnsProxyListener::GetHostByNameHandler::start() { 3292d4610ec34cc78799a3353638fa05ee53276892aMattias Falk pthread_t thread; 3302d4610ec34cc78799a3353638fa05ee53276892aMattias Falk pthread_create(&thread, NULL, 3312d4610ec34cc78799a3353638fa05ee53276892aMattias Falk DnsProxyListener::GetHostByNameHandler::threadStart, this); 3322d4610ec34cc78799a3353638fa05ee53276892aMattias Falk pthread_detach(thread); 3332d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 3342d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3352d4610ec34cc78799a3353638fa05ee53276892aMattias Falkvoid* DnsProxyListener::GetHostByNameHandler::threadStart(void* obj) { 3362d4610ec34cc78799a3353638fa05ee53276892aMattias Falk GetHostByNameHandler* handler = reinterpret_cast<GetHostByNameHandler*>(obj); 3372d4610ec34cc78799a3353638fa05ee53276892aMattias Falk handler->run(); 3382d4610ec34cc78799a3353638fa05ee53276892aMattias Falk delete handler; 3392d4610ec34cc78799a3353638fa05ee53276892aMattias Falk pthread_exit(NULL); 3402d4610ec34cc78799a3353638fa05ee53276892aMattias Falk return NULL; 3412d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 3422d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3432d4610ec34cc78799a3353638fa05ee53276892aMattias Falkvoid DnsProxyListener::GetHostByNameHandler::run() { 3442d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (DBG) { 3452d4610ec34cc78799a3353638fa05ee53276892aMattias Falk ALOGD("DnsProxyListener::GetHostByNameHandler::run\n"); 3462d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 3472d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3482d4610ec34cc78799a3353638fa05ee53276892aMattias Falk struct hostent* hp; 3492d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3507dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen hp = android_gethostbynamefornet(mName, mAf, mNetId, mMark); 3512d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3522d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (DBG) { 3532a54d96c5ae809216965e6f86e70cdae2ed7e09cMatthew Leach ALOGD("GetHostByNameHandler::run gethostbyname errno: %s hp->h_name = %s, name_len = %zu\n", 3542d4610ec34cc78799a3353638fa05ee53276892aMattias Falk hp ? "success" : strerror(errno), 3552a54d96c5ae809216965e6f86e70cdae2ed7e09cMatthew Leach (hp && hp->h_name) ? hp->h_name : "null", 3562a54d96c5ae809216965e6f86e70cdae2ed7e09cMatthew Leach (hp && hp->h_name) ? strlen(hp->h_name) + 1 : 0); 3572d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 3582d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3592d4610ec34cc78799a3353638fa05ee53276892aMattias Falk bool success = true; 3602d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (hp) { 3612d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0; 3622d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendhostent(mClient, hp); 3632d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } else { 3642d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, NULL, 0) == 0; 3652d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 3662d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3672d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (!success) { 3682d4610ec34cc78799a3353638fa05ee53276892aMattias Falk ALOGW("GetHostByNameHandler: Error writing DNS result to client\n"); 3692d4610ec34cc78799a3353638fa05ee53276892aMattias Falk } 3702d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mClient->decRef(); 3712d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 3722d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3732d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 3742d4610ec34cc78799a3353638fa05ee53276892aMattias Falk/******************************************************* 3752d4610ec34cc78799a3353638fa05ee53276892aMattias Falk * GetHostByAddr * 3761dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk *******************************************************/ 3777dd69a1b0b95e67c8b939884476f2cf888026eb7Paul JensenDnsProxyListener::GetHostByAddrCmd::GetHostByAddrCmd(const DnsProxyListener* dnsProxyListener) : 378a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak NetdCommand("gethostbyaddr"), 3797dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen mDnsProxyListener(dnsProxyListener) { 3801dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk} 3811dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 3821dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falkint DnsProxyListener::GetHostByAddrCmd::runCommand(SocketClient *cli, 3831dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk int argc, char **argv) { 3840475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom if (DBG) { 3850475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom for (int i = 0; i < argc; i++) { 3867b984e3f7e724f8a3547a707210319f3d479f261Steve Block ALOGD("argv[%i]=%s", i, argv[i]); 3870475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom } 3880475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom } 38952b17bcfdf63a9d00f3ab1bc6ff738cbc4d30b0bNick Kralevich if (argc != 5) { 390ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun char* msg = NULL; 391ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun asprintf(&msg, "Invalid number of arguments to gethostbyaddr: %i", argc); 392ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun ALOGW("%s", msg); 393ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun cli->sendMsg(ResponseCode::CommandParameterError, msg, false); 394ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun free(msg); 3950475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom return -1; 3961dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk } 3971dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 3980475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom char* addrStr = argv[1]; 3991dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk int addrLen = atoi(argv[2]); 4001dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk int addrFamily = atoi(argv[3]); 4013acdb064d8d5a86b1973fcda1e8dd83e0e12e0b3Chad Brubaker uid_t uid = cli->getUid(); 402a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak unsigned netId = strtoul(argv[4], NULL, 10); 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 4171011b4941d96d9fd90bc7243be387b63ec775936Sreeram Ramachandran uint32_t mark = mDnsProxyListener->mNetCtrl->getNetworkForDns(&netId, uid); 418a0efaece8c05370f201efe099a537ceb014c6fdfSzymon Jakubczak 41934ffd85aed3838d53bd1136c751a7825de1940e0Brad Fitzpatrick cli->incRef(); 4201dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk DnsProxyListener::GetHostByAddrHandler* handler = 4217dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen new DnsProxyListener::GetHostByAddrHandler(cli, addr, addrLen, addrFamily, netId, mark); 4221dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk handler->start(); 4231dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4241dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk return 0; 4251dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk} 4261dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4272d4610ec34cc78799a3353638fa05ee53276892aMattias FalkDnsProxyListener::GetHostByAddrHandler::GetHostByAddrHandler(SocketClient* c, 4282d4610ec34cc78799a3353638fa05ee53276892aMattias Falk void* address, 4292d4610ec34cc78799a3353638fa05ee53276892aMattias Falk int addressLen, 4302d4610ec34cc78799a3353638fa05ee53276892aMattias Falk int addressFamily, 4317dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen unsigned netId, 4327dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen uint32_t mark) 4332d4610ec34cc78799a3353638fa05ee53276892aMattias Falk : mClient(c), 4342d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mAddress(address), 4352d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mAddressLen(addressLen), 4362d4610ec34cc78799a3353638fa05ee53276892aMattias Falk mAddressFamily(addressFamily), 4377dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen mNetId(netId), 4387dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen mMark(mark) { 4392d4610ec34cc78799a3353638fa05ee53276892aMattias Falk} 4402d4610ec34cc78799a3353638fa05ee53276892aMattias Falk 4411dbd6cf148ea3fab57ec0644c336e94c78a488beMattias FalkDnsProxyListener::GetHostByAddrHandler::~GetHostByAddrHandler() { 4421dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk free(mAddress); 4431dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk} 4441dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4451dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falkvoid DnsProxyListener::GetHostByAddrHandler::start() { 4460cdb680c7648b0f48e6513926cb0a06d290a5cbeJurijs Oniscuks pthread_t thread; 4470cdb680c7648b0f48e6513926cb0a06d290a5cbeJurijs Oniscuks pthread_create(&thread, NULL, 4481dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk DnsProxyListener::GetHostByAddrHandler::threadStart, this); 4492d4610ec34cc78799a3353638fa05ee53276892aMattias Falk pthread_detach(thread); 4501dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk} 4511dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4521dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falkvoid* DnsProxyListener::GetHostByAddrHandler::threadStart(void* obj) { 4531dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk GetHostByAddrHandler* handler = reinterpret_cast<GetHostByAddrHandler*>(obj); 4541dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk handler->run(); 4551dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk delete handler; 4561dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk pthread_exit(NULL); 4571dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk return NULL; 4581dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk} 4591dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4601dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falkvoid DnsProxyListener::GetHostByAddrHandler::run() { 4611dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk if (DBG) { 4627b984e3f7e724f8a3547a707210319f3d479f261Steve Block ALOGD("DnsProxyListener::GetHostByAddrHandler::run\n"); 4631dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk } 4641dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk struct hostent* hp; 4651dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4660475ae98cd8f45de815d67d1966edaf5997be9a9Brian Carlstrom // NOTE gethostbyaddr should take a void* but bionic thinks it should be char* 4677dd69a1b0b95e67c8b939884476f2cf888026eb7Paul Jensen hp = android_gethostbyaddrfornet((char*)mAddress, mAddressLen, mAddressFamily, mNetId, mMark); 4681dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4691dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk if (DBG) { 4702a54d96c5ae809216965e6f86e70cdae2ed7e09cMatthew Leach ALOGD("GetHostByAddrHandler::run gethostbyaddr errno: %s hp->h_name = %s, name_len = %zu\n", 4711dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk hp ? "success" : strerror(errno), 4722a54d96c5ae809216965e6f86e70cdae2ed7e09cMatthew Leach (hp && hp->h_name) ? hp->h_name : "null", 4732a54d96c5ae809216965e6f86e70cdae2ed7e09cMatthew Leach (hp && hp->h_name) ? strlen(hp->h_name) + 1 : 0); 4741dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk } 4751dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4762d4610ec34cc78799a3353638fa05ee53276892aMattias Falk bool success = true; 477ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun if (hp) { 4782d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0; 4792d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success &= sendhostent(mClient, hp); 480ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun } else { 4812d4610ec34cc78799a3353638fa05ee53276892aMattias Falk success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, NULL, 0) == 0; 482ddb34755fb54882b3ece8d4919593e26a2c1cfcbSelim Gurun } 4831dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk 4842d4610ec34cc78799a3353638fa05ee53276892aMattias Falk if (!success) { 4850e76b761a1514d5182675dd7b7d33725f62d6bc5Steve Block ALOGW("GetHostByAddrHandler: Error writing DNS result to client\n"); 4861dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk } 48734ffd85aed3838d53bd1136c751a7825de1940e0Brad Fitzpatrick mClient->decRef(); 4881dbd6cf148ea3fab57ec0644c336e94c78a488beMattias Falk} 489