Casey Dahlin | 3122cdf | 2016-06-23 14:19:37 -0700 | [diff] [blame] | 1 | /* |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 2 | * Copyright (C) 2020 The Android Open Source Project |
Casey Dahlin | 3122cdf | 2016-06-23 14:19:37 -0700 | [diff] [blame] | 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 | |
Casey Dahlin | 20238f2 | 2016-09-21 14:03:39 -0700 | [diff] [blame] | 21 | #ifdef _WIN32 |
| 22 | #include <winsock2.h> |
| 23 | #else |
Casey Dahlin | 3122cdf | 2016-06-23 14:19:37 -0700 | [diff] [blame] | 24 | #include <arpa/inet.h> |
Casey Dahlin | 20238f2 | 2016-09-21 14:03:39 -0700 | [diff] [blame] | 25 | #endif |
Casey Dahlin | 3122cdf | 2016-06-23 14:19:37 -0700 | [diff] [blame] | 26 | |
Joshua Duong | 290ccb5 | 2019-11-20 14:18:43 -0800 | [diff] [blame] | 27 | #include <memory> |
Josh Gao | a7430f3 | 2017-05-03 14:23:09 -0700 | [diff] [blame] | 28 | #include <thread> |
Joshua Duong | 2ed15ac | 2020-04-23 09:46:12 -0700 | [diff] [blame] | 29 | #include <unordered_set> |
Lingfeng Yang | 9f4fff3 | 2018-11-26 17:31:39 -0800 | [diff] [blame] | 30 | #include <vector> |
Josh Gao | a7430f3 | 2017-05-03 14:23:09 -0700 | [diff] [blame] | 31 | |
Casey Dahlin | 3122cdf | 2016-06-23 14:19:37 -0700 | [diff] [blame] | 32 | #include <android-base/stringprintf.h> |
Joshua Duong | 290ccb5 | 2019-11-20 14:18:43 -0800 | [diff] [blame] | 33 | #include <android-base/strings.h> |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 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> |
Casey Dahlin | 3122cdf | 2016-06-23 14:19:37 -0700 | [diff] [blame] | 42 | |
Lingfeng Yang | 9f4fff3 | 2018-11-26 17:31:39 -0800 | [diff] [blame] | 43 | #include "adb_client.h" |
Casey Dahlin | 3122cdf | 2016-06-23 14:19:37 -0700 | [diff] [blame] | 44 | #include "adb_mdns.h" |
| 45 | #include "adb_trace.h" |
Joshua Duong | 290ccb5 | 2019-11-20 14:18:43 -0800 | [diff] [blame] | 46 | #include "adb_utils.h" |
| 47 | #include "adb_wifi.h" |
Joshua Duong | 7ea62d8 | 2020-05-01 09:25:12 -0700 | [diff] [blame] | 48 | #include "client/mdns_utils.h" |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 49 | #include "client/openscreen/mdns_service_watcher.h" |
| 50 | #include "client/openscreen/platform/task_runner.h" |
Josh Gao | b51193a | 2019-06-28 13:50:37 -0700 | [diff] [blame] | 51 | #include "fdevent/fdevent.h" |
Casey Dahlin | 3122cdf | 2016-06-23 14:19:37 -0700 | [diff] [blame] | 52 | #include "sysdeps.h" |
| 53 | |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 54 | namespace { |
Lingfeng Yang | 8f21710 | 2018-11-26 14:19:55 -0800 | [diff] [blame] | 55 | |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 56 | using namespace mdns; |
| 57 | using namespace openscreen; |
| 58 | using ServicesUpdatedState = mdns::ServiceReceiver::ServicesUpdatedState; |
Lingfeng Yang | 8f21710 | 2018-11-26 14:19:55 -0800 | [diff] [blame] | 59 | |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 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; |
Joshua Duong | 2ed15ac | 2020-04-23 09:46:12 -0700 | [diff] [blame] | 74 | } |
| 75 | |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 76 | void OnRecoverableError(Error error) override { |
| 77 | LOG(ERROR) << "Encountered recoverable discovery error: " << error; |
Joshua Duong | 2ed15ac | 2020-04-23 09:46:12 -0700 | [diff] [blame] | 78 | } |
| 79 | |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 80 | bool GotFatalError() const { return got_fatal_; } |
Joshua Duong | 2ed15ac | 2020-04-23 09:46:12 -0700 | [diff] [blame] | 81 | |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 82 | private: |
| 83 | std::atomic<bool> got_fatal_{false}; |
| 84 | }; |
Joshua Duong | 2ed15ac | 2020-04-23 09:46:12 -0700 | [diff] [blame] | 85 | |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 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; |
Joshua Duong | 2ed15ac | 2020-04-23 09:46:12 -0700 | [diff] [blame] | 132 | } |
| 133 | } |
| 134 | |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 135 | std::optional<discovery::Config> GetConfigForAllInterfaces() { |
| 136 | auto interface_infos = GetNetworkInterfaces(); |
| 137 | |
| 138 | discovery::Config config; |
| 139 | for (const auto interface : interface_infos) { |
Colin Cross | 434c85d | 2021-08-26 12:00:31 -0700 | [diff] [blame^] | 140 | config.network_info.push_back({interface}); |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 141 | LOG(VERBOSE) << "Listening on interface [" << interface << "]"; |
| 142 | } |
| 143 | |
| 144 | if (config.network_info.empty()) { |
| 145 | LOG(INFO) << "No available network interfaces for mDNS discovery"; |
| 146 | return std::nullopt; |
| 147 | } |
| 148 | |
| 149 | return config; |
| 150 | } |
| 151 | |
| 152 | void StartDiscovery() { |
| 153 | CHECK(!g_state); |
| 154 | g_state = new DiscoveryState(); |
| 155 | g_state->task_runner = std::make_unique<AdbOspTaskRunner>(); |
| 156 | g_state->reporting_client = std::make_unique<DiscoveryReportingClient>(); |
| 157 | |
| 158 | g_state->task_runner->PostTask([]() { |
| 159 | auto config = GetConfigForAllInterfaces(); |
| 160 | if (!config) { |
| 161 | return; |
| 162 | } |
| 163 | |
| 164 | g_state->service = discovery::CreateDnsSdService(g_state->task_runner.get(), |
| 165 | g_state->reporting_client.get(), *config); |
| 166 | // Register a receiver for each service type |
| 167 | for (int i = 0; i < kNumADBDNSServices; ++i) { |
| 168 | auto receiver = std::make_unique<ServiceReceiver>( |
| 169 | g_state->service.get(), kADBDNSServices[i], OnServiceReceiverResult); |
| 170 | receiver->StartDiscovery(); |
| 171 | g_state->receivers.push_back(std::move(receiver)); |
| 172 | |
| 173 | if (g_state->reporting_client->GotFatalError()) { |
| 174 | for (auto& r : g_state->receivers) { |
| 175 | if (r->is_running()) { |
| 176 | r->StopDiscovery(); |
| 177 | } |
| 178 | } |
| 179 | g_using_bonjour = true; |
| 180 | break; |
| 181 | } |
| 182 | } |
| 183 | |
| 184 | if (g_using_bonjour) { |
| 185 | LOG(INFO) << "Fallback to MdnsResponder client for discovery"; |
| 186 | g_adb_mdnsresponder_funcs = StartMdnsResponderDiscovery(); |
| 187 | } |
| 188 | }); |
| 189 | } |
| 190 | |
| 191 | void ForEachService(const std::unique_ptr<ServiceReceiver>& receiver, |
| 192 | std::string_view wanted_instance_name, adb_secure_foreach_service_callback cb) { |
| 193 | if (!receiver->is_running()) { |
| 194 | return; |
| 195 | } |
| 196 | auto services = receiver->GetServices(); |
| 197 | for (const auto& s : services) { |
| 198 | if (wanted_instance_name.empty() || s.get().instance_name == wanted_instance_name) { |
| 199 | std::stringstream ss; |
| 200 | ss << s.get().v4_address; |
| 201 | cb(s.get().instance_name.c_str(), s.get().service_name.c_str(), ss.str().c_str(), |
| 202 | s.get().port); |
| 203 | } |
| 204 | } |
| 205 | } |
| 206 | |
| 207 | bool ConnectAdbSecureDevice(const MdnsInfo& info) { |
| 208 | if (!adb_wifi_is_known_host(info.service_name)) { |
| 209 | LOG(INFO) << "serviceName=" << info.service_name << " not in keystore"; |
Joshua Duong | 2ed15ac | 2020-04-23 09:46:12 -0700 | [diff] [blame] | 210 | return false; |
| 211 | } |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 212 | |
| 213 | std::string response; |
| 214 | connect_device(android::base::StringPrintf("%s.%s", info.service_name.c_str(), |
| 215 | info.service_type.c_str()), |
| 216 | &response); |
| 217 | D("Secure connect to %s regtype %s (%s:%hu) : %s", info.service_name.c_str(), |
| 218 | info.service_type.c_str(), info.addr.c_str(), info.port, response.c_str()); |
Joshua Duong | 2ed15ac | 2020-04-23 09:46:12 -0700 | [diff] [blame] | 219 | return true; |
Lingfeng Yang | 8f21710 | 2018-11-26 14:19:55 -0800 | [diff] [blame] | 220 | } |
Casey Dahlin | 3122cdf | 2016-06-23 14:19:37 -0700 | [diff] [blame] | 221 | |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 222 | } // namespace |
Casey Dahlin | 20238f2 | 2016-09-21 14:03:39 -0700 | [diff] [blame] | 223 | |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 224 | ///////////////////////////////////////////////////////////////////////////////// |
| 225 | void mdns_cleanup() { |
| 226 | if (g_using_bonjour) { |
| 227 | return g_adb_mdnsresponder_funcs.mdns_cleanup(); |
Lingfeng Yang | b90156e | 2018-11-17 10:14:29 -0800 | [diff] [blame] | 228 | } |
Josh Gao | a7430f3 | 2017-05-03 14:23:09 -0700 | [diff] [blame] | 229 | } |
| 230 | |
| 231 | void init_mdns_transport_discovery(void) { |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 232 | // TODO(joshuaduong): Use openscreen discovery by default for all platforms. |
| 233 | const char* mdns_osp = getenv("ADB_MDNS_OPENSCREEN"); |
| 234 | if (mdns_osp && strcmp(mdns_osp, "1") == 0) { |
| 235 | LOG(INFO) << "Openscreen mdns discovery enabled"; |
| 236 | StartDiscovery(); |
| 237 | } else { |
| 238 | // Original behavior is to use Bonjour client. |
| 239 | g_using_bonjour = true; |
| 240 | g_adb_mdnsresponder_funcs = StartMdnsResponderDiscovery(); |
| 241 | } |
| 242 | } |
| 243 | |
| 244 | bool adb_secure_connect_by_service_name(const std::string& instance_name) { |
| 245 | if (g_using_bonjour) { |
| 246 | return g_adb_mdnsresponder_funcs.adb_secure_connect_by_service_name(instance_name); |
| 247 | } |
| 248 | |
| 249 | if (!g_state || g_state->receivers.empty()) { |
| 250 | LOG(INFO) << "Mdns not enabled"; |
| 251 | return false; |
| 252 | } |
| 253 | |
| 254 | std::optional<MdnsInfo> info; |
| 255 | auto cb = [&](const std::string& instance_name, const std::string& service_name, |
| 256 | const std::string& ip_addr, |
| 257 | uint16_t port) { info.emplace(instance_name, service_name, ip_addr, port); }; |
| 258 | ForEachService(g_state->receivers[kADBSecureConnectServiceRefIndex], instance_name, cb); |
| 259 | if (info.has_value()) { |
| 260 | return ConnectAdbSecureDevice(*info); |
| 261 | } |
| 262 | return false; |
Casey Dahlin | 3122cdf | 2016-06-23 14:19:37 -0700 | [diff] [blame] | 263 | } |
Joshua Duong | e22e161 | 2020-03-31 10:58:50 -0700 | [diff] [blame] | 264 | |
| 265 | std::string mdns_check() { |
Joshua Duong | cdc9c6a | 2021-05-03 12:57:07 -0700 | [diff] [blame] | 266 | if (!g_state && !g_using_bonjour) { |
| 267 | return "ERROR: mdns discovery disabled"; |
| 268 | } |
| 269 | |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 270 | if (g_using_bonjour) { |
| 271 | return g_adb_mdnsresponder_funcs.mdns_check(); |
Joshua Duong | e22e161 | 2020-03-31 10:58:50 -0700 | [diff] [blame] | 272 | } |
| 273 | |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 274 | return "mdns daemon version [Openscreen discovery 0.0.0]"; |
Joshua Duong | e22e161 | 2020-03-31 10:58:50 -0700 | [diff] [blame] | 275 | } |
Joshua Duong | 5f63d11 | 2020-03-31 08:39:24 -0700 | [diff] [blame] | 276 | |
| 277 | std::string mdns_list_discovered_services() { |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 278 | if (g_using_bonjour) { |
| 279 | return g_adb_mdnsresponder_funcs.mdns_list_discovered_services(); |
| 280 | } |
| 281 | |
| 282 | if (!g_state || g_state->receivers.empty()) { |
| 283 | return ""; |
| 284 | } |
| 285 | |
Joshua Duong | 5f63d11 | 2020-03-31 08:39:24 -0700 | [diff] [blame] | 286 | std::string result; |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 287 | auto cb = [&](const std::string& instance_name, const std::string& service_name, |
| 288 | const std::string& ip_addr, uint16_t port) { |
| 289 | result += android::base::StringPrintf("%s\t%s\t%s:%u\n", instance_name.data(), |
| 290 | service_name.data(), ip_addr.data(), port); |
Joshua Duong | 5f63d11 | 2020-03-31 08:39:24 -0700 | [diff] [blame] | 291 | }; |
| 292 | |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 293 | for (const auto& receiver : g_state->receivers) { |
| 294 | ForEachService(receiver, "", cb); |
| 295 | } |
Joshua Duong | 5f63d11 | 2020-03-31 08:39:24 -0700 | [diff] [blame] | 296 | return result; |
| 297 | } |
Joshua Duong | 7ea62d8 | 2020-05-01 09:25:12 -0700 | [diff] [blame] | 298 | |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 299 | std::optional<MdnsInfo> mdns_get_connect_service_info(const std::string& name) { |
Joshua Duong | 7ea62d8 | 2020-05-01 09:25:12 -0700 | [diff] [blame] | 300 | CHECK(!name.empty()); |
| 301 | |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 302 | if (g_using_bonjour) { |
| 303 | return g_adb_mdnsresponder_funcs.mdns_get_connect_service_info(name); |
| 304 | } |
| 305 | |
| 306 | if (!g_state || g_state->receivers.empty()) { |
Joshua Duong | 31451f2 | 2020-06-16 15:04:51 -0700 | [diff] [blame] | 307 | return std::nullopt; |
| 308 | } |
Joshua Duong | 31451f2 | 2020-06-16 15:04:51 -0700 | [diff] [blame] | 309 | |
Joshua Duong | 7ea62d8 | 2020-05-01 09:25:12 -0700 | [diff] [blame] | 310 | auto mdns_instance = mdns::mdns_parse_instance_name(name); |
| 311 | if (!mdns_instance.has_value()) { |
| 312 | D("Failed to parse mDNS name [%s]", name.data()); |
| 313 | return std::nullopt; |
| 314 | } |
| 315 | |
| 316 | std::optional<MdnsInfo> info; |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 317 | auto cb = [&](const std::string& instance_name, const std::string& service_name, |
| 318 | const std::string& ip_addr, |
| 319 | uint16_t port) { info.emplace(instance_name, service_name, ip_addr, port); }; |
Joshua Duong | 7ea62d8 | 2020-05-01 09:25:12 -0700 | [diff] [blame] | 320 | |
| 321 | std::string reg_type; |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 322 | // Service name was provided. |
Joshua Duong | 7ea62d8 | 2020-05-01 09:25:12 -0700 | [diff] [blame] | 323 | if (!mdns_instance->service_name.empty()) { |
| 324 | reg_type = android::base::StringPrintf("%s.%s", mdns_instance->service_name.data(), |
| 325 | mdns_instance->transport_type.data()); |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 326 | const auto index = adb_DNSServiceIndexByName(reg_type); |
| 327 | if (!index) { |
| 328 | return std::nullopt; |
| 329 | } |
| 330 | switch (*index) { |
Joshua Duong | 7ea62d8 | 2020-05-01 09:25:12 -0700 | [diff] [blame] | 331 | case kADBTransportServiceRefIndex: |
Joshua Duong | 7ea62d8 | 2020-05-01 09:25:12 -0700 | [diff] [blame] | 332 | case kADBSecureConnectServiceRefIndex: |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 333 | ForEachService(g_state->receivers[*index], mdns_instance->instance_name, cb); |
Joshua Duong | 7ea62d8 | 2020-05-01 09:25:12 -0700 | [diff] [blame] | 334 | break; |
| 335 | default: |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 336 | D("Not a connectable service name [%s]", reg_type.data()); |
Joshua Duong | 7ea62d8 | 2020-05-01 09:25:12 -0700 | [diff] [blame] | 337 | return std::nullopt; |
| 338 | } |
| 339 | return info; |
| 340 | } |
| 341 | |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 342 | // No mdns service name provided. Just search for the instance name in all adb connect services. |
| 343 | // Prefer the secured connect service over the other. |
| 344 | ForEachService(g_state->receivers[kADBSecureConnectServiceRefIndex], name, cb); |
| 345 | if (!info.has_value()) { |
| 346 | ForEachService(g_state->receivers[kADBTransportServiceRefIndex], name, cb); |
Joshua Duong | 7ea62d8 | 2020-05-01 09:25:12 -0700 | [diff] [blame] | 347 | } |
| 348 | |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 349 | return info; |
Joshua Duong | 7ea62d8 | 2020-05-01 09:25:12 -0700 | [diff] [blame] | 350 | } |
Joshua Duong | 07e9587 | 2020-05-04 18:42:46 -0700 | [diff] [blame] | 351 | |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 352 | std::optional<MdnsInfo> mdns_get_pairing_service_info(const std::string& name) { |
Joshua Duong | 07e9587 | 2020-05-04 18:42:46 -0700 | [diff] [blame] | 353 | CHECK(!name.empty()); |
| 354 | |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 355 | if (g_using_bonjour) { |
| 356 | return g_adb_mdnsresponder_funcs.mdns_get_pairing_service_info(name); |
| 357 | } |
| 358 | |
| 359 | if (!g_state || g_state->receivers.empty()) { |
| 360 | return std::nullopt; |
| 361 | } |
| 362 | |
Joshua Duong | 07e9587 | 2020-05-04 18:42:46 -0700 | [diff] [blame] | 363 | auto mdns_instance = mdns::mdns_parse_instance_name(name); |
| 364 | if (!mdns_instance.has_value()) { |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 365 | D("Failed to parse mDNS name [%s]", name.data()); |
Joshua Duong | 07e9587 | 2020-05-04 18:42:46 -0700 | [diff] [blame] | 366 | return std::nullopt; |
| 367 | } |
| 368 | |
| 369 | std::optional<MdnsInfo> info; |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 370 | auto cb = [&](const std::string& instance_name, const std::string& service_name, |
| 371 | const std::string& ip_addr, |
| 372 | uint16_t port) { info.emplace(instance_name, service_name, ip_addr, port); }; |
Joshua Duong | 07e9587 | 2020-05-04 18:42:46 -0700 | [diff] [blame] | 373 | |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 374 | std::string reg_type; |
Joshua Duong | 07e9587 | 2020-05-04 18:42:46 -0700 | [diff] [blame] | 375 | // Verify it's a pairing service if user explicitly inputs it. |
| 376 | if (!mdns_instance->service_name.empty()) { |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 377 | reg_type = android::base::StringPrintf("%s.%s", mdns_instance->service_name.data(), |
| 378 | mdns_instance->transport_type.data()); |
| 379 | const auto index = adb_DNSServiceIndexByName(reg_type); |
| 380 | if (!index) { |
| 381 | return std::nullopt; |
| 382 | } |
| 383 | switch (*index) { |
Joshua Duong | 07e9587 | 2020-05-04 18:42:46 -0700 | [diff] [blame] | 384 | case kADBSecurePairingServiceRefIndex: |
| 385 | break; |
| 386 | default: |
| 387 | D("Not an adb pairing reg_type [%s]", reg_type.data()); |
| 388 | return std::nullopt; |
| 389 | } |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 390 | return info; |
Joshua Duong | 07e9587 | 2020-05-04 18:42:46 -0700 | [diff] [blame] | 391 | } |
| 392 | |
Joshua Duong | f4ba8d7 | 2021-01-13 12:18:15 -0800 | [diff] [blame] | 393 | ForEachService(g_state->receivers[kADBSecurePairingServiceRefIndex], name, cb); |
| 394 | |
Joshua Duong | 07e9587 | 2020-05-04 18:42:46 -0700 | [diff] [blame] | 395 | return info; |
| 396 | } |