Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4b62bcde authored by Lingfeng Yang's avatar Lingfeng Yang Committed by Joshua Duong
Browse files

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
parent c712f2db
Loading
Loading
Loading
Loading
+76 −42
Original line number Original line Diff line number Diff line
@@ -35,7 +35,21 @@
#include "sysdeps.h"
#include "sysdeps.h"


static DNSServiceRef service_refs[kNumADBDNSServices];
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()
// Use adb_DNSServiceRefSockFD() instead of calling DNSServiceRefSockFD()
// directly so that the socket is put through the appropriate compatibility
// directly so that the socket is put through the appropriate compatibility
@@ -94,10 +108,15 @@ class ResolvedService : public AsyncServiceRef {
  public:
  public:
    virtual ~ResolvedService() = default;
    virtual ~ResolvedService() = default;


    ResolvedService(std::string name, uint32_t interfaceIndex,
    ResolvedService(std::string serviceName, std::string regType, uint32_t interfaceIndex,
                    const char* hosttarget, uint16_t port) :
                    const char* hosttarget, uint16_t port)
            name_(name),
        : serviceName_(serviceName),
            port_(port) {
          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
        /* TODO: We should be able to get IPv6 support by adding
         * kDNSServiceProtocol_IPv6 to the flags below. However, when we do
         * kDNSServiceProtocol_IPv6 to the flags below. However, when we do
@@ -119,17 +138,14 @@ class ResolvedService : public AsyncServiceRef {
    }
    }


    void Connect(const sockaddr* address) {
    void Connect(const sockaddr* address) {
        char ip_addr[INET6_ADDRSTRLEN];
        sa_family_ = address->sa_family;
        const void* ip_addr_data;
        const char* addr_format;
        const char* addr_format;


        if (address->sa_family == AF_INET) {
        if (sa_family_ == AF_INET) {
            ip_addr_data =
            ip_addr_data_ = &reinterpret_cast<const sockaddr_in*>(address)->sin_addr;
                &reinterpret_cast<const sockaddr_in*>(address)->sin_addr;
            addr_format = "%s:%hu";
            addr_format = "%s:%hu";
        } else if (address->sa_family == AF_INET6) {
        } else if (sa_family_ == AF_INET6) {
            ip_addr_data =
            ip_addr_data_ = &reinterpret_cast<const sockaddr_in6*>(address)->sin6_addr;
                &reinterpret_cast<const sockaddr_in6*>(address)->sin6_addr;
            addr_format = "[%s]:%hu";
            addr_format = "[%s]:%hu";
        } else {  // Should be impossible
        } else {  // Should be impossible
            D("mDNS resolved non-IP address.");
            D("mDNS resolved non-IP address.");
@@ -137,22 +153,32 @@ class ResolvedService : public AsyncServiceRef {
        }
        }


        // Winsock version requires the const cast Because Microsoft.
        // Winsock version requires the const cast Because Microsoft.
        if (!inet_ntop(address->sa_family, const_cast<void*>(ip_addr_data),
        if (!inet_ntop(sa_family_, const_cast<void*>(ip_addr_data_), ip_addr_, sizeof(ip_addr_))) {
                       ip_addr, INET6_ADDRSTRLEN)) {
            D("Could not convert IP address to string.");
            D("Could not convert IP address to string.");
            return;
            return;
        }
        }


        // adb secure service needs to do something different from just
        // connecting here.
        if (adb_DNSServiceShouldConnect(regType_.c_str())) {
            std::string response;
            std::string response;
        connect_device(android::base::StringPrintf(addr_format, ip_addr, port_),
            connect_device(android::base::StringPrintf(addr_format, ip_addr_, port_), &response);
                       &response);
            D("Connect to %s (%s:%hu) : %s", serviceName_.c_str(), ip_addr_, port_,
        D("Connect to %s (%s:%hu) : %s", name_.c_str(), ip_addr, port_,
              response.c_str());
              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:
  private:
    std::string name_;
    std::string serviceName_;
    std::string regType_;
    std::string hosttarget_;
    const uint16_t port_;
    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*/,
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 {
class DiscoveredService : public AsyncServiceRef {
  public:
  public:
    DiscoveredService(uint32_t interfaceIndex, const char* serviceName,
    DiscoveredService(uint32_t interfaceIndex, const char* serviceName, const char* regtype,
                      const char* regtype, const char* domain)
                      const char* domain)
        : serviceName_(serviceName) {
        : serviceName_(serviceName), regType_(regtype) {

        DNSServiceErrorType ret =
        DNSServiceErrorType ret =
            DNSServiceResolve(&sdRef_, 0, interfaceIndex, serviceName, regtype,
            DNSServiceResolve(&sdRef_, 0, interfaceIndex, serviceName, regtype,
                              domain, register_resolved_mdns_service,
                              domain, register_resolved_mdns_service,
                              reinterpret_cast<void*>(this));
                              reinterpret_cast<void*>(this));


        if (ret != kDNSServiceErr_NoError) {
        D("DNSServiceResolve for "
            D("Got %d from DNSServiceResolve.", ret);
          "interfaceIndex %u "
        } else {
          "serviceName %s "
          "regtype %s "
          "domain %s "
          ": %d",
          interfaceIndex, serviceName, regtype, domain, ret);

        if (ret == kDNSServiceErr_NoError) {
            Initialize();
            Initialize();
        }
        }
    }
    }
@@ -202,8 +233,11 @@ class DiscoveredService : public AsyncServiceRef {
        return serviceName_.c_str();
        return serviceName_.c_str();
    }
    }


    const char* RegType() { return regType_.c_str(); }

  private:
  private:
    std::string serviceName_;
    std::string serviceName_;
    std::string regType_;
};
};


static void DNSSD_API register_resolved_mdns_service(DNSServiceRef sdRef,
static void DNSSD_API register_resolved_mdns_service(DNSServiceRef sdRef,
@@ -225,9 +259,7 @@ static void DNSSD_API register_resolved_mdns_service(DNSServiceRef sdRef,
        return;
        return;
    }
    }



    auto resolved = new ResolvedService(discovered->ServiceName(), discovered->RegType(),
    auto resolved =
        new ResolvedService(discovered->ServiceName(),
                                        interfaceIndex, hosttarget, ntohs(port));
                                        interfaceIndex, hosttarget, ntohs(port));


    if (! resolved->Initialized()) {
    if (! resolved->Initialized()) {
@@ -247,7 +279,10 @@ static void DNSSD_API on_service_browsed(DNSServiceRef sdRef, DNSServiceFlags fl
    if (errorCode != kDNSServiceErr_NoError) {
    if (errorCode != kDNSServiceErr_NoError) {
        D("Got error %d during mDNS browse.", errorCode);
        D("Got error %d during mDNS browse.", errorCode);
        DNSServiceRefDeallocate(sdRef);
        DNSServiceRefDeallocate(sdRef);
        fdevent_destroy(service_ref_fde);
        int serviceIndex = adb_DNSServiceIndexByName(regtype);
        if (serviceIndex != -1) {
            fdevent_destroy(service_ref_fdes[serviceIndex]);
        }
        return;
        return;
    }
    }


@@ -267,17 +302,16 @@ void init_mdns_transport_discovery_thread(void) {
        if (errorCodes[i] != kDNSServiceErr_NoError) {
        if (errorCodes[i] != kDNSServiceErr_NoError) {
            D("Got %d browsing for mDNS service %s.", errorCodes[i], kADBDNSServices[i]);
            D("Got %d browsing for mDNS service %s.", errorCodes[i], kADBDNSServices[i]);
        }
        }
    }


    if (errorCodes[kADBTransportServiceRefIndex] == kDNSServiceErr_NoError) {
        if (errorCodes[i] == kDNSServiceErr_NoError) {
        fdevent_run_on_main_thread([]() {
            fdevent_run_on_main_thread([i]() {
            service_ref_fde = fdevent_create(
                service_ref_fdes[i] = fdevent_create(adb_DNSServiceRefSockFD(service_refs[i]),
                    adb_DNSServiceRefSockFD(service_refs[kADBTransportServiceRefIndex]),
                                                     pump_service_ref, &service_refs[i]);
                    pump_service_ref, &service_refs[kADBTransportServiceRefIndex]);
                fdevent_set(service_ref_fdes[i], FDE_READ);
            fdevent_set(service_ref_fde, FDE_READ);
            });
            });
        }
        }
    }
    }
}


void init_mdns_transport_discovery(void) {
void init_mdns_transport_discovery(void) {
    std::thread(init_mdns_transport_discovery_thread).detach();
    std::thread(init_mdns_transport_discovery_thread).detach();