DnsProxyListener.cpp revision ff2c0d8c13457e43f0d4bf06d3177271aac104c1
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> 27007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 28007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#define LOG_TAG "DnsProxyListener" 29007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#define DBG 0 30007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 31007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#include <cutils/log.h> 32007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#include <sysutils/SocketClient.h> 33007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 34007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick#include "DnsProxyListener.h" 35007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 36007e987fee7e815e0c4bc820f434a632b7a69a9dBrad FitzpatrickDnsProxyListener::DnsProxyListener() : 37007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick FrameworkListener("dnsproxyd") { 38007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick registerCmd(new GetAddrInfoCmd()); 39007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 40007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 41007e987fee7e815e0c4bc820f434a632b7a69a9dBrad FitzpatrickDnsProxyListener::GetAddrInfoHandler::~GetAddrInfoHandler() { 42007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick free(mHost); 43007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick free(mService); 44007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick free(mHints); 45007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 46007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 47007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrickvoid DnsProxyListener::GetAddrInfoHandler::start() { 48007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick pthread_create(&mThread, NULL, 49007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick DnsProxyListener::GetAddrInfoHandler::threadStart, this); 50007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 51007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 52007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrickvoid* DnsProxyListener::GetAddrInfoHandler::threadStart(void* obj) { 53007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick GetAddrInfoHandler* handler = reinterpret_cast<GetAddrInfoHandler*>(obj); 54007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick handler->run(); 55007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick delete handler; 56007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick pthread_exit(NULL); 57007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick return NULL; 58007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 59007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 60007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick// Sends 4 bytes of big-endian length, followed by the data. 61007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick// Returns true on success. 62007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrickstatic bool sendLenAndData(SocketClient *c, const int len, const void* data) { 63007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick uint32_t len_be = htonl(len); 64e6a3a58d6aa4b551e38e1e19fdfea2c0d2841b85Brad Fitzpatrick return c->sendData(&len_be, 4) == 0 && 65e6a3a58d6aa4b551e38e1e19fdfea2c0d2841b85Brad Fitzpatrick (len == 0 || c->sendData(data, len) == 0); 66007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 67007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 68007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrickvoid DnsProxyListener::GetAddrInfoHandler::run() { 69007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (DBG) { 70007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick LOGD("GetAddrInfoHandler, now for %s / %s", mHost, mService); 71007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 72007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 73007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick struct addrinfo* result = NULL; 74007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick int rv = getaddrinfo(mHost, mService, mHints, &result); 756c798fbf4e89c4058f046a65ee4f9aa5647e43e1Brad Fitzpatrick bool success = (mClient->sendData(&rv, sizeof(rv)) == 0); 76007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (rv == 0) { 77007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick struct addrinfo* ai = result; 78007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick while (ai && success) { 79007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick success = sendLenAndData(mClient, sizeof(struct addrinfo), ai) 80007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick && sendLenAndData(mClient, ai->ai_addrlen, ai->ai_addr) 81007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick && sendLenAndData(mClient, 82007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0, 83007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick ai->ai_canonname); 84007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick ai = ai->ai_next; 85007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 86007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick success = success && sendLenAndData(mClient, 0, ""); 87007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 88007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (result) { 89007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick freeaddrinfo(result); 90007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 91007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (!success) { 92007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick LOGW("Error writing DNS result to client"); 93007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 94007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 95007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 96007e987fee7e815e0c4bc820f434a632b7a69a9dBrad FitzpatrickDnsProxyListener::GetAddrInfoCmd::GetAddrInfoCmd() : 97007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick NetdCommand("getaddrinfo") { 98007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 99007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 100007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrickint DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient *cli, 101007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick int argc, char **argv) { 102007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (argc != 7) { 103007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick LOGW("Invalid number of arguments to getaddrinfo"); 104007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick return 0; 105007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 106007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 107007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick char* name = argv[1]; 108007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (strcmp("^", name) == 0) { 109007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick name = NULL; 110007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } else { 111007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick name = strdup(name); 112007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 113007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 114007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick char* service = argv[2]; 115007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (strcmp("^", service) == 0) { 116007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick service = NULL; 117007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } else { 118007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick service = strdup(service); 119007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 120007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 121007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick struct addrinfo* hints = NULL; 122007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick int ai_flags = atoi(argv[3]); 123007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick int ai_family = atoi(argv[4]); 124007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick int ai_socktype = atoi(argv[5]); 125007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick int ai_protocol = atoi(argv[6]); 126007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (ai_flags != -1 || ai_family != -1 || 127007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick ai_socktype != -1 || ai_protocol != -1) { 128007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick hints = (struct addrinfo*) calloc(1, sizeof(struct addrinfo)); 129007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick hints->ai_flags = ai_flags; 130007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick hints->ai_family = ai_family; 131007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick hints->ai_socktype = ai_socktype; 132007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick hints->ai_protocol = ai_protocol; 133007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 134007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 135007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick if (DBG) { 136007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick LOGD("GetAddrInfoHandler for %s / %s", 137007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick name ? name : "[nullhost]", 138007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick service ? service : "[nullservice]"); 139007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick } 140007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 141007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick DnsProxyListener::GetAddrInfoHandler* handler = 142007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick new DnsProxyListener::GetAddrInfoHandler(cli, name, service, hints); 143007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick handler->start(); 144007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 145007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick 146007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick return 0; 147007e987fee7e815e0c4bc820f434a632b7a69a9dBrad Fitzpatrick} 148