diff --git a/iiod/dns-sd.c b/iiod/dns-sd.c index 75bb27d04..1575faf3b 100644 --- a/iiod/dns-sd.c +++ b/iiod/dns-sd.c @@ -21,6 +21,8 @@ #include #include +#include +#include #include #include @@ -242,21 +244,53 @@ static void create_services(AvahiClient *c) } #define IIOD_ON "iiod on " +#define TIMEOUT 20 static void start_avahi_thd(struct thread_pool *pool, void *d) { - char label[AVAHI_LABEL_MAX]; char host[AVAHI_LABEL_MAX - sizeof(IIOD_ON)]; struct timespec ts; - int ret; + int ret, net = 0; ts.tv_nsec = 0; ts.tv_sec = 1; while(true) { + struct ifaddrs* ifaddr = 0; + struct ifaddrs* ifa = 0; + + if (!net) { + /* Ensure networking is alive */ + ret = getifaddrs(&ifaddr); + if (ret) + goto again; + + /* Make sure at least one practical interface is up and ready */ + for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) { + /* no address */ + if (!ifa->ifa_addr) + continue; + /* or not up */ + if (!(ifa->ifa_flags & IFF_UP) ) + continue; + /* or not multicast (doesn't support MDNS) */ + if (!(ifa->ifa_flags & IFF_MULTICAST)) + continue; + /* or is loopback */ + if ((ifa->ifa_flags & IFF_LOOPBACK)) + continue; + net++; + } + freeifaddrs(ifaddr); + if (!net) + goto again; + } + + /* Get the hostname, which on uClibc, can return (none) + * rather than fail/zero length string, like on glibc */ ret = gethostname(host, sizeof(host)); - if (ret || !strcmp(host, "none")) + if (ret || (ts.tv_sec <= TIMEOUT && (!strcmp(host, "none") || !strcmp(host, "(none)")))) goto again; snprintf(label, sizeof(label), "%s%s", IIOD_ON, host); @@ -277,13 +311,13 @@ static void start_avahi_thd(struct thread_pool *pool, void *d) if (avahi.client) break; again: - IIO_INFO("Avahi didn't start, try again later\n"); + IIO_INFO("Avahi didn't start, try again in %d seconds later\n", ts.tv_sec); nanosleep(&ts, NULL); ts.tv_sec++; - /* If it hasn't started in 10 times over 60 seconds, + /* If it hasn't started in 20 times over 210 secondsi (3.5 min), * it is not going to, so stop */ - if (ts.tv_sec >= 11) + if (ts.tv_sec >= TIMEOUT + 1) break; }