1 /* 2 * Copyright (C) 2020 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 TRACE_TAG TRANSPORT 18 19 #include "transport.h" 20 21 #ifdef _WIN32 22 #include <winsock2.h> 23 #else 24 #include <arpa/inet.h> 25 #endif 26 27 #include <memory> 28 #include <thread> 29 #include <unordered_set> 30 #include <vector> 31 32 #include <android-base/stringprintf.h> 33 #include <android-base/strings.h> 34 35 #include <discovery/common/config.h> 36 #include <discovery/common/reporting_client.h> 37 #include <discovery/public/dns_sd_service_factory.h> 38 #include <platform/api/network_interface.h> 39 #include <platform/api/serial_delete_ptr.h> 40 #include <platform/base/error.h> 41 #include <platform/base/interface_info.h> 42 43 #include "adb_client.h" 44 #include "adb_mdns.h" 45 #include "adb_trace.h" 46 #include "adb_utils.h" 47 #include "adb_wifi.h" 48 #include "client/mdns_utils.h" 49 #include "client/openscreen/mdns_service_watcher.h" 50 #include "client/openscreen/platform/task_runner.h" 51 #include "fdevent/fdevent.h" 52 #include "sysdeps.h" 53 54 namespace { 55 56 using namespace mdns; 57 using namespace openscreen; 58 using ServicesUpdatedState = mdns::ServiceReceiver::ServicesUpdatedState; 59 60 struct DiscoveryState; 61 DiscoveryState* g_state = nullptr; 62 // TODO: remove once openscreen has bonjour client APIs. 63 bool g_using_bonjour = false; 64 AdbMdnsResponderFuncs g_adb_mdnsresponder_funcs; 65 66 class DiscoveryReportingClient : public discovery::ReportingClient { 67 public: 68 void OnFatalError(Error error) override { 69 // The multicast port 5353 may fail to bind because of another process already binding 70 // to it (bonjour). So let's fallback to bonjour client APIs. 71 // TODO: Remove this once openscreen implements the bonjour client APIs. 72 LOG(ERROR) << "Encountered fatal discovery error: " << error; 73 got_fatal_ = true; 74 } 75 76 void OnRecoverableError(Error error) override { 77 LOG(ERROR) << "Encountered recoverable discovery error: " << error; 78 } 79 80 bool GotFatalError() const { return got_fatal_; } 81 82 private: 83 std::atomic<bool> got_fatal_{false}; 84 }; 85 86 struct DiscoveryState { 87 SerialDeletePtr<discovery::DnsSdService> service; 88 std::unique_ptr<DiscoveryReportingClient> reporting_client; 89 std::unique_ptr<AdbOspTaskRunner> task_runner; 90 std::vector<std::unique_ptr<ServiceReceiver>> receivers; 91 InterfaceInfo interface_info; 92 }; 93 94 // Callback provided to service receiver for updates. 95 void OnServiceReceiverResult(std::vector<std::reference_wrapper<const ServiceInfo>> infos, 96 std::reference_wrapper<const ServiceInfo> info, 97 ServicesUpdatedState state) { 98 LOG(INFO) << "Endpoint state=" << static_cast<int>(state) 99 << " instance_name=" << info.get().instance_name 100 << " service_name=" << info.get().service_name << " addr=" << info.get().v4_address 101 << " addrv6=" << info.get().v6_address << " total_serv=" << infos.size(); 102 103 switch (state) { 104 case ServicesUpdatedState::EndpointCreated: 105 case ServicesUpdatedState::EndpointUpdated: 106 if (adb_DNSServiceShouldAutoConnect(info.get().service_name, 107 info.get().instance_name) && 108 info.get().v4_address) { 109 auto index = adb_DNSServiceIndexByName(info.get().service_name); 110 if (!index) { 111 return; 112 } 113 114 // Don't try to auto-connect if not in the keystore. 115 if (*index == kADBSecureConnectServiceRefIndex && 116 !adb_wifi_is_known_host(info.get().instance_name)) { 117 LOG(INFO) << "instance_name=" << info.get().instance_name << " not in keystore"; 118 return; 119 } 120 std::string response; 121 LOG(INFO) << "Attempting to auto-connect to instance=" << info.get().instance_name 122 << " service=" << info.get().service_name << " addr4=%s" 123 << info.get().v4_address << ":" << info.get().port; 124 connect_device( 125 android::base::StringPrintf("%s.%s", info.get().instance_name.c_str(), 126 info.get().service_name.c_str()), 127 &response); 128 } 129 break; 130 default: 131 break; 132 } 133 } 134 135 std::optional<discovery::Config> GetConfigForAllInterfaces() { 136 auto interface_infos = GetNetworkInterfaces(); 137 138 discovery::Config config; 139 for (const auto interface : interface_infos) { 140 discovery::Config::NetworkInfo::AddressFamilies supported_address_families = 141 discovery::Config::NetworkInfo::kNoAddressFamily; 142 if (interface.GetIpAddressV4()) { 143 supported_address_families |= discovery::Config::NetworkInfo::kUseIpV4; 144 } 145 if (interface.GetIpAddressV6()) { 146 supported_address_families |= discovery::Config::NetworkInfo::kUseIpV6; 147 } 148 if (supported_address_families == discovery::Config::NetworkInfo::kNoAddressFamily) { 149 LOG(INFO) << "Interface [" << interface << "] doesn't support ipv4 or ipv6." 150 << " Ignoring interface."; 151 continue; 152 } 153 config.network_info.push_back({interface, supported_address_families}); 154 LOG(VERBOSE) << "Listening on interface [" << interface << "]"; 155 } 156 157 if (config.network_info.empty()) { 158 LOG(INFO) << "No available network interfaces for mDNS discovery"; 159 return std::nullopt; 160 } 161 162 return config; 163 } 164 165 void StartDiscovery() { 166 CHECK(!g_state); 167 g_state = new DiscoveryState(); 168 g_state->task_runner = std::make_unique<AdbOspTaskRunner>(); 169 g_state->reporting_client = std::make_unique<DiscoveryReportingClient>(); 170 171 g_state->task_runner->PostTask([]() { 172 auto config = GetConfigForAllInterfaces(); 173 if (!config) { 174 return; 175 } 176 177 g_state->service = discovery::CreateDnsSdService(g_state->task_runner.get(), 178 g_state->reporting_client.get(), *config); 179 // Register a receiver for each service type 180 for (int i = 0; i < kNumADBDNSServices; ++i) { 181 auto receiver = std::make_unique<ServiceReceiver>( 182 g_state->service.get(), kADBDNSServices[i], OnServiceReceiverResult); 183 receiver->StartDiscovery(); 184 g_state->receivers.push_back(std::move(receiver)); 185 186 if (g_state->reporting_client->GotFatalError()) { 187 for (auto& r : g_state->receivers) { 188 if (r->is_running()) { 189 r->StopDiscovery(); 190 } 191 } 192 g_using_bonjour = true; 193 break; 194 } 195 } 196 197 if (g_using_bonjour) { 198 LOG(INFO) << "Fallback to MdnsResponder client for discovery"; 199 g_adb_mdnsresponder_funcs = StartMdnsResponderDiscovery(); 200 } 201 }); 202 } 203 204 void ForEachService(const std::unique_ptr<ServiceReceiver>& receiver, 205 std::string_view wanted_instance_name, adb_secure_foreach_service_callback cb) { 206 if (!receiver->is_running()) { 207 return; 208 } 209 auto services = receiver->GetServices(); 210 for (const auto& s : services) { 211 if (wanted_instance_name.empty() || s.get().instance_name == wanted_instance_name) { 212 std::stringstream ss; 213 ss << s.get().v4_address; 214 cb(s.get().instance_name.c_str(), s.get().service_name.c_str(), ss.str().c_str(), 215 s.get().port); 216 } 217 } 218 } 219 220 bool ConnectAdbSecureDevice(const MdnsInfo& info) { 221 if (!adb_wifi_is_known_host(info.service_name)) { 222 LOG(INFO) << "serviceName=" << info.service_name << " not in keystore"; 223 return false; 224 } 225 226 std::string response; 227 connect_device(android::base::StringPrintf("%s.%s", info.service_name.c_str(), 228 info.service_type.c_str()), 229 &response); 230 D("Secure connect to %s regtype %s (%s:%hu) : %s", info.service_name.c_str(), 231 info.service_type.c_str(), info.addr.c_str(), info.port, response.c_str()); 232 return true; 233 } 234 235 } // namespace 236 237 ///////////////////////////////////////////////////////////////////////////////// 238 void mdns_cleanup() { 239 if (g_using_bonjour) { 240 return g_adb_mdnsresponder_funcs.mdns_cleanup(); 241 } 242 } 243 244 void init_mdns_transport_discovery(void) { 245 // TODO(joshuaduong): Use openscreen discovery by default for all platforms. 246 const char* mdns_osp = getenv("ADB_MDNS_OPENSCREEN"); 247 if (mdns_osp && strcmp(mdns_osp, "1") == 0) { 248 LOG(INFO) << "Openscreen mdns discovery enabled"; 249 StartDiscovery(); 250 } else { 251 // Original behavior is to use Bonjour client. 252 g_using_bonjour = true; 253 g_adb_mdnsresponder_funcs = StartMdnsResponderDiscovery(); 254 } 255 } 256 257 bool adb_secure_connect_by_service_name(const std::string& instance_name) { 258 if (g_using_bonjour) { 259 return g_adb_mdnsresponder_funcs.adb_secure_connect_by_service_name(instance_name); 260 } 261 262 if (!g_state || g_state->receivers.empty()) { 263 LOG(INFO) << "Mdns not enabled"; 264 return false; 265 } 266 267 std::optional<MdnsInfo> info; 268 auto cb = [&](const std::string& instance_name, const std::string& service_name, 269 const std::string& ip_addr, 270 uint16_t port) { info.emplace(instance_name, service_name, ip_addr, port); }; 271 ForEachService(g_state->receivers[kADBSecureConnectServiceRefIndex], instance_name, cb); 272 if (info.has_value()) { 273 return ConnectAdbSecureDevice(*info); 274 } 275 return false; 276 } 277 278 std::string mdns_check() { 279 if (!g_state && !g_using_bonjour) { 280 return "ERROR: mdns discovery disabled"; 281 } 282 283 if (g_using_bonjour) { 284 return g_adb_mdnsresponder_funcs.mdns_check(); 285 } 286 287 return "mdns daemon version [Openscreen discovery 0.0.0]"; 288 } 289 290 std::string mdns_list_discovered_services() { 291 if (g_using_bonjour) { 292 return g_adb_mdnsresponder_funcs.mdns_list_discovered_services(); 293 } 294 295 if (!g_state || g_state->receivers.empty()) { 296 return ""; 297 } 298 299 std::string result; 300 auto cb = [&](const std::string& instance_name, const std::string& service_name, 301 const std::string& ip_addr, uint16_t port) { 302 result += android::base::StringPrintf("%s\t%s\t%s:%u\n", instance_name.data(), 303 service_name.data(), ip_addr.data(), port); 304 }; 305 306 for (const auto& receiver : g_state->receivers) { 307 ForEachService(receiver, "", cb); 308 } 309 return result; 310 } 311 312 std::optional<MdnsInfo> mdns_get_connect_service_info(const std::string& name) { 313 CHECK(!name.empty()); 314 315 if (g_using_bonjour) { 316 return g_adb_mdnsresponder_funcs.mdns_get_connect_service_info(name); 317 } 318 319 if (!g_state || g_state->receivers.empty()) { 320 return std::nullopt; 321 } 322 323 auto mdns_instance = mdns::mdns_parse_instance_name(name); 324 if (!mdns_instance.has_value()) { 325 D("Failed to parse mDNS name [%s]", name.data()); 326 return std::nullopt; 327 } 328 329 std::optional<MdnsInfo> info; 330 auto cb = [&](const std::string& instance_name, const std::string& service_name, 331 const std::string& ip_addr, 332 uint16_t port) { info.emplace(instance_name, service_name, ip_addr, port); }; 333 334 std::string reg_type; 335 // Service name was provided. 336 if (!mdns_instance->service_name.empty()) { 337 reg_type = android::base::StringPrintf("%s.%s", mdns_instance->service_name.data(), 338 mdns_instance->transport_type.data()); 339 const auto index = adb_DNSServiceIndexByName(reg_type); 340 if (!index) { 341 return std::nullopt; 342 } 343 switch (*index) { 344 case kADBTransportServiceRefIndex: 345 case kADBSecureConnectServiceRefIndex: 346 ForEachService(g_state->receivers[*index], mdns_instance->instance_name, cb); 347 break; 348 default: 349 D("Not a connectable service name [%s]", reg_type.data()); 350 return std::nullopt; 351 } 352 return info; 353 } 354 355 // No mdns service name provided. Just search for the instance name in all adb connect services. 356 // Prefer the secured connect service over the other. 357 ForEachService(g_state->receivers[kADBSecureConnectServiceRefIndex], name, cb); 358 if (!info.has_value()) { 359 ForEachService(g_state->receivers[kADBTransportServiceRefIndex], name, cb); 360 } 361 362 return info; 363 } 364 365 std::optional<MdnsInfo> mdns_get_pairing_service_info(const std::string& name) { 366 CHECK(!name.empty()); 367 368 if (g_using_bonjour) { 369 return g_adb_mdnsresponder_funcs.mdns_get_pairing_service_info(name); 370 } 371 372 if (!g_state || g_state->receivers.empty()) { 373 return std::nullopt; 374 } 375 376 auto mdns_instance = mdns::mdns_parse_instance_name(name); 377 if (!mdns_instance.has_value()) { 378 D("Failed to parse mDNS name [%s]", name.data()); 379 return std::nullopt; 380 } 381 382 std::optional<MdnsInfo> info; 383 auto cb = [&](const std::string& instance_name, const std::string& service_name, 384 const std::string& ip_addr, 385 uint16_t port) { info.emplace(instance_name, service_name, ip_addr, port); }; 386 387 std::string reg_type; 388 // Verify it's a pairing service if user explicitly inputs it. 389 if (!mdns_instance->service_name.empty()) { 390 reg_type = android::base::StringPrintf("%s.%s", mdns_instance->service_name.data(), 391 mdns_instance->transport_type.data()); 392 const auto index = adb_DNSServiceIndexByName(reg_type); 393 if (!index) { 394 return std::nullopt; 395 } 396 switch (*index) { 397 case kADBSecurePairingServiceRefIndex: 398 break; 399 default: 400 D("Not an adb pairing reg_type [%s]", reg_type.data()); 401 return std::nullopt; 402 } 403 return info; 404 } 405 406 ForEachService(g_state->receivers[kADBSecurePairingServiceRefIndex], name, cb); 407 408 return info; 409 } 410