get the ip address info for all DNS services

This CL adds functionality to the class ResolvedService where the ip
address associated with a resolved DNS service is recorded.

It also avoids connecting to the device unless it is the Things-related
DNS service.

Next step is to add some kind of interface in other parts of adb code
to retrieve these IP addresses.

Bug: 111434128, 119490749

Test: N/A
Exempt-From-Owner-Approval: already approved
Change-Id: I46895a7a5bf5660f524c7323a9454f1e2c7d385c
diff --git a/adb/client/transport_mdns.cpp b/adb/client/transport_mdns.cpp
index 20fa09e..ebef711 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 @@
   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 @@
     }
 
     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<const sockaddr_in*>(address)->sin_addr;
+        if (sa_family_ == AF_INET) {
+            ip_addr_data_ = &reinterpret_cast<const sockaddr_in*>(address)->sin_addr;
             addr_format = "%s:%hu";
-        } else if (address->sa_family == AF_INET6) {
-            ip_addr_data =
-                &reinterpret_cast<const sockaddr_in6*>(address)->sin6_addr;
+        } else if (sa_family_ == AF_INET6) {
+            ip_addr_data_ = &reinterpret_cast<const sockaddr_in6*>(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<void*>(ip_addr_data),
-                       ip_addr, INET6_ADDRSTRLEN)) {
+        if (!inet_ntop(sa_family_, const_cast<void*>(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 @@
 
 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<void*>(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 @@
         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 @@
         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 @@
     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 @@
         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);
+            });
+        }
     }
 }