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 <vector>
30
31 #include <android-base/stringprintf.h>
32 #include <android-base/strings.h>
33 #include <dns_sd.h>
34
35 #include "adb_client.h"
36 #include "adb_mdns.h"
37 #include "adb_trace.h"
38 #include "adb_utils.h"
39 #include "adb_wifi.h"
40 #include "client/mdns_utils.h"
41 #include "fdevent/fdevent.h"
42 #include "sysdeps.h"
43
44 // TODO: Remove this file once openscreen has bonjour client APIs implemented.
45 namespace {
46
47 DNSServiceRef g_service_refs[kNumADBDNSServices];
48 fdevent* g_service_ref_fdes[kNumADBDNSServices];
49
50 // Use adb_DNSServiceRefSockFD() instead of calling DNSServiceRefSockFD()
51 // directly so that the socket is put through the appropriate compatibility
52 // layers to work with the rest of ADB's internal APIs.
adb_DNSServiceRefSockFD(DNSServiceRef ref)53 int adb_DNSServiceRefSockFD(DNSServiceRef ref) {
54 return adb_register_socket(DNSServiceRefSockFD(ref));
55 }
56 #define DNSServiceRefSockFD ___xxx_DNSServiceRefSockFD
57
58 void DNSSD_API register_service_ip(DNSServiceRef sdref, DNSServiceFlags flags,
59 uint32_t interface_index, DNSServiceErrorType error_code,
60 const char* hostname, const sockaddr* address, uint32_t ttl,
61 void* context);
62
pump_service_ref(int,unsigned ev,void * data)63 void pump_service_ref(int /*fd*/, unsigned ev, void* data) {
64 DNSServiceRef* ref = reinterpret_cast<DNSServiceRef*>(data);
65
66 if (ev & FDE_READ) DNSServiceProcessResult(*ref);
67 }
68
69 class AsyncServiceRef {
70 public:
Initialized() const71 bool Initialized() const { return initialized_; }
72
DestroyServiceRef()73 void DestroyServiceRef() {
74 if (!initialized_) {
75 return;
76 }
77
78 // Order matters here! Must destroy the fdevent first since it has a
79 // reference to |sdref_|.
80 fdevent_destroy(fde_);
81 D("DNSServiceRefDeallocate(sdref=%p)", sdref_);
82 DNSServiceRefDeallocate(sdref_);
83 initialized_ = false;
84 }
85
~AsyncServiceRef()86 virtual ~AsyncServiceRef() { DestroyServiceRef(); }
87
88 protected:
89 DNSServiceRef sdref_;
90
Initialize()91 void Initialize() {
92 fde_ = fdevent_create(adb_DNSServiceRefSockFD(sdref_), pump_service_ref, &sdref_);
93 if (fde_ == nullptr) {
94 D("Unable to create fdevent");
95 return;
96 }
97 fdevent_set(fde_, FDE_READ);
98 initialized_ = true;
99 }
100
101 private:
102 bool initialized_ = false;
103 fdevent* fde_;
104 };
105
106 class ResolvedService : public AsyncServiceRef {
107 public:
108 virtual ~ResolvedService() = default;
109
ResolvedService(const std::string & service_name,const std::string & reg_type,uint32_t interface_index,const std::string & host_target,uint16_t port,int version)110 ResolvedService(const std::string& service_name, const std::string& reg_type,
111 uint32_t interface_index, const std::string& host_target, uint16_t port,
112 int version)
113 : service_name_(service_name),
114 reg_type_(reg_type),
115 host_target_(host_target),
116 port_(port),
117 sa_family_(0),
118 service_version_(version) {
119 /* TODO: We should be able to get IPv6 support by adding
120 * kDNSServiceProtocol_IPv6 to the flags below. However, when we do
121 * this, we get served link-local addresses that are usually useless to
122 * connect to. What's more, we seem to /only/ get those and nothing else.
123 * If we want IPv6 in the future we'll have to figure out why.
124 */
125 DNSServiceErrorType ret = DNSServiceGetAddrInfo(
126 &sdref_, 0, interface_index, kDNSServiceProtocol_IPv4, host_target_.c_str(),
127 register_service_ip, reinterpret_cast<void*>(this));
128
129 if (ret != kDNSServiceErr_NoError) {
130 D("Got %d from DNSServiceGetAddrInfo.", ret);
131 } else {
132 D("DNSServiceGetAddrInfo(sdref=%p, host_target=%s)", sdref_, host_target_.c_str());
133 Initialize();
134 }
135
136 D("Client version: %d Service version: %d\n", clientVersion_, service_version_);
137 }
138
ConnectSecureWifiDevice()139 bool ConnectSecureWifiDevice() {
140 if (!adb_wifi_is_known_host(service_name_)) {
141 LOG(INFO) << "service_name=" << service_name_ << " not in keystore";
142 return false;
143 }
144
145 std::string response;
146 connect_device(
147 android::base::StringPrintf("%s.%s", service_name_.c_str(), reg_type_.c_str()),
148 &response);
149 D("Secure connect to %s regtype %s (%s:%hu) : %s", service_name_.c_str(), reg_type_.c_str(),
150 ip_addr_.c_str(), port_, response.c_str());
151 return true;
152 }
153
RegisterIpAddress(const sockaddr * address)154 bool RegisterIpAddress(const sockaddr* address) {
155 sa_family_ = address->sa_family;
156
157 const void* ip_addr_data;
158 if (sa_family_ == AF_INET) {
159 ip_addr_data = &reinterpret_cast<const sockaddr_in*>(address)->sin_addr;
160 addr_format_ = "%s:%hu";
161 } else if (sa_family_ == AF_INET6) {
162 ip_addr_data = &reinterpret_cast<const sockaddr_in6*>(address)->sin6_addr;
163 addr_format_ = "[%s]:%hu";
164 } else { // Should be impossible
165 D("mDNS resolved non-IP address.");
166 return false;
167 }
168
169 // Winsock version requires the const cast mingw defines inet_ntop differently from msvc.
170 char ip_addr[INET6_ADDRSTRLEN] = {};
171 if (!inet_ntop(sa_family_, const_cast<void*>(ip_addr_data), ip_addr, sizeof(ip_addr))) {
172 D("Could not convert IP address to string.");
173 return false;
174 }
175 ip_addr_ = ip_addr;
176
177 return true;
178 }
179
AddToServiceRegistry(std::unique_ptr<ResolvedService> service)180 static void AddToServiceRegistry(std::unique_ptr<ResolvedService> service) {
181 // Add to the service registry before trying to auto-connect, since socket_spec_connect will
182 // check these registries for the ip address when connecting via mdns instance name.
183 auto service_index = service->service_index();
184 if (!service_index) {
185 return;
186 }
187
188 // Remove any services with the same instance name, as it may be a stale registration.
189 RemoveDNSService(service->reg_type(), service->service_name());
190
191 ServiceRegistry* services = nullptr;
192 switch (*service_index) {
193 case kADBTransportServiceRefIndex:
194 services = sAdbTransportServices;
195 break;
196 case kADBSecurePairingServiceRefIndex:
197 services = sAdbSecurePairingServices;
198 break;
199 case kADBSecureConnectServiceRefIndex:
200 services = sAdbSecureConnectServices;
201 break;
202 default:
203 LOG(WARNING) << "No registry available for reg_type=[" << service->reg_type()
204 << "]";
205 return;
206 }
207
208 services->push_back(std::move(service));
209 const auto& s = services->back();
210
211 auto reg_type = s->reg_type();
212 auto service_name = s->service_name();
213
214 auto ip_addr = s->ip_address();
215 auto port = s->port();
216 if (adb_DNSServiceShouldAutoConnect(reg_type, service_name)) {
217 std::string response;
218 D("Attempting to connect service_name=[%s], regtype=[%s] ip_addr=(%s:%hu)",
219 service_name.c_str(), reg_type.c_str(), ip_addr.c_str(), port);
220
221 if (*service_index == kADBSecureConnectServiceRefIndex) {
222 s->ConnectSecureWifiDevice();
223 } else {
224 connect_device(android::base::StringPrintf("%s.%s", service_name.c_str(),
225 reg_type.c_str()),
226 &response);
227 D("Connect to %s regtype %s (%s:%hu) : %s", service_name.c_str(), reg_type.c_str(),
228 ip_addr.c_str(), port, response.c_str());
229 }
230 } else {
231 D("Not immediately connecting to service_name=[%s], regtype=[%s] ip_addr=(%s:%hu)",
232 service_name.c_str(), reg_type.c_str(), ip_addr.c_str(), port);
233 }
234 }
235
service_index() const236 std::optional<int> service_index() const {
237 return adb_DNSServiceIndexByName(reg_type_.c_str());
238 }
239
host_target() const240 const std::string& host_target() const { return host_target_; }
241
service_name() const242 const std::string& service_name() const { return service_name_; }
243
reg_type() const244 const std::string& reg_type() const { return reg_type_; }
245
ip_address() const246 const std::string& ip_address() const { return ip_addr_; }
247
port() const248 uint16_t port() const { return port_; }
249
250 using ServiceRegistry = std::vector<std::unique_ptr<ResolvedService>>;
251
252 // unencrypted tcp connections
253 static ServiceRegistry* sAdbTransportServices;
254
255 static ServiceRegistry* sAdbSecurePairingServices;
256 static ServiceRegistry* sAdbSecureConnectServices;
257
258 static void InitAdbServiceRegistries();
259
260 static void ForEachService(const ServiceRegistry& services, const std::string& hostname,
261 adb_secure_foreach_service_callback cb);
262
263 static bool ConnectByServiceName(const ServiceRegistry& services,
264 const std::string& service_name);
265
266 static void RemoveDNSService(const std::string& reg_type, const std::string& service_name);
267
268 private:
269 int clientVersion_ = ADB_SECURE_CLIENT_VERSION;
270 std::string addr_format_;
271 std::string service_name_;
272 std::string reg_type_;
273 std::string host_target_;
274 const uint16_t port_;
275 int sa_family_;
276 std::string ip_addr_;
277 int service_version_;
278 };
279
280 // static
281 ResolvedService::ServiceRegistry* ResolvedService::sAdbTransportServices = NULL;
282
283 // static
284 ResolvedService::ServiceRegistry* ResolvedService::sAdbSecurePairingServices = NULL;
285
286 // static
287 ResolvedService::ServiceRegistry* ResolvedService::sAdbSecureConnectServices = NULL;
288
289 // static
InitAdbServiceRegistries()290 void ResolvedService::InitAdbServiceRegistries() {
291 if (!sAdbTransportServices) {
292 sAdbTransportServices = new ServiceRegistry;
293 }
294 if (!sAdbSecurePairingServices) {
295 sAdbSecurePairingServices = new ServiceRegistry;
296 }
297 if (!sAdbSecureConnectServices) {
298 sAdbSecureConnectServices = new ServiceRegistry;
299 }
300 }
301
302 // static
ForEachService(const ServiceRegistry & services,const std::string & wanted_service_name,adb_secure_foreach_service_callback cb)303 void ResolvedService::ForEachService(const ServiceRegistry& services,
304 const std::string& wanted_service_name,
305 adb_secure_foreach_service_callback cb) {
306 InitAdbServiceRegistries();
307
308 for (const auto& service : services) {
309 auto service_name = service->service_name();
310 auto reg_type = service->reg_type();
311 auto ip = service->ip_address();
312 auto port = service->port();
313
314 if (wanted_service_name.empty()) {
315 cb(service_name.c_str(), reg_type.c_str(), ip.c_str(), port);
316 } else if (service_name == wanted_service_name) {
317 cb(service_name.c_str(), reg_type.c_str(), ip.c_str(), port);
318 }
319 }
320 }
321
322 // static
ConnectByServiceName(const ServiceRegistry & services,const std::string & service_name)323 bool ResolvedService::ConnectByServiceName(const ServiceRegistry& services,
324 const std::string& service_name) {
325 InitAdbServiceRegistries();
326 for (const auto& service : services) {
327 auto wanted_name = service->service_name();
328 if (wanted_name == service_name) {
329 D("Got service_name match [%s]", wanted_name.c_str());
330 return service->ConnectSecureWifiDevice();
331 }
332 }
333 D("No registered service_names matched [%s]", service_name.c_str());
334 return false;
335 }
336
337 // static
RemoveDNSService(const std::string & reg_type,const std::string & service_name)338 void ResolvedService::RemoveDNSService(const std::string& reg_type,
339 const std::string& service_name) {
340 D("%s: reg_type=[%s] service_name=[%s]", __func__, reg_type.c_str(), service_name.c_str());
341 auto index = adb_DNSServiceIndexByName(reg_type);
342 if (!index) {
343 return;
344 }
345 ServiceRegistry* services;
346 switch (*index) {
347 case kADBTransportServiceRefIndex:
348 services = sAdbTransportServices;
349 break;
350 case kADBSecurePairingServiceRefIndex:
351 services = sAdbSecurePairingServices;
352 break;
353 case kADBSecureConnectServiceRefIndex:
354 services = sAdbSecureConnectServices;
355 break;
356 default:
357 return;
358 }
359
360 if (services->empty()) {
361 return;
362 }
363
364 services->erase(std::remove_if(services->begin(), services->end(),
365 [&service_name](std::unique_ptr<ResolvedService>& service) {
366 return (service_name == service->service_name());
367 }),
368 services->end());
369 }
370
register_service_ip(DNSServiceRef sdref,DNSServiceFlags flags,uint32_t,DNSServiceErrorType error_code,const char * hostname,const sockaddr * address,uint32_t ttl,void * context)371 void DNSSD_API register_service_ip(DNSServiceRef sdref, DNSServiceFlags flags,
372 uint32_t /*interface_index*/, DNSServiceErrorType error_code,
373 const char* hostname, const sockaddr* address, uint32_t ttl,
374 void* context) {
375 D("%s: sdref=%p flags=0x%08x error_code=%u ttl=%u", __func__, sdref, flags, error_code, ttl);
376 std::unique_ptr<ResolvedService> data(static_cast<ResolvedService*>(context));
377 // Only resolve the address once. If the address or port changes, we'll just get another
378 // registration.
379 data->DestroyServiceRef();
380
381 if (error_code != kDNSServiceErr_NoError) {
382 D("Got error while looking up ip_addr [%u]", error_code);
383 return;
384 }
385
386 if (flags & kDNSServiceFlagsAdd) {
387 if (data->RegisterIpAddress(address)) {
388 D("Resolved IP address for [%s]. Adding to service registry.", hostname);
389 ResolvedService::AddToServiceRegistry(std::move(data));
390 }
391 }
392 }
393
394 void DNSSD_API register_resolved_mdns_service(DNSServiceRef sdref, DNSServiceFlags flags,
395 uint32_t interface_index,
396 DNSServiceErrorType error_code, const char* fullname,
397 const char* host_target, uint16_t port,
398 uint16_t txt_len, const unsigned char* txt_record,
399 void* context);
400
401 class DiscoveredService : public AsyncServiceRef {
402 public:
DiscoveredService(uint32_t interface_index,const char * service_name,const char * regtype,const char * domain)403 DiscoveredService(uint32_t interface_index, const char* service_name, const char* regtype,
404 const char* domain)
405 : service_name_(service_name), reg_type_(regtype) {
406 DNSServiceErrorType ret =
407 DNSServiceResolve(&sdref_, 0, interface_index, service_name, regtype, domain,
408 register_resolved_mdns_service, reinterpret_cast<void*>(this));
409
410 D("DNSServiceResolve for "
411 "interface_index %u "
412 "service_name %s "
413 "regtype %s "
414 "domain %s "
415 ": %d",
416 interface_index, service_name, regtype, domain, ret);
417
418 if (ret == kDNSServiceErr_NoError) {
419 Initialize();
420 }
421 }
422
service_name()423 const std::string& service_name() { return service_name_; }
424
reg_type()425 const std::string& reg_type() { return reg_type_; }
426
427 private:
428 std::string service_name_;
429 std::string reg_type_;
430 };
431
432 // Returns the version the device wanted to advertise,
433 // or -1 if parsing fails.
ParseVersionFromTxtRecord(uint16_t txt_len,const unsigned char * txt_record)434 int ParseVersionFromTxtRecord(uint16_t txt_len, const unsigned char* txt_record) {
435 if (!txt_len) return -1;
436 if (!txt_record) return -1;
437
438 // https://tools.ietf.org/html/rfc6763
439 // """
440 // 6.1. General Format Rules for DNS TXT Records
441 //
442 // A DNS TXT record can be up to 65535 (0xFFFF) bytes long. The total
443 // length is indicated by the length given in the resource record header
444 // in the DNS message. There is no way to tell directly from the data
445 // alone how long it is (e.g., there is no length count at the start, or
446 // terminating NULL byte at the end).
447 // """
448
449 // Let's trust the TXT record's length byte
450 // Worst case, it wastes 255 bytes
451 std::vector<char> record_str(txt_len + 1, '\0');
452 char* str = record_str.data();
453
454 memcpy(str, txt_record + 1 /* skip the length byte */, txt_len);
455
456 // Check if it's the version key
457 static const char* version_key = "v=";
458 size_t version_key_len = strlen(version_key);
459
460 if (strncmp(version_key, str, version_key_len)) return -1;
461
462 auto value_start = str + version_key_len;
463
464 long parsed_number = strtol(value_start, 0, 10);
465
466 // No valid conversion. Also, 0
467 // is not a valid version.
468 if (!parsed_number) return -1;
469
470 // Outside bounds of int.
471 if (parsed_number < INT_MIN || parsed_number > INT_MAX) return -1;
472
473 // Possibly valid version
474 return static_cast<int>(parsed_number);
475 }
476
register_resolved_mdns_service(DNSServiceRef sdref,DNSServiceFlags flags,uint32_t interface_index,DNSServiceErrorType error_code,const char * fullname,const char * host_target,uint16_t port,uint16_t txt_len,const unsigned char * txt_record,void * context)477 void DNSSD_API register_resolved_mdns_service(DNSServiceRef sdref, DNSServiceFlags flags,
478 uint32_t interface_index,
479 DNSServiceErrorType error_code, const char* fullname,
480 const char* host_target, uint16_t port,
481 uint16_t txt_len, const unsigned char* txt_record,
482 void* context) {
483 D("Resolved a service.");
484 std::unique_ptr<DiscoveredService> discovered(reinterpret_cast<DiscoveredService*>(context));
485
486 if (error_code != kDNSServiceErr_NoError) {
487 D("Got error %d resolving service.", error_code);
488 return;
489 }
490
491 // TODO: Reject certain combinations of invalid or mismatched client and
492 // service versions here before creating anything.
493 // At the moment, there is nothing to reject, so accept everything
494 // as an optimistic default.
495 auto service_version = ParseVersionFromTxtRecord(txt_len, txt_record);
496
497 auto resolved = new ResolvedService(discovered->service_name(), discovered->reg_type(),
498 interface_index, host_target, ntohs(port), service_version);
499
500 if (!resolved->Initialized()) {
501 D("Unable to init resolved service");
502 delete resolved;
503 }
504
505 if (flags) { /* Only ever equals MoreComing or 0 */
506 D("releasing discovered service");
507 discovered.release();
508 }
509 }
510
on_service_browsed(DNSServiceRef sdref,DNSServiceFlags flags,uint32_t interface_index,DNSServiceErrorType error_code,const char * service_name,const char * regtype,const char * domain,void *)511 void DNSSD_API on_service_browsed(DNSServiceRef sdref, DNSServiceFlags flags,
512 uint32_t interface_index, DNSServiceErrorType error_code,
513 const char* service_name, const char* regtype, const char* domain,
514 void* /*context*/) {
515 if (error_code != kDNSServiceErr_NoError) {
516 D("Got error %d during mDNS browse.", error_code);
517 DNSServiceRefDeallocate(sdref);
518 auto service_index = adb_DNSServiceIndexByName(regtype);
519 if (service_index) {
520 fdevent_destroy(g_service_ref_fdes[*service_index]);
521 }
522 return;
523 }
524
525 if (flags & kDNSServiceFlagsAdd) {
526 D("%s: Discover found new service_name=[%s] regtype=[%s] domain=[%s]", __func__,
527 service_name, regtype, domain);
528 auto discovered = new DiscoveredService(interface_index, service_name, regtype, domain);
529 if (!discovered->Initialized()) {
530 delete discovered;
531 }
532 } else {
533 D("%s: Discover lost service_name=[%s] regtype=[%s] domain=[%s]", __func__, service_name,
534 regtype, domain);
535 ResolvedService::RemoveDNSService(regtype, service_name);
536 }
537 }
538
init_mdns_transport_discovery_thread(void)539 void init_mdns_transport_discovery_thread(void) {
540 int error_codes[kNumADBDNSServices];
541 for (int i = 0; i < kNumADBDNSServices; ++i) {
542 error_codes[i] = DNSServiceBrowse(&g_service_refs[i], 0, 0, kADBDNSServices[i], nullptr,
543 on_service_browsed, nullptr);
544
545 if (error_codes[i] != kDNSServiceErr_NoError) {
546 D("Got %d browsing for mDNS service %s.", error_codes[i], kADBDNSServices[i]);
547 } else {
548 fdevent_run_on_main_thread([i]() {
549 g_service_ref_fdes[i] = fdevent_create(adb_DNSServiceRefSockFD(g_service_refs[i]),
550 pump_service_ref, &g_service_refs[i]);
551 fdevent_set(g_service_ref_fdes[i], FDE_READ);
552 });
553 }
554 }
555 }
556
557 namespace MdnsResponder {
558
adb_secure_connect_by_service_name(const std::string & instance_name)559 bool adb_secure_connect_by_service_name(const std::string& instance_name) {
560 return ResolvedService::ConnectByServiceName(*ResolvedService::sAdbSecureConnectServices,
561 instance_name);
562 }
563
mdns_check()564 std::string mdns_check() {
565 uint32_t daemon_version;
566 uint32_t sz = sizeof(daemon_version);
567
568 auto dnserr = DNSServiceGetProperty(kDNSServiceProperty_DaemonVersion, &daemon_version, &sz);
569 if (dnserr != kDNSServiceErr_NoError) {
570 return "ERROR: mdns daemon unavailable";
571 }
572
573 return android::base::StringPrintf("mdns daemon version [%u]", daemon_version);
574 }
575
mdns_list_discovered_services()576 std::string mdns_list_discovered_services() {
577 std::string result;
578 auto cb = [&](const std::string& service_name, const std::string& reg_type,
579 const std::string& ip_addr, uint16_t port) {
580 result += android::base::StringPrintf("%s\t%s\t%s:%u\n", service_name.c_str(),
581 reg_type.c_str(), ip_addr.c_str(), port);
582 };
583
584 ResolvedService::ForEachService(*ResolvedService::sAdbTransportServices, "", cb);
585 ResolvedService::ForEachService(*ResolvedService::sAdbSecureConnectServices, "", cb);
586 ResolvedService::ForEachService(*ResolvedService::sAdbSecurePairingServices, "", cb);
587 return result;
588 }
589
mdns_get_connect_service_info(const std::string & name)590 std::optional<MdnsInfo> mdns_get_connect_service_info(const std::string& name) {
591 CHECK(!name.empty());
592
593 // only adb server creates these registries
594 if (!ResolvedService::sAdbTransportServices && !ResolvedService::sAdbSecureConnectServices) {
595 return std::nullopt;
596 }
597 CHECK(ResolvedService::sAdbTransportServices);
598 CHECK(ResolvedService::sAdbSecureConnectServices);
599
600 auto mdns_instance = mdns::mdns_parse_instance_name(name);
601 if (!mdns_instance.has_value()) {
602 D("Failed to parse mDNS name [%s]", name.c_str());
603 return std::nullopt;
604 }
605
606 std::optional<MdnsInfo> info;
607 auto cb = [&](const std::string& service_name, const std::string& reg_type,
608 const std::string& ip_addr,
609 uint16_t port) { info.emplace(service_name, reg_type, ip_addr, port); };
610
611 std::string reg_type;
612 if (!mdns_instance->service_name.empty()) {
613 reg_type = android::base::StringPrintf("%s.%s", mdns_instance->service_name.c_str(),
614 mdns_instance->transport_type.c_str());
615 auto index = adb_DNSServiceIndexByName(reg_type);
616 if (!index) {
617 return std::nullopt;
618 }
619 switch (*index) {
620 case kADBTransportServiceRefIndex:
621 ResolvedService::ForEachService(*ResolvedService::sAdbTransportServices,
622 mdns_instance->instance_name, cb);
623 break;
624 case kADBSecureConnectServiceRefIndex:
625 ResolvedService::ForEachService(*ResolvedService::sAdbSecureConnectServices,
626 mdns_instance->instance_name, cb);
627 break;
628 default:
629 D("Unknown reg_type [%s]", reg_type.c_str());
630 return std::nullopt;
631 }
632 return info;
633 }
634
635 for (const auto& service :
636 {ResolvedService::sAdbTransportServices, ResolvedService::sAdbSecureConnectServices}) {
637 ResolvedService::ForEachService(*service, name, cb);
638 if (info.has_value()) {
639 return info;
640 }
641 }
642
643 return std::nullopt;
644 }
645
mdns_get_pairing_service_info(const std::string & name)646 std::optional<MdnsInfo> mdns_get_pairing_service_info(const std::string& name) {
647 CHECK(!name.empty());
648
649 auto mdns_instance = mdns::mdns_parse_instance_name(name);
650 if (!mdns_instance.has_value()) {
651 D("Failed to parse mDNS pairing name [%s]", name.c_str());
652 return std::nullopt;
653 }
654
655 std::optional<MdnsInfo> info;
656 auto cb = [&](const std::string& service_name, const std::string& reg_type,
657 const std::string& ip_addr,
658 uint16_t port) { info.emplace(service_name, reg_type, ip_addr, port); };
659
660 // Verify it's a pairing service if user explicitly inputs it.
661 if (!mdns_instance->service_name.empty()) {
662 auto reg_type = android::base::StringPrintf("%s.%s", mdns_instance->service_name.c_str(),
663 mdns_instance->transport_type.c_str());
664 auto index = adb_DNSServiceIndexByName(reg_type);
665 if (!index) {
666 return std::nullopt;
667 }
668 switch (*index) {
669 case kADBSecurePairingServiceRefIndex:
670 break;
671 default:
672 D("Not an adb pairing reg_type [%s]", reg_type.c_str());
673 return std::nullopt;
674 }
675 }
676
677 ResolvedService::ForEachService(*ResolvedService::sAdbSecurePairingServices, name, cb);
678 return info;
679 }
680
mdns_cleanup()681 void mdns_cleanup() {}
682
683 } // namespace MdnsResponder
684 } // namespace
685
StartMdnsResponderDiscovery()686 AdbMdnsResponderFuncs StartMdnsResponderDiscovery() {
687 ResolvedService::InitAdbServiceRegistries();
688 std::thread(init_mdns_transport_discovery_thread).detach();
689 AdbMdnsResponderFuncs f = {
690 .mdns_check = MdnsResponder::mdns_check,
691 .mdns_list_discovered_services = MdnsResponder::mdns_list_discovered_services,
692 .mdns_get_connect_service_info = MdnsResponder::mdns_get_connect_service_info,
693 .mdns_get_pairing_service_info = MdnsResponder::mdns_get_pairing_service_info,
694 .mdns_cleanup = MdnsResponder::mdns_cleanup,
695 .adb_secure_connect_by_service_name = MdnsResponder::adb_secure_connect_by_service_name,
696 };
697 return f;
698 }
699