- /* Pick address family to match known-working connectivity to the server */
- int family = disorder_client_af(c);
- /* Get a list of interfaces */
- struct ifaddrs *ifa, *bestifa = NULL;
- if(getifaddrs(&ifa) < 0)
- disorder_fatal(errno, "error calling getifaddrs");
- /* Try to pick a good one */
- for(; ifa; ifa = ifa->ifa_next) {
- if(!ifa->ifa_addr) continue;
- if(bestifa == NULL
- || compare_interfaces(ifa, bestifa, family) > 0)
- bestifa = ifa;
+ /* If no address was given, pick something sensible based on the known-
+ * working connectivity to the server */
+ if(!node) {
+ int family = disorder_client_af(c);
+ /* Get a list of interfaces */
+ struct ifaddrs *ifa, *bestifa = NULL;
+ if(getifaddrs(&ifa) < 0)
+ disorder_fatal(errno, "error calling getifaddrs");
+ /* Try to pick a good one */
+ for(; ifa; ifa = ifa->ifa_next) {
+ if(!ifa->ifa_addr) continue;
+ if(bestifa == NULL
+ || compare_interfaces(ifa, bestifa, family) > 0)
+ bestifa = ifa;
+ }
+ if(!bestifa)
+ disorder_fatal(0, "failed to select a network interface");
+ sa = bestifa->ifa_addr;
+ switch(sa->sa_family) {
+ case AF_INET: ((struct sockaddr_in *)sa)->sin_port = 0; break;
+ case AF_INET6: ((struct sockaddr_in6 *)sa)->sin6_port = 0; break;
+ default: assert(!"unexpected address family");
+ }
+ prefs.ai_family = sa->sa_family;
+ }
+ /* If we have an address or port to resolve then do that now */
+ if (node || svc) {
+ struct addrinfo *ai;
+ char errbuf[1024];
+ int rc;
+ if((rc = getaddrinfo(node, svc, &prefs, &ai)))
+ disorder_fatal(0, "failed to resolve address `%s' and service `%s': %s",
+ node ? node : "-", svc ? svc : "-",
+ format_error(ec_getaddrinfo, rc,
+ errbuf, sizeof(errbuf)));
+ if(!sa)
+ sa = ai->ai_addr;
+ else {
+ assert(sa->sa_family == ai->ai_addr->sa_family);
+ switch(sa->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *)sa)->sin_port =
+ ((struct sockaddr_in *)ai->ai_addr)->sin_port;
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)sa)->sin6_port =
+ ((struct sockaddr_in6 *)ai->ai_addr)->sin6_port;
+ break;
+ default:
+ assert(!"unexpected address family");
+ }
+ }