diff --git a/adb/client/transport_mdns.cpp b/adb/client/transport_mdns.cpp index 20fa09efa..ebef711bd 100644 --- a/adb/client/transport_mdns.cpp +++ b/adb/client/transport_mdns.cpp @@ -35,7 +35,21 @@ #include "sysdeps.h" static DNSServiceRef service_refs[kNumADBDNSServices]; -static fdevent* service_ref_fde; +static fdevent* service_ref_fdes[kNumADBDNSServices]; + +static int adb_DNSServiceIndexByName(const char* regType) { + for (int i = 0; i < kNumADBDNSServices; ++i) { + if (!strncmp(regType, kADBDNSServices[i], strlen(kADBDNSServices[i]))) { + return i; + } + } + return -1; +} + +static bool adb_DNSServiceShouldConnect(const char* regType) { + int index = adb_DNSServiceIndexByName(regType); + return index == kADBTransportServiceRefIndex; +} // Use adb_DNSServiceRefSockFD() instead of calling DNSServiceRefSockFD() // directly so that the socket is put through the appropriate compatibility @@ -94,10 +108,15 @@ class ResolvedService : public AsyncServiceRef { public: virtual ~ResolvedService() = default; - ResolvedService(std::string name, uint32_t interfaceIndex, - const char* hosttarget, uint16_t port) : - name_(name), - port_(port) { + ResolvedService(std::string serviceName, std::string regType, uint32_t interfaceIndex, + const char* hosttarget, uint16_t port) + : serviceName_(serviceName), + regType_(regType), + hosttarget_(hosttarget), + port_(port), + sa_family_(0), + ip_addr_data_(NULL) { + memset(ip_addr_, 0, sizeof(ip_addr_)); /* TODO: We should be able to get IPv6 support by adding * kDNSServiceProtocol_IPv6 to the flags below. However, when we do @@ -119,40 +138,47 @@ class ResolvedService : public AsyncServiceRef { } void Connect(const sockaddr* address) { - char ip_addr[INET6_ADDRSTRLEN]; - const void* ip_addr_data; + sa_family_ = address->sa_family; const char* addr_format; - if (address->sa_family == AF_INET) { - ip_addr_data = - &reinterpret_cast(address)->sin_addr; + if (sa_family_ == AF_INET) { + ip_addr_data_ = &reinterpret_cast(address)->sin_addr; addr_format = "%s:%hu"; - } else if (address->sa_family == AF_INET6) { - ip_addr_data = - &reinterpret_cast(address)->sin6_addr; + } else if (sa_family_ == AF_INET6) { + ip_addr_data_ = &reinterpret_cast(address)->sin6_addr; addr_format = "[%s]:%hu"; - } else { // Should be impossible + } else { // Should be impossible D("mDNS resolved non-IP address."); return; } // Winsock version requires the const cast Because Microsoft. - if (!inet_ntop(address->sa_family, const_cast(ip_addr_data), - ip_addr, INET6_ADDRSTRLEN)) { + if (!inet_ntop(sa_family_, const_cast(ip_addr_data_), ip_addr_, sizeof(ip_addr_))) { D("Could not convert IP address to string."); return; } - std::string response; - connect_device(android::base::StringPrintf(addr_format, ip_addr, port_), - &response); - D("Connect to %s (%s:%hu) : %s", name_.c_str(), ip_addr, port_, - response.c_str()); + // adb secure service needs to do something different from just + // connecting here. + if (adb_DNSServiceShouldConnect(regType_.c_str())) { + std::string response; + connect_device(android::base::StringPrintf(addr_format, ip_addr_, port_), &response); + D("Connect to %s (%s:%hu) : %s", serviceName_.c_str(), ip_addr_, port_, + response.c_str()); + } else { + D("Not immediately connecting to serviceName=[%s], regtype=[%s] ipaddr=(%s:%hu)", + serviceName_.c_str(), regType_.c_str(), ip_addr_, port_); + } } private: - std::string name_; + std::string serviceName_; + std::string regType_; + std::string hosttarget_; const uint16_t port_; + int sa_family_; + const void* ip_addr_data_; + char ip_addr_[INET6_ADDRSTRLEN]; }; static void DNSSD_API register_service_ip(DNSServiceRef /*sdRef*/, @@ -182,18 +208,23 @@ static void DNSSD_API register_resolved_mdns_service(DNSServiceRef sdRef, class DiscoveredService : public AsyncServiceRef { public: - DiscoveredService(uint32_t interfaceIndex, const char* serviceName, - const char* regtype, const char* domain) - : serviceName_(serviceName) { - + DiscoveredService(uint32_t interfaceIndex, const char* serviceName, const char* regtype, + const char* domain) + : serviceName_(serviceName), regType_(regtype) { DNSServiceErrorType ret = DNSServiceResolve(&sdRef_, 0, interfaceIndex, serviceName, regtype, domain, register_resolved_mdns_service, reinterpret_cast(this)); - if (ret != kDNSServiceErr_NoError) { - D("Got %d from DNSServiceResolve.", ret); - } else { + D("DNSServiceResolve for " + "interfaceIndex %u " + "serviceName %s " + "regtype %s " + "domain %s " + ": %d", + interfaceIndex, serviceName, regtype, domain, ret); + + if (ret == kDNSServiceErr_NoError) { Initialize(); } } @@ -202,8 +233,11 @@ class DiscoveredService : public AsyncServiceRef { return serviceName_.c_str(); } + const char* RegType() { return regType_.c_str(); } + private: std::string serviceName_; + std::string regType_; }; static void DNSSD_API register_resolved_mdns_service(DNSServiceRef sdRef, @@ -225,10 +259,8 @@ static void DNSSD_API register_resolved_mdns_service(DNSServiceRef sdRef, return; } - - auto resolved = - new ResolvedService(discovered->ServiceName(), - interfaceIndex, hosttarget, ntohs(port)); + auto resolved = new ResolvedService(discovered->ServiceName(), discovered->RegType(), + interfaceIndex, hosttarget, ntohs(port)); if (! resolved->Initialized()) { delete resolved; @@ -247,7 +279,10 @@ static void DNSSD_API on_service_browsed(DNSServiceRef sdRef, DNSServiceFlags fl if (errorCode != kDNSServiceErr_NoError) { D("Got error %d during mDNS browse.", errorCode); DNSServiceRefDeallocate(sdRef); - fdevent_destroy(service_ref_fde); + int serviceIndex = adb_DNSServiceIndexByName(regtype); + if (serviceIndex != -1) { + fdevent_destroy(service_ref_fdes[serviceIndex]); + } return; } @@ -267,15 +302,14 @@ void init_mdns_transport_discovery_thread(void) { if (errorCodes[i] != kDNSServiceErr_NoError) { D("Got %d browsing for mDNS service %s.", errorCodes[i], kADBDNSServices[i]); } - } - if (errorCodes[kADBTransportServiceRefIndex] == kDNSServiceErr_NoError) { - fdevent_run_on_main_thread([]() { - service_ref_fde = fdevent_create( - adb_DNSServiceRefSockFD(service_refs[kADBTransportServiceRefIndex]), - pump_service_ref, &service_refs[kADBTransportServiceRefIndex]); - fdevent_set(service_ref_fde, FDE_READ); - }); + if (errorCodes[i] == kDNSServiceErr_NoError) { + fdevent_run_on_main_thread([i]() { + service_ref_fdes[i] = fdevent_create(adb_DNSServiceRefSockFD(service_refs[i]), + pump_service_ref, &service_refs[i]); + fdevent_set(service_ref_fdes[i], FDE_READ); + }); + } } }