1 /* 2 * Copyright (C) 2019 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 #define LOG_TAG "dns_responder_client" 18 19 #include "dns_responder_client_ndk.h" 20 21 #include <android/binder_manager.h> 22 #include "NetdClient.h" 23 24 // TODO: make this dynamic and stop depending on implementation details. 25 #define TEST_OEM_NETWORK "oem29" 26 #define TEST_NETID 30 27 28 // TODO: move this somewhere shared. 29 static const char* ANDROID_DNS_MODE = "ANDROID_DNS_MODE"; 30 31 using aidl::android::net::IDnsResolver; 32 using aidl::android::net::INetd; 33 using aidl::android::net::ResolverOptionsParcel; 34 using aidl::android::net::ResolverParamsParcel; 35 using android::net::ResolverStats; 36 37 void DnsResponderClient::SetupMappings(unsigned numHosts, const std::vector<std::string>& domains, 38 std::vector<Mapping>* mappings) { 39 mappings->resize(numHosts * domains.size()); 40 auto mappingsIt = mappings->begin(); 41 for (unsigned i = 0; i < numHosts; ++i) { 42 for (const auto& domain : domains) { 43 mappingsIt->host = StringPrintf("host%u", i); 44 mappingsIt->entry = StringPrintf("%s.%s.", mappingsIt->host.c_str(), domain.c_str()); 45 mappingsIt->ip4 = StringPrintf("192.0.2.%u", i % 253 + 1); 46 mappingsIt->ip6 = StringPrintf("2001:db8::%x", i % 65534 + 1); 47 ++mappingsIt; 48 } 49 } 50 } 51 52 // TODO: Use SetResolverConfiguration() with ResolverParamsParcel struct directly. 53 // DEPRECATED: Use SetResolverConfiguration() in new code 54 ResolverParamsParcel DnsResponderClient::makeResolverParamsParcel( 55 int netId, const std::vector<int>& params, const std::vector<std::string>& servers, 56 const std::vector<std::string>& domains, const std::string& tlsHostname, 57 const std::vector<std::string>& tlsServers, const std::string& caCert) { 58 ResolverParamsParcel paramsParcel; 59 60 paramsParcel.netId = netId; 61 paramsParcel.sampleValiditySeconds = params[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY]; 62 paramsParcel.successThreshold = params[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD]; 63 paramsParcel.minSamples = params[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES]; 64 paramsParcel.maxSamples = params[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES]; 65 if (params.size() > IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC) { 66 paramsParcel.baseTimeoutMsec = params[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC]; 67 } else { 68 paramsParcel.baseTimeoutMsec = 0; 69 } 70 if (params.size() > IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT) { 71 paramsParcel.retryCount = params[IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT]; 72 } else { 73 paramsParcel.retryCount = 0; 74 } 75 paramsParcel.servers = servers; 76 paramsParcel.domains = domains; 77 paramsParcel.tlsName = tlsHostname; 78 paramsParcel.tlsServers = tlsServers; 79 paramsParcel.tlsFingerprints = {}; 80 paramsParcel.caCertificate = caCert; 81 paramsParcel.resolverOptions = ResolverOptionsParcel{}; // optional, must be explicitly set. 82 83 // Note, do not remove this otherwise the ResolverTest#ConnectTlsServerTimeout won't pass in M4 84 // module. 85 // TODO: remove after 2020-01 rolls out. 86 paramsParcel.tlsConnectTimeoutMs = 1000; 87 88 return paramsParcel; 89 } 90 91 bool DnsResponderClient::GetResolverInfo(aidl::android::net::IDnsResolver* dnsResolverService, 92 unsigned netId, std::vector<std::string>* servers, 93 std::vector<std::string>* domains, 94 std::vector<std::string>* tlsServers, res_params* params, 95 std::vector<ResolverStats>* stats, 96 int* waitForPendingReqTimeoutCount) { 97 using aidl::android::net::IDnsResolver; 98 std::vector<int32_t> params32; 99 std::vector<int32_t> stats32; 100 std::vector<int32_t> waitForPendingReqTimeoutCount32{0}; 101 auto rv = dnsResolverService->getResolverInfo(netId, servers, domains, tlsServers, ¶ms32, 102 &stats32, &waitForPendingReqTimeoutCount32); 103 104 if (!rv.isOk() || params32.size() != static_cast<size_t>(IDnsResolver::RESOLVER_PARAMS_COUNT)) { 105 return false; 106 } 107 *params = res_params{ 108 .sample_validity = 109 static_cast<uint16_t>(params32[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY]), 110 .success_threshold = 111 static_cast<uint8_t>(params32[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD]), 112 .min_samples = 113 static_cast<uint8_t>(params32[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES]), 114 .max_samples = 115 static_cast<uint8_t>(params32[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES]), 116 .base_timeout_msec = params32[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC], 117 .retry_count = params32[IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT], 118 }; 119 *waitForPendingReqTimeoutCount = waitForPendingReqTimeoutCount32[0]; 120 return ResolverStats::decodeAll(stats32, stats); 121 } 122 123 bool DnsResponderClient::SetResolversForNetwork(const std::vector<std::string>& servers, 124 const std::vector<std::string>& domains, 125 const std::vector<int>& params) { 126 const auto& resolverParams = 127 makeResolverParamsParcel(TEST_NETID, params, servers, domains, "", {}, ""); 128 const auto rv = mDnsResolvSrv->setResolverConfiguration(resolverParams); 129 return rv.isOk(); 130 } 131 132 bool DnsResponderClient::SetResolversWithTls(const std::vector<std::string>& servers, 133 const std::vector<std::string>& domains, 134 const std::vector<int>& params, 135 const std::vector<std::string>& tlsServers, 136 const std::string& name) { 137 const auto& resolverParams = makeResolverParamsParcel(TEST_NETID, params, servers, domains, 138 name, tlsServers, kCaCert); 139 const auto rv = mDnsResolvSrv->setResolverConfiguration(resolverParams); 140 if (!rv.isOk()) LOG(ERROR) << "SetResolversWithTls() -> " << rv.getMessage(); 141 return rv.isOk(); 142 } 143 144 bool DnsResponderClient::SetResolversFromParcel(const ResolverParamsParcel& resolverParams) { 145 const auto rv = mDnsResolvSrv->setResolverConfiguration(resolverParams); 146 if (!rv.isOk()) LOG(ERROR) << "SetResolversFromParcel() -> " << rv.getMessage(); 147 return rv.isOk(); 148 } 149 150 ResolverParamsParcel DnsResponderClient::GetDefaultResolverParamsParcel() { 151 return makeResolverParamsParcel(TEST_NETID, kDefaultParams, kDefaultServers, 152 kDefaultSearchDomains, {} /* tlsHostname */, kDefaultServers, 153 kCaCert); 154 } 155 156 void DnsResponderClient::SetupDNSServers(unsigned numServers, const std::vector<Mapping>& mappings, 157 std::vector<std::unique_ptr<test::DNSResponder>>* dns, 158 std::vector<std::string>* servers) { 159 const char* listenSrv = "53"; 160 dns->resize(numServers); 161 servers->resize(numServers); 162 for (unsigned i = 0; i < numServers; ++i) { 163 auto& server = (*servers)[i]; 164 auto& d = (*dns)[i]; 165 server = StringPrintf("127.0.0.%u", i + 100); 166 d = std::make_unique<test::DNSResponder>(server, listenSrv, ns_rcode::ns_r_servfail); 167 for (const auto& mapping : mappings) { 168 d->addMapping(mapping.entry.c_str(), ns_type::ns_t_a, mapping.ip4.c_str()); 169 d->addMapping(mapping.entry.c_str(), ns_type::ns_t_aaaa, mapping.ip6.c_str()); 170 } 171 d->startServer(); 172 } 173 } 174 175 int DnsResponderClient::SetupOemNetwork() { 176 mNetdSrv->networkDestroy(TEST_NETID); 177 mDnsResolvSrv->destroyNetworkCache(TEST_NETID); 178 179 ::ndk::ScopedAStatus ret; 180 if (DnsResponderClient::isRemoteVersionSupported(mNetdSrv, 6)) { 181 const auto& config = DnsResponderClient::makeNativeNetworkConfig( 182 TEST_NETID, NativeNetworkType::PHYSICAL, INetd::PERMISSION_NONE, /*secure=*/false); 183 ret = mNetdSrv->networkCreate(config); 184 } else { 185 // Only for presubmit tests that run mainline module (and its tests) on R or earlier images. 186 #pragma clang diagnostic push 187 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 188 ret = mNetdSrv->networkCreatePhysical(TEST_NETID, INetd::PERMISSION_NONE); 189 #pragma clang diagnostic pop 190 } 191 if (!ret.isOk()) { 192 fprintf(stderr, "Creating physical network %d failed, %s\n", TEST_NETID, ret.getMessage()); 193 return -1; 194 } 195 ret = mDnsResolvSrv->createNetworkCache(TEST_NETID); 196 if (!ret.isOk()) { 197 fprintf(stderr, "Creating network cache %d failed, %s\n", TEST_NETID, ret.getMessage()); 198 return -1; 199 } 200 setNetworkForProcess(TEST_NETID); 201 if ((unsigned)TEST_NETID != getNetworkForProcess()) { 202 return -1; 203 } 204 return TEST_NETID; 205 } 206 207 void DnsResponderClient::TearDownOemNetwork(int oemNetId) { 208 if (oemNetId != -1) { 209 mNetdSrv->networkDestroy(oemNetId); 210 mDnsResolvSrv->destroyNetworkCache(oemNetId); 211 } 212 } 213 214 void DnsResponderClient::SetUp() { 215 // binder setup 216 ndk::SpAIBinder netdBinder = ndk::SpAIBinder(AServiceManager_getService("netd")); 217 mNetdSrv = INetd::fromBinder(netdBinder); 218 if (mNetdSrv.get() == nullptr) { 219 LOG(FATAL) << "Can't connect to service 'netd'. Missing root privileges? uid=" << getuid(); 220 } 221 222 ndk::SpAIBinder resolvBinder = ndk::SpAIBinder(AServiceManager_getService("dnsresolver")); 223 mDnsResolvSrv = IDnsResolver::fromBinder(resolvBinder); 224 if (mDnsResolvSrv.get() == nullptr) { 225 LOG(FATAL) << "Can't connect to service 'dnsresolver'. Missing root privileges? uid=" 226 << getuid(); 227 } 228 229 // Ensure resolutions go via proxy. 230 setenv(ANDROID_DNS_MODE, "", 1); 231 mOemNetId = SetupOemNetwork(); 232 } 233 234 void DnsResponderClient::TearDown() { 235 TearDownOemNetwork(mOemNetId); 236 } 237 238 NativeNetworkConfig DnsResponderClient::makeNativeNetworkConfig(int netId, 239 NativeNetworkType networkType, 240 int permission, bool secure) { 241 NativeNetworkConfig config = {}; 242 config.netId = netId; 243 config.networkType = networkType; 244 config.permission = permission; 245 config.secure = secure; 246 // The vpnType doesn't matter in AOSP. Just pick a well defined one from INetd. 247 config.vpnType = NativeVpnType::PLATFORM; 248 return config; 249 } 250