Home | History | Annotate | Download | only in dns_responder
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "dns_responder_client.h"
     18 
     19 #include <android-base/stringprintf.h>
     20 
     21 // TODO: make this dynamic and stop depending on implementation details.
     22 #define TEST_OEM_NETWORK "oem29"
     23 #define TEST_NETID 30
     24 
     25 // TODO: move this somewhere shared.
     26 static const char* ANDROID_DNS_MODE = "ANDROID_DNS_MODE";
     27 
     28 // The only response code used in this class. See
     29 // frameworks/base/services/java/com/android/server/NetworkManagementService.java
     30 // for others.
     31 static constexpr int ResponseCodeOK = 200;
     32 
     33 using android::base::StringPrintf;
     34 
     35 static int netdCommand(const char* sockname, const char* command) {
     36     int sock = socket_local_client(sockname,
     37                                    ANDROID_SOCKET_NAMESPACE_RESERVED,
     38                                    SOCK_STREAM);
     39     if (sock < 0) {
     40         perror("Error connecting");
     41         return -1;
     42     }
     43 
     44     // FrameworkListener expects the whole command in one read.
     45     char buffer[256];
     46     int nwritten = snprintf(buffer, sizeof(buffer), "0 %s", command);
     47     if (write(sock, buffer, nwritten + 1) < 0) {
     48         perror("Error sending netd command");
     49         close(sock);
     50         return -1;
     51     }
     52 
     53     int nread = read(sock, buffer, sizeof(buffer));
     54     if (nread < 0) {
     55         perror("Error reading response");
     56         close(sock);
     57         return -1;
     58     }
     59     close(sock);
     60     return atoi(buffer);
     61 }
     62 
     63 static bool expectNetdResult(int expected, const char* sockname, const char* format, ...) {
     64     char command[256];
     65     va_list args;
     66     va_start(args, format);
     67     vsnprintf(command, sizeof(command), format, args);
     68     va_end(args);
     69     int result = netdCommand(sockname, command);
     70     if (expected != result) {
     71         return false;
     72     }
     73     return (200 <= expected && expected < 300);
     74 }
     75 
     76 void DnsResponderClient::SetupMappings(unsigned num_hosts, const std::vector<std::string>& domains,
     77         std::vector<Mapping>* mappings) {
     78     mappings->resize(num_hosts * domains.size());
     79     auto mappings_it = mappings->begin();
     80     for (unsigned i = 0 ; i < num_hosts ; ++i) {
     81         for (const auto& domain : domains) {
     82             mappings_it->host = StringPrintf("host%u", i);
     83             mappings_it->entry = StringPrintf("%s.%s.", mappings_it->host.c_str(),
     84                     domain.c_str());
     85             mappings_it->ip4 = StringPrintf("192.0.2.%u", i%253 + 1);
     86             mappings_it->ip6 = StringPrintf("2001:db8::%x", i%65534 + 1);
     87             ++mappings_it;
     88         }
     89     }
     90 }
     91 
     92 bool DnsResponderClient::SetResolversForNetwork(const std::vector<std::string>& servers,
     93         const std::vector<std::string>& domains, const std::vector<int>& params) {
     94     auto rv = mNetdSrv->setResolverConfiguration(TEST_NETID, servers, domains, params);
     95     return rv.isOk();
     96 }
     97 
     98 bool DnsResponderClient::SetResolversForNetwork(const std::vector<std::string>& searchDomains,
     99             const std::vector<std::string>& servers, const std::string& params) {
    100     std::string cmd = StringPrintf("resolver setnetdns %d \"", mOemNetId);
    101     if (!searchDomains.empty()) {
    102         cmd += searchDomains[0].c_str();
    103         for (size_t i = 1 ; i < searchDomains.size() ; ++i) {
    104             cmd += " ";
    105             cmd += searchDomains[i];
    106         }
    107     }
    108     cmd += "\"";
    109 
    110     for (const auto& str : servers) {
    111         cmd += " ";
    112         cmd += str;
    113     }
    114 
    115     if (!params.empty()) {
    116         cmd += " --params \"";
    117         cmd += params;
    118         cmd += "\"";
    119     }
    120 
    121     int rv = netdCommand("netd", cmd.c_str());
    122     if (rv != ResponseCodeOK) {
    123         return false;
    124     }
    125     return true;
    126 }
    127 
    128 void DnsResponderClient::SetupDNSServers(unsigned num_servers, const std::vector<Mapping>& mappings,
    129         std::vector<std::unique_ptr<test::DNSResponder>>* dns,
    130         std::vector<std::string>* servers) {
    131     const char* listen_srv = "53";
    132     dns->resize(num_servers);
    133     servers->resize(num_servers);
    134     for (unsigned i = 0 ; i < num_servers ; ++i) {
    135         auto& server = (*servers)[i];
    136         auto& d = (*dns)[i];
    137         server = StringPrintf("127.0.0.%u", i + 100);
    138         d = std::make_unique<test::DNSResponder>(server, listen_srv, 250,
    139                 ns_rcode::ns_r_servfail, 1.0);
    140         for (const auto& mapping : mappings) {
    141             d->addMapping(mapping.entry.c_str(), ns_type::ns_t_a, mapping.ip4.c_str());
    142             d->addMapping(mapping.entry.c_str(), ns_type::ns_t_aaaa, mapping.ip6.c_str());
    143         }
    144         d->startServer();
    145     }
    146 }
    147 
    148 void DnsResponderClient::ShutdownDNSServers(std::vector<std::unique_ptr<test::DNSResponder>>* dns) {
    149     for (const auto& d : *dns) {
    150         d->stopServer();
    151     }
    152     dns->clear();
    153 }
    154 
    155 int DnsResponderClient::SetupOemNetwork() {
    156     netdCommand("netd", "network destroy " TEST_OEM_NETWORK);
    157     if (!expectNetdResult(ResponseCodeOK, "netd",
    158                          "network create %s", TEST_OEM_NETWORK)) {
    159         return -1;
    160     }
    161     int oemNetId = TEST_NETID;
    162     setNetworkForProcess(oemNetId);
    163     if ((unsigned) oemNetId != getNetworkForProcess()) {
    164         return -1;
    165     }
    166     return oemNetId;
    167 }
    168 
    169 void DnsResponderClient::TearDownOemNetwork(int oemNetId) {
    170     if (oemNetId != -1) {
    171         expectNetdResult(ResponseCodeOK, "netd",
    172                          "network destroy %s", TEST_OEM_NETWORK);
    173     }
    174 }
    175 
    176 void DnsResponderClient::SetUp() {
    177     // Ensure resolutions go via proxy.
    178     setenv(ANDROID_DNS_MODE, "", 1);
    179     mOemNetId = SetupOemNetwork();
    180 
    181     // binder setup
    182     auto binder = android::defaultServiceManager()->getService(android::String16("netd"));
    183     mNetdSrv = android::interface_cast<android::net::INetd>(binder);
    184 }
    185 
    186 void DnsResponderClient::TearDown() {
    187     TearDownOemNetwork(mOemNetId);
    188 }
    189