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", ADB_SECURE_CLIENT_VERSION, 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
service_name() const240 const std::string& service_name() const { return service_name_; }
241
reg_type() const242 const std::string& reg_type() const { return reg_type_; }
243
ip_address() const244 const std::string& ip_address() const { return ip_addr_; }
245
port() const246 uint16_t port() const { return port_; }
247
248 using ServiceRegistry = std::vector<std::unique_ptr<ResolvedService>>;
249
250 // unencrypted tcp connections
251 static ServiceRegistry* sAdbTransportServices;
252
253 static ServiceRegistry* sAdbSecurePairingServices;
254 static ServiceRegistry* sAdbSecureConnectServices;
255
256 static void InitAdbServiceRegistries();
257
258 static void ForEachService(const ServiceRegistry& services, const std::string& hostname,
259 adb_secure_foreach_service_callback cb);
260
261 static bool ConnectByServiceName(const ServiceRegistry& services,
262 const std::string& service_name);
263
264 static void RemoveDNSService(const std::string& reg_type, const std::string& service_name);
265
266 private:
267 std::string addr_format_;
268 std::string service_name_;
269 std::string reg_type_;
270 std::string host_target_;
271 const uint16_t port_;
272 int sa_family_;
273 std::string ip_addr_;
274 int service_version_;
275 };
276
277 // static
278 ResolvedService::ServiceRegistry* ResolvedService::sAdbTransportServices = NULL;
279
280 // static
281 ResolvedService::ServiceRegistry* ResolvedService::sAdbSecurePairingServices = NULL;
282
283 // static
284 ResolvedService::ServiceRegistry* ResolvedService::sAdbSecureConnectServices = NULL;
285
286 // static
InitAdbServiceRegistries()287 void ResolvedService::InitAdbServiceRegistries() {
288 if (!sAdbTransportServices) {
289 sAdbTransportServices = new ServiceRegistry;
290 }
291 if (!sAdbSecurePairingServices) {
292 sAdbSecurePairingServices = new ServiceRegistry;
293 }
294 if (!sAdbSecureConnectServices) {
295 sAdbSecureConnectServices = new ServiceRegistry;
296 }
297 }
298
299 // static
ForEachService(const ServiceRegistry & services,const std::string & wanted_service_name,adb_secure_foreach_service_callback cb)300 void ResolvedService::ForEachService(const ServiceRegistry& services,
301 const std::string& wanted_service_name,
302 adb_secure_foreach_service_callback cb) {
303 InitAdbServiceRegistries();
304
305 for (const auto& service : services) {
306 auto service_name = service->service_name();
307 auto reg_type = service->reg_type();
308 auto ip = service->ip_address();
309 auto port = service->port();
310
311 if (wanted_service_name.empty()) {
312 cb(service_name.c_str(), reg_type.c_str(), ip.c_str(), port);
313 } else if (service_name == wanted_service_name) {
314 cb(service_name.c_str(), reg_type.c_str(), ip.c_str(), port);
315 }
316 }
317 }
318
319 // static
ConnectByServiceName(const ServiceRegistry & services,const std::string & service_name)320 bool ResolvedService::ConnectByServiceName(const ServiceRegistry& services,
321 const std::string& service_name) {
322 InitAdbServiceRegistries();
323 for (const auto& service : services) {
324 auto wanted_name = service->service_name();
325 if (wanted_name == service_name) {
326 D("Got service_name match [%s]", wanted_name.c_str());
327 return service->ConnectSecureWifiDevice();
328 }
329 }
330 D("No registered service_names matched [%s]", service_name.c_str());
331 return false;
332 }
333
334 // static
RemoveDNSService(const std::string & reg_type,const std::string & service_name)335 void ResolvedService::RemoveDNSService(const std::string& reg_type,
336 const std::string& service_name) {
337 D("%s: reg_type=[%s] service_name=[%s]", __func__, reg_type.c_str(), service_name.c_str());
338 auto index = adb_DNSServiceIndexByName(reg_type);
339 if (!index) {
340 return;
341 }
342 ServiceRegistry* services;
343 switch (*index) {
344 case kADBTransportServiceRefIndex:
345 services = sAdbTransportServices;
346 break;
347 case kADBSecurePairingServiceRefIndex:
348 services = sAdbSecurePairingServices;
349 break;
350 case kADBSecureConnectServiceRefIndex:
351 services = sAdbSecureConnectServices;
352 break;
353 default:
354 return;
355 }
356
357 if (services->empty()) {
358 return;
359 }
360
361 services->erase(std::remove_if(services->begin(), services->end(),
362 [&service_name](std::unique_ptr<ResolvedService>& service) {
363 return (service_name == service->service_name());
364 }),
365 services->end());
366 }
367
register_service_ip(DNSServiceRef sdref,DNSServiceFlags flags,uint32_t,DNSServiceErrorType error_code,const char * hostname,const sockaddr * address,uint32_t ttl,void * context)368 void DNSSD_API register_service_ip(DNSServiceRef sdref, DNSServiceFlags flags,
369 uint32_t /*interface_index*/, DNSServiceErrorType error_code,
370 const char* hostname, const sockaddr* address, uint32_t ttl,
371 void* context) {
372 D("%s: sdref=%p flags=0x%08x error_code=%u ttl=%u", __func__, sdref, flags, error_code, ttl);
373 std::unique_ptr<ResolvedService> data(static_cast<ResolvedService*>(context));
374 // Only resolve the address once. If the address or port changes, we'll just get another
375 // registration.
376 data->DestroyServiceRef();
377
378 if (error_code != kDNSServiceErr_NoError) {
379 D("Got error while looking up ip_addr [%u]", error_code);
380 return;
381 }
382
383 if (flags & kDNSServiceFlagsAdd) {
384 if (data->RegisterIpAddress(address)) {
385 D("Resolved IP address for [%s]. Adding to service registry.", hostname);
386 ResolvedService::AddToServiceRegistry(std::move(data));
387 }
388 }
389 }
390
391 void DNSSD_API register_resolved_mdns_service(DNSServiceRef sdref, DNSServiceFlags flags,
392 uint32_t interface_index,
393 DNSServiceErrorType error_code, const char* fullname,
394 const char* host_target, uint16_t port,
395 uint16_t txt_len, const unsigned char* txt_record,
396 void* context);
397
398 class DiscoveredService : public AsyncServiceRef {
399 public:
DiscoveredService(uint32_t interface_index,const char * service_name,const char * regtype,const char * domain)400 DiscoveredService(uint32_t interface_index, const char* service_name, const char* regtype,
401 const char* domain)
402 : service_name_(service_name), reg_type_(regtype) {
403 DNSServiceErrorType ret =
404 DNSServiceResolve(&sdref_, 0, interface_index, service_name, regtype, domain,
405 register_resolved_mdns_service, reinterpret_cast<void*>(this));
406
407 D("DNSServiceResolve for "
408 "interface_index %u "
409 "service_name %s "
410 "regtype %s "
411 "domain %s "
412 ": %d",
413 interface_index, service_name, regtype, domain, ret);
414
415 if (ret == kDNSServiceErr_NoError) {
416 Initialize();
417 }
418 }
419
service_name()420 const std::string& service_name() { return service_name_; }
421
reg_type()422 const std::string& reg_type() { return reg_type_; }
423
424 private:
425 std::string service_name_;
426 std::string reg_type_;
427 };
428
429 // Returns the version the device wanted to advertise,
430 // or -1 if parsing fails.
ParseVersionFromTxtRecord(uint16_t txt_len,const unsigned char * txt_record)431 int ParseVersionFromTxtRecord(uint16_t txt_len, const unsigned char* txt_record) {
432 if (!txt_len) return -1;
433 if (!txt_record) return -1;
434
435 // https://tools.ietf.org/html/rfc6763
436 // """
437 // 6.1. General Format Rules for DNS TXT Records
438 //
439 // A DNS TXT record can be up to 65535 (0xFFFF) bytes long. The total
440 // length is indicated by the length given in the resource record header
441 // in the DNS message. There is no way to tell directly from the data
442 // alone how long it is (e.g., there is no length count at the start, or
443 // terminating NULL byte at the end).
444 //
445 // The format of the data within a DNS TXT record is zero or more strings,
446 // packed together in memory without any intervening gaps or padding bytes
447 // for word alignment. The format of each constituent string within the DNS
448 // TXT record is a single length byte, followed by 0-255 bytes of text data.
449 // """
450
451 // We only parse the first string in the record.
452 // Let's not trust the length byte (txt_record[0]).
453 // Worst case, it wastes 65,535 bytes.
454 std::vector<char> record_str(txt_len + 1, '\0');
455 char* str = record_str.data();
456
457 memcpy(str, txt_record + 1 /* skip the length byte */, txt_len - 1);
458
459 // Check if it's the version key
460 static const char* version_key = "v=";
461 size_t version_key_len = strlen(version_key);
462
463 if (strncmp(version_key, str, version_key_len)) return -1;
464
465 auto value_start = str + version_key_len;
466
467 long parsed_number = strtol(value_start, 0, 10);
468
469 // No valid conversion. Also, 0
470 // is not a valid version.
471 if (!parsed_number) return -1;
472
473 // Outside bounds of int.
474 if (parsed_number < INT_MIN || parsed_number > INT_MAX) return -1;
475
476 // Possibly valid version
477 return static_cast<int>(parsed_number);
478 }
479
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)480 void DNSSD_API register_resolved_mdns_service(DNSServiceRef sdref, DNSServiceFlags flags,
481 uint32_t interface_index,
482 DNSServiceErrorType error_code, const char* fullname,
483 const char* host_target, uint16_t port,
484 uint16_t txt_len, const unsigned char* txt_record,
485 void* context) {
486 D("Resolved a service.");
487 std::unique_ptr<DiscoveredService> discovered(reinterpret_cast<DiscoveredService*>(context));
488
489 if (error_code != kDNSServiceErr_NoError) {
490 D("Got error %d resolving service.", error_code);
491 return;
492 }
493
494 // TODO: Reject certain combinations of invalid or mismatched client and
495 // service versions here before creating anything.
496 // At the moment, there is nothing to reject, so accept everything
497 // as an optimistic default.
498 auto service_version = ParseVersionFromTxtRecord(txt_len, txt_record);
499
500 auto resolved = new ResolvedService(discovered->service_name(), discovered->reg_type(),
501 interface_index, host_target, ntohs(port), service_version);
502
503 if (!resolved->Initialized()) {
504 D("Unable to init resolved service");
505 delete resolved;
506 }
507
508 if (flags) { /* Only ever equals MoreComing or 0 */
509 D("releasing discovered service");
510 discovered.release();
511 }
512 }
513
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 *)514 void DNSSD_API on_service_browsed(DNSServiceRef sdref, DNSServiceFlags flags,
515 uint32_t interface_index, DNSServiceErrorType error_code,
516 const char* service_name, const char* regtype, const char* domain,
517 void* /*context*/) {
518 if (error_code != kDNSServiceErr_NoError) {
519 D("Got error %d during mDNS browse.", error_code);
520 DNSServiceRefDeallocate(sdref);
521 auto service_index = adb_DNSServiceIndexByName(regtype);
522 if (service_index) {
523 fdevent_destroy(g_service_ref_fdes[*service_index]);
524 }
525 return;
526 }
527
528 if (flags & kDNSServiceFlagsAdd) {
529 D("%s: Discover found new service_name=[%s] regtype=[%s] domain=[%s]", __func__,
530 service_name, regtype, domain);
531 auto discovered = new DiscoveredService(interface_index, service_name, regtype, domain);
532 if (!discovered->Initialized()) {
533 delete discovered;
534 }
535 } else {
536 D("%s: Discover lost service_name=[%s] regtype=[%s] domain=[%s]", __func__, service_name,
537 regtype, domain);
538 ResolvedService::RemoveDNSService(regtype, service_name);
539 }
540 }
541
init_mdns_transport_discovery_thread(void)542 void init_mdns_transport_discovery_thread(void) {
543 int error_codes[kNumADBDNSServices];
544 for (int i = 0; i < kNumADBDNSServices; ++i) {
545 error_codes[i] = DNSServiceBrowse(&g_service_refs[i], 0, 0, kADBDNSServices[i], nullptr,
546 on_service_browsed, nullptr);
547
548 if (error_codes[i] != kDNSServiceErr_NoError) {
549 D("Got %d browsing for mDNS service %s.", error_codes[i], kADBDNSServices[i]);
550 } else {
551 fdevent_run_on_looper([i]() {
552 g_service_ref_fdes[i] = fdevent_create(adb_DNSServiceRefSockFD(g_service_refs[i]),
553 pump_service_ref, &g_service_refs[i]);
554 fdevent_set(g_service_ref_fdes[i], FDE_READ);
555 });
556 }
557 }
558 }
559
560 namespace MdnsResponder {
561
adb_secure_connect_by_service_name(const std::string & instance_name)562 bool adb_secure_connect_by_service_name(const std::string& instance_name) {
563 return ResolvedService::ConnectByServiceName(*ResolvedService::sAdbSecureConnectServices,
564 instance_name);
565 }
566
mdns_check()567 std::string mdns_check() {
568 uint32_t daemon_version;
569 uint32_t sz = sizeof(daemon_version);
570
571 auto dnserr = DNSServiceGetProperty(kDNSServiceProperty_DaemonVersion, &daemon_version, &sz);
572 if (dnserr != kDNSServiceErr_NoError) {
573 return "ERROR: mdns daemon unavailable";
574 }
575
576 return android::base::StringPrintf("mdns daemon version [%u]", daemon_version);
577 }
578
mdns_list_discovered_services()579 std::string mdns_list_discovered_services() {
580 std::string result;
581 auto cb = [&](const std::string& service_name, const std::string& reg_type,
582 const std::string& ip_addr, uint16_t port) {
583 result += android::base::StringPrintf("%s\t%s\t%s:%u\n", service_name.c_str(),
584 reg_type.c_str(), ip_addr.c_str(), port);
585 };
586
587 ResolvedService::ForEachService(*ResolvedService::sAdbTransportServices, "", cb);
588 ResolvedService::ForEachService(*ResolvedService::sAdbSecureConnectServices, "", cb);
589 ResolvedService::ForEachService(*ResolvedService::sAdbSecurePairingServices, "", cb);
590 return result;
591 }
592
mdns_get_connect_service_info(const std::string & name)593 std::optional<MdnsInfo> mdns_get_connect_service_info(const std::string& name) {
594 CHECK(!name.empty());
595
596 // only adb server creates these registries
597 if (!ResolvedService::sAdbTransportServices && !ResolvedService::sAdbSecureConnectServices) {
598 return std::nullopt;
599 }
600 CHECK(ResolvedService::sAdbTransportServices);
601 CHECK(ResolvedService::sAdbSecureConnectServices);
602
603 auto mdns_instance = mdns::mdns_parse_instance_name(name);
604 if (!mdns_instance.has_value()) {
605 D("Failed to parse mDNS name [%s]", name.c_str());
606 return std::nullopt;
607 }
608
609 std::optional<MdnsInfo> info;
610 auto cb = [&](const std::string& service_name, const std::string& reg_type,
611 const std::string& ip_addr,
612 uint16_t port) { info.emplace(service_name, reg_type, ip_addr, port); };
613
614 std::string reg_type;
615 if (!mdns_instance->service_name.empty()) {
616 reg_type = android::base::StringPrintf("%s.%s", mdns_instance->service_name.c_str(),
617 mdns_instance->transport_type.c_str());
618 auto index = adb_DNSServiceIndexByName(reg_type);
619 if (!index) {
620 return std::nullopt;
621 }
622 switch (*index) {
623 case kADBTransportServiceRefIndex:
624 ResolvedService::ForEachService(*ResolvedService::sAdbTransportServices,
625 mdns_instance->instance_name, cb);
626 break;
627 case kADBSecureConnectServiceRefIndex:
628 ResolvedService::ForEachService(*ResolvedService::sAdbSecureConnectServices,
629 mdns_instance->instance_name, cb);
630 break;
631 default:
632 D("Unknown reg_type [%s]", reg_type.c_str());
633 return std::nullopt;
634 }
635 return info;
636 }
637
638 for (const auto& service :
639 {ResolvedService::sAdbTransportServices, ResolvedService::sAdbSecureConnectServices}) {
640 ResolvedService::ForEachService(*service, name, cb);
641 if (info.has_value()) {
642 return info;
643 }
644 }
645
646 return std::nullopt;
647 }
648
mdns_get_pairing_service_info(const std::string & name)649 std::optional<MdnsInfo> mdns_get_pairing_service_info(const std::string& name) {
650 CHECK(!name.empty());
651
652 auto mdns_instance = mdns::mdns_parse_instance_name(name);
653 if (!mdns_instance.has_value()) {
654 D("Failed to parse mDNS pairing name [%s]", name.c_str());
655 return std::nullopt;
656 }
657
658 std::optional<MdnsInfo> info;
659 auto cb = [&](const std::string& service_name, const std::string& reg_type,
660 const std::string& ip_addr,
661 uint16_t port) { info.emplace(service_name, reg_type, ip_addr, port); };
662
663 // Verify it's a pairing service if user explicitly inputs it.
664 if (!mdns_instance->service_name.empty()) {
665 auto reg_type = android::base::StringPrintf("%s.%s", mdns_instance->service_name.c_str(),
666 mdns_instance->transport_type.c_str());
667 auto index = adb_DNSServiceIndexByName(reg_type);
668 if (!index) {
669 return std::nullopt;
670 }
671 switch (*index) {
672 case kADBSecurePairingServiceRefIndex:
673 break;
674 default:
675 D("Not an adb pairing reg_type [%s]", reg_type.c_str());
676 return std::nullopt;
677 }
678 }
679
680 ResolvedService::ForEachService(*ResolvedService::sAdbSecurePairingServices, name, cb);
681 return info;
682 }
683
mdns_cleanup()684 void mdns_cleanup() {}
685
686 } // namespace MdnsResponder
687 } // namespace
688
StartMdnsResponderDiscovery()689 AdbMdnsResponderFuncs StartMdnsResponderDiscovery() {
690 ResolvedService::InitAdbServiceRegistries();
691 std::thread(init_mdns_transport_discovery_thread).detach();
692 AdbMdnsResponderFuncs f = {
693 .mdns_check = MdnsResponder::mdns_check,
694 .mdns_list_discovered_services = MdnsResponder::mdns_list_discovered_services,
695 .mdns_get_connect_service_info = MdnsResponder::mdns_get_connect_service_info,
696 .mdns_get_pairing_service_info = MdnsResponder::mdns_get_pairing_service_info,
697 .mdns_cleanup = MdnsResponder::mdns_cleanup,
698 .adb_secure_connect_by_service_name = MdnsResponder::adb_secure_connect_by_service_name,
699 };
700 return f;
701 }
702