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 unfortunately - that doesn't work. The kernel
really only needs to have a hostname set for uname() to work, which is
what glibc and uclibc implement in gethostname().

So - now we 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 #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

and when you have multiple on network (with same name):
192.168.1.110:5353 : answer _iio._tcp.local. PTR "iiod on pluto._iio._tcp.local." rclass 0x1 ttl 10 length 16
192.168.1.110:5353 : answer pluto.local. A 192.168.1.110
192.168.1.115:5353 : answer _iio._tcp.local. PTR "iiod on pluto #2._iio._tcp.local." rclass 0x1 ttl 10 length 19
192.168.1.115:5353 : answer pluto-2.local. A 192.168.1.115

Signed-off-by: Robin Getz <rgetz@mathworks.com>
[pcercuei: change %d to %ld in print format string]
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
(cherry picked from commit 38483f3)
  • Loading branch information
rgetz authored and SRaus committed Feb 26, 2024
1 parent 8fb78e0 commit 9952927
Showing 1 changed file with 49 additions and 6 deletions.
55 changes: 49 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,62 @@ 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;

/*
* Try to make sure the network is up before letting avahi
* know we are here, and advertising on the network.
* However, if we are on the last try before we timeout,
* ignore some prerequisites, and just assume it will be
* OK later (if someone boots, and later plugs in USB <-> ethernet).
*/
while(true) {
struct ifaddrs *ifaddr = 0;
struct ifaddrs *ifa = 0;

if (!net && ts.tv_sec < TIMEOUT) {
/* 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;
/* Interface is running, think ifup */
if (!(ifa->ifa_flags & IFF_UP))
continue;
/* supports multicast (i.e. MDNS) */
if (!(ifa->ifa_flags & IFF_MULTICAST))
continue;
/* Interface is not a loopback interface */
if ((ifa->ifa_flags & IFF_LOOPBACK))
continue;
IIO_INFO("found applicable network for mdns on %s\n", ifa->ifa_name);
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 || !host[0] || (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 +320,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 %ld 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 seconds (3.5 min),
* it is not going to, so stop
*/
if (ts.tv_sec >= 11)
if (ts.tv_sec > TIMEOUT)
break;
}

Expand Down

0 comments on commit 9952927

Please sign in to comment.