X-Git-Url: https://git.distorted.org.uk/~mdw/disorder/blobdiff_plain/e31de8226f81ac0d38666423f60ea4754da1b874..32d209ee9059cc881f6fbc3e5c877eb7edf5327b:/clients/playrtp.c?ds=sidebyside diff --git a/clients/playrtp.c b/clients/playrtp.c index 3a4757b..c22998b 100644 --- a/clients/playrtp.c +++ b/clients/playrtp.c @@ -635,53 +635,6 @@ static size_t playrtp_callback(void *buffer, return samples; } -static int compare_family(const struct ifaddrs *a, - const struct ifaddrs *b, - int family) { - int afamily = a->ifa_addr->sa_family; - int bfamily = b->ifa_addr->sa_family; - if(afamily != bfamily) { - /* Preferred family wins */ - if(afamily == family) return 1; - if(bfamily == family) return -1; - /* Either there's no preference or it doesn't help. Prefer IPv4 */ - if(afamily == AF_INET) return 1; - if(bfamily == AF_INET) return -1; - /* Failing that prefer IPv6 */ - if(afamily == AF_INET6) return 1; - if(bfamily == AF_INET6) return -1; - } - return 0; -} - -static int compare_flags(const struct ifaddrs *a, - const struct ifaddrs *b) { - unsigned aflags = a->ifa_flags, bflags = b->ifa_flags; - /* Up interfaces are better than down ones */ - unsigned aup = aflags & IFF_UP, bup = bflags & IFF_UP; - if(aup != bup) - return aup > bup ? 1 : -1; -#if IFF_DYNAMIC - /* Static addresses are better than dynamic */ - unsigned adynamic = aflags & IFF_DYNAMIC, bdynamic = bflags & IFF_DYNAMIC; - if(adynamic != bdynamic) - return adynamic < bdynamic ? 1 : -1; -#endif - unsigned aloopback = aflags & IFF_LOOPBACK, bloopback = bflags & IFF_LOOPBACK; - /* Static addresses are better than dynamic */ - if(aloopback != bloopback) - return aloopback < bloopback ? 1 : -1; - return 0; -} - -static int compare_interfaces(const struct ifaddrs *a, - const struct ifaddrs *b, - int family) { - int c; - if((c = compare_family(a, b, family))) return c; - return compare_flags(a, b); -} - int main(int argc, char **argv) { int n, err; struct addrinfo *res; @@ -840,30 +793,22 @@ int main(int argc, char **argv) { if(!(c = disorder_new(1))) exit(EXIT_FAILURE); if(disorder_connect(c)) exit(EXIT_FAILURE); } - /* If no address was given, pick something sensible based on the known- - * working connectivity to the server */ + /* If no address was given, we need to pick one. But we already have a + * connection to the server, so we can probably use the address from that. + */ + struct sockaddr_storage ss; if(!node) { - int family = config->rtp_request_address.af; - if(family == AF_UNSPEC) 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"); + addr_len = sizeof ss; + if(disorder_client_sockname(c, (struct sockaddr *)&ss, &addr_len)) + exit(EXIT_FAILURE); + if(ss.ss_family != AF_INET && ss.ss_family != AF_INET6) { + /* We're using a Unix-domain socket, so use a loopback address. I'm + * cowardly using IPv4 here. */ + struct sockaddr_in *sin = (struct sockaddr_in *)&ss; + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = htonl(INADDR_LOOPBACK); } + sa = (struct sockaddr *)&ss; prefs.ai_family = sa->sa_family; } /* If we have an address or port to resolve then do that now */