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
netdCommand(const char * sockname,const char * command)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
expectNetdResult(int expected,const char * sockname,const char * format,...)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
SetupMappings(unsigned num_hosts,const std::vector<std::string> & domains,std::vector<Mapping> * mappings)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
SetResolversForNetwork(const std::vector<std::string> & servers,const std::vector<std::string> & domains,const std::vector<int> & params)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
SetResolversForNetwork(const std::vector<std::string> & searchDomains,const std::vector<std::string> & servers,const std::string & params)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
SetupDNSServers(unsigned num_servers,const std::vector<Mapping> & mappings,std::vector<std::unique_ptr<test::DNSResponder>> * dns,std::vector<std::string> * servers)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
ShutdownDNSServers(std::vector<std::unique_ptr<test::DNSResponder>> * dns)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
SetupOemNetwork()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
TearDownOemNetwork(int oemNetId)169 void DnsResponderClient::TearDownOemNetwork(int oemNetId) {
170 if (oemNetId != -1) {
171 expectNetdResult(ResponseCodeOK, "netd",
172 "network destroy %s", TEST_OEM_NETWORK);
173 }
174 }
175
SetUp()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
TearDown()186 void DnsResponderClient::TearDown() {
187 TearDownOemNetwork(mOemNetId);
188 }
189