DnsProxyListener.cpp revision 4e248e5a7a542067fd3f0467680eef2f92b1e195
14e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick/* 24e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick * Copyright (C) 2010 The Android Open Source Project 34e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick * 44e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick * Licensed under the Apache License, Version 2.0 (the "License"); 54e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick * you may not use this file except in compliance with the License. 64e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick * You may obtain a copy of the License at 74e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick * 84e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick * http://www.apache.org/licenses/LICENSE-2.0 94e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick * 104e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick * Unless required by applicable law or agreed to in writing, software 114e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick * distributed under the License is distributed on an "AS IS" BASIS, 124e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick * See the License for the specific language governing permissions and 144e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick * limitations under the License. 154e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick */ 164e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick 174e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick#include <arpa/inet.h> 184e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick#include <dirent.h> 194e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick#include <errno.h> 204e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick#include <linux/if.h> 214e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick#include <netdb.h> 224e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick#include <netinet/in.h> 234e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick#include <stdlib.h> 244e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick#include <sys/socket.h> 254e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick#include <sys/types.h> 264e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick 274e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick#define LOG_TAG "DnsProxyListener" 284e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick#define DBG 0 294e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick 304e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick#include <cutils/log.h> 314e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick#include <sysutils/SocketClient.h> 324e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick 334e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick#include "DnsProxyListener.h" 344e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick 354e248e5a7a542067fd3f0467680eef2f92b1e195Brad FitzpatrickDnsProxyListener::DnsProxyListener() : 364e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick FrameworkListener("dnsproxyd") { 374e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick registerCmd(new GetAddrInfoCmd()); 384e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick} 394e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick 404e248e5a7a542067fd3f0467680eef2f92b1e195Brad FitzpatrickDnsProxyListener::GetAddrInfoHandler::~GetAddrInfoHandler() { 414e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick free(mHost); 424e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick free(mService); 434e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick free(mHints); 444e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick} 454e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick 464e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrickvoid DnsProxyListener::GetAddrInfoHandler::start() { 474e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick pthread_create(&mThread, NULL, 484e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick DnsProxyListener::GetAddrInfoHandler::threadStart, this); 494e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick} 504e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick 514e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrickvoid* DnsProxyListener::GetAddrInfoHandler::threadStart(void* obj) { 524e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick GetAddrInfoHandler* handler = reinterpret_cast<GetAddrInfoHandler*>(obj); 534e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick handler->run(); 544e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick delete handler; 554e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick pthread_exit(NULL); 564e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick return NULL; 574e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick} 584e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick 594e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick// Sends 4 bytes of big-endian length, followed by the data. 604e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick// Returns true on success. 614e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrickstatic bool sendLenAndData(SocketClient *c, const int len, const void* data) { 624e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick uint32_t len_be = htonl(len); 634e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick return c->sendData(&len_be, 4) == 0 && c->sendData(data, len) == 0; 644e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick} 654e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick 664e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrickvoid DnsProxyListener::GetAddrInfoHandler::run() { 674e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick if (DBG) { 684e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick LOGD("GetAddrInfoHandler, now for %s / %s", mHost, mService); 694e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick } 704e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick 714e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick struct addrinfo* result = NULL; 724e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick int rv = getaddrinfo(mHost, mService, mHints, &result); 734e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick bool success = mClient->sendData(&rv, sizeof(rv)); 744e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick if (rv == 0) { 754e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick struct addrinfo* ai = result; 764e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick while (ai && success) { 774e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick success = sendLenAndData(mClient, sizeof(struct addrinfo), ai) 784e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick && sendLenAndData(mClient, ai->ai_addrlen, ai->ai_addr) 794e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick && sendLenAndData(mClient, 804e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0, 814e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick ai->ai_canonname); 824e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick ai = ai->ai_next; 834e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick } 844e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick success = success && sendLenAndData(mClient, 0, ""); 854e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick } 864e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick if (result) { 874e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick freeaddrinfo(result); 884e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick } 894e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick if (!success) { 904e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick LOGW("Error writing DNS result to client"); 914e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick } 924e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick} 934e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick 944e248e5a7a542067fd3f0467680eef2f92b1e195Brad FitzpatrickDnsProxyListener::GetAddrInfoCmd::GetAddrInfoCmd() : 954e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick NetdCommand("getaddrinfo") { 964e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick} 974e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick 984e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrickint DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient *cli, 994e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick int argc, char **argv) { 1004e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick if (argc != 7) { 1014e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick LOGW("Invalid number of arguments to getaddrinfo"); 1024e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick return 0; 1034e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick } 1044e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick 1054e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick char* name = argv[1]; 1064e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick if (strcmp("^", name) == 0) { 1074e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick name = NULL; 1084e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick } else { 1094e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick name = strdup(name); 1104e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick } 1114e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick 1124e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick char* service = argv[2]; 1134e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick if (strcmp("^", service) == 0) { 1144e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick service = NULL; 1154e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick } else { 1164e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick service = strdup(service); 1174e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick } 1184e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick 1194e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick struct addrinfo* hints = NULL; 1204e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick int ai_flags = atoi(argv[3]); 1214e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick int ai_family = atoi(argv[4]); 1224e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick int ai_socktype = atoi(argv[5]); 1234e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick int ai_protocol = atoi(argv[6]); 1244e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick if (ai_flags != -1 || ai_family != -1 || 1254e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick ai_socktype != -1 || ai_protocol != -1) { 1264e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick hints = (struct addrinfo*) calloc(1, sizeof(struct addrinfo)); 1274e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick hints->ai_flags = ai_flags; 1284e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick hints->ai_family = ai_family; 1294e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick hints->ai_socktype = ai_socktype; 1304e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick hints->ai_protocol = ai_protocol; 1314e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick } 1324e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick 1334e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick if (DBG) { 1344e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick LOGD("GetAddrInfoHandler for %s / %s", 1354e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick name ? name : "[nullhost]", 1364e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick service ? service : "[nullservice]"); 1374e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick } 1384e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick 1394e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick DnsProxyListener::GetAddrInfoHandler* handler = 1404e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick new DnsProxyListener::GetAddrInfoHandler(cli, name, service, hints); 1414e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick handler->start(); 1424e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick 1434e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick 1444e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick return 0; 1454e248e5a7a542067fd3f0467680eef2f92b1e195Brad Fitzpatrick} 146