• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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