Skip to content

Commit

Permalink
iiod: Make sure network is alive before poking avahi
Browse files Browse the repository at this point in the history
In the past, we were only checking hostname, as a way to see if the
network was ready, but unfortantely - that doesn't work. The kernel
really only needs to have a hostname set for uname() to work, which is
what glibc and uclibc actaully do in gethostname().

So - now we actualyl check there is a working, configured ethernet card,
that supports mdns (ie multicast) that is up before moving on to making
sure there is a hostname.

We also don't allow "none" or "(none)" to be the hostname until after
things time out (3 min).

This fixes analogdevicesinc#1072 and turns:
192.168.2.1:5353 : answer _iio._tcp.local. PTR "iiod on (none)._iio._tcp.local." rclass 0x1 ttl 10 length 17
into:
192.168.2.1:5353 : answer _iio._tcp.local. PTR "iiod on pluto._iio._tcp.local." rclass 0x1 ttl 10 length 16

Signed-off-by: Robin Getz <rgetz@mathworks.com>
  • Loading branch information
rgetz committed Oct 29, 2023
1 parent 43bcd0e commit 0ee0f7b
Showing 1 changed file with 40 additions and 6 deletions.
46 changes: 40 additions & 6 deletions iiod/dns-sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include <avahi-client/publish.h>
#include <avahi-common/domain.h>

#include <ifaddrs.h>
#include <net/if.h>
#include <stddef.h>
#include <time.h>

Expand Down Expand Up @@ -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);
Expand All @@ -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;
}

Expand Down

0 comments on commit 0ee0f7b

Please sign in to comment.