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