static bool lookupAddrForIface()

in gloo/transport/uv/device.cc [61:158]


static bool lookupAddrForIface(struct attr* attr) {
  InterfaceAddresses addresses;

  for (auto i = 0; i < addresses.size(); i++) {
#ifdef _WIN32
    const auto& address = addresses[i].address;
#else
    const auto& interface = addresses[i];
    const auto& address = interface.address;
#endif

    // Skip entry if the name doesn't match.
#ifdef _WIN32
    if (strcmp(attr->iface.c_str(), addresses[i].name) != 0) {
#else
    if (strcmp(attr->iface.c_str(), interface.name) != 0) {
#endif
      continue;
    }

    // Match on address family
    struct sockaddr* sockaddr = (struct sockaddr*)&address.address4;
    switch (sockaddr->sa_family) {
      case AF_INET:
        if (attr->ai_family != AF_INET && attr->ai_family != AF_UNSPEC) {
          continue;
        }
        attr->ai_addrlen = sizeof(address.address4);
        memcpy(&attr->ai_addr, &address.address4, sizeof(address.address4));
        break;
      case AF_INET6:
        if (attr->ai_family != AF_INET6 && attr->ai_family != AF_UNSPEC) {
          continue;
        }
        attr->ai_addrlen = sizeof(address.address6);
        memcpy(&attr->ai_addr, &address.address6, sizeof(address.address6));
        break;
      default:
        continue;
    }

    attr->ai_socktype = SOCK_STREAM;
    attr->ai_protocol = 0;
    return true;
  }

  return false;
}

static void lookupAddrForHostname(struct attr& attr) {
#ifdef _WIN32
  init_winsock();
#endif

  struct addrinfo hints;
  memset(&hints, 0, sizeof(hints));
  hints.ai_family = attr.ai_family;
  hints.ai_socktype = SOCK_STREAM;
  struct addrinfo* result;
  auto rv = getaddrinfo(attr.hostname.data(), nullptr, &hints, &result);
  GLOO_ENFORCE_NE(rv, -1);
  struct addrinfo* rp;
  for (rp = result; rp != nullptr; rp = rp->ai_next) {
    auto fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
    if (fd == -1) {
      continue;
    }

    rv = bind(fd, rp->ai_addr, rp->ai_addrlen);
    if (rv == -1) {
#ifdef _WIN32
      closesocket(fd);
#else
      close(fd);
#endif
      continue;
    }

    attr.ai_family = rp->ai_family;
    attr.ai_socktype = rp->ai_socktype;
    attr.ai_protocol = rp->ai_protocol;
    memcpy(&attr.ai_addr, rp->ai_addr, rp->ai_addrlen);
    attr.ai_addrlen = rp->ai_addrlen;
#ifdef _WIN32
    closesocket(fd);
#else
    close(fd);
#endif
    break;
  }

  // Check that we found an address we were able to bind to
  GLOO_ENFORCE(rp != nullptr, "Unable to find address for: ", attr.hostname);
  freeaddrinfo(result);
  return;
}

} // namespace