Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iiod: Make sure network is alive before poking avahi #1080

Merged
merged 1 commit into from
Nov 13, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 %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 seconds (3.5 min),
* it is not going to, so stop
*/
if (ts.tv_sec >= 11)
if (ts.tv_sec > TIMEOUT)
break;
}

Expand Down