Skip to content

Commit

Permalink
bonjour: Fix discovery on IPv6 network
Browse files Browse the repository at this point in the history
The code would discard discovered IPv6 addresses in favour of IPv4 ones.
Also, the IPv6 addresses discovered did not have the interface
specifier, which caused context creation to fail.

Signed-off-by: Paul Cercueil <[email protected]>
  • Loading branch information
pcercuei committed Jul 13, 2023
1 parent a590363 commit c74e32e
Showing 1 changed file with 31 additions and 29 deletions.
60 changes: 31 additions & 29 deletions dns_sd_bonjour.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,18 @@ static void __cfnet_browser_cb(CFNetServiceBrowserRef browser,
{
const CFNetServiceRef netService = (CFNetServiceRef)domainOrService;
struct dns_sd_discovery_data *dd = info;
char address_v4[DNS_SD_ADDRESS_STR_MAX+1] = "";
char address_v6[DNS_SD_ADDRESS_STR_MAX+1] = "";
char address[DNS_SD_ADDRESS_STR_MAX+1] = "";
char hostname[FQDN_LEN];
char name[FQDN_LEN];
bool have_v4 = false;
bool have_v6 = false;
struct sockaddr_in6 *sa6;
struct sockaddr_in *sa;
CFStreamError anError;
CFStringRef targetHost;
CFStringRef svcName;
CFArrayRef addrArr;
CFDataRef data;
SInt32 port;
char *ptr;

if ((flags & kCFNetServiceFlagIsDomain) != 0) {
IIO_ERROR("DNS SD: FATAL! Callback called for domain, not service.\n");
Expand Down Expand Up @@ -97,45 +96,44 @@ static void __cfnet_browser_cb(CFNetServiceBrowserRef browser,
goto exit;
}

/* Set properties on the last element on the list. */
while (dd->next)
dd = dd->next;

for (CFIndex i = 0; i < CFArrayGetCount(addrArr); i++) {
data = CFArrayGetValueAtIndex(addrArr, i);
sa = (struct sockaddr_in *) CFDataGetBytePtr(data);
sa6 = (struct sockaddr_in6 *) sa;

switch(sa->sin_family) {
case AF_INET:
if (inet_ntop(sa->sin_family, &sa->sin_addr,
address_v4, sizeof(address_v4))) {
have_v4 = true;
}
address, sizeof(address)))
break;
continue;
case AF_INET6:
if (inet_ntop(sa->sin_family, &sa->sin_addr,
address_v6, sizeof(address_v6))) {
have_v6 = true;
}
if (inet_ntop(sa->sin_family, &sa6->sin6_addr,
address, sizeof(address)))
break;
continue;
default:
continue;
}
}

if (!have_v4 && !have_v6) {
IIO_WARNING("DNS SD: Can't resolve valid address for "
"service %s.\n", name);
goto exit;
}

/* Set properties on the last element on the list. */
while (dd->next)
dd = dd->next;
dd->port = port;
dd->hostname = strdup(hostname);

dd->port = port;
dd->hostname = strdup(hostname);
iio_strlcpy(dd->addr_str, address, sizeof(dd->addr_str));

if (have_v4)
iio_strlcpy(dd->addr_str, address_v4, sizeof(dd->addr_str));
else if(have_v6)
iio_strlcpy(dd->addr_str, address_v6, sizeof(dd->addr_str));
ptr = dd->addr_str + strnlen(dd->addr_str, DNS_SD_ADDRESS_STR_MAX);

IIO_DEBUG("DNS SD: added %s (%s:%d)\n", hostname, dd->addr_str, port);
if (sa->sin_family == AF_INET6
&& sa6->sin6_addr.s6_addr[0] == 0xfe
&& sa6->sin6_addr.s6_addr[1] == 0x80
&& if_indextoname((unsigned int)sa6->sin6_scope_id, ptr + 1)) {
*ptr = '%';
}

if (have_v4 || have_v6) {
/* A list entry was filled, prepare new item on the list. */
dd->next = zalloc(sizeof(*dd->next));
if (dd->next) {
Expand All @@ -144,6 +142,10 @@ static void __cfnet_browser_cb(CFNetServiceBrowserRef browser,
} else {
IIO_ERROR("DNS SD Bonjour Resolver : memory failure\n");
}

IIO_DEBUG("DNS SD: added %s (%s:%d)\n", hostname, dd->addr_str, port);

dd = dd->next;
}

verify_flags:
Expand Down

0 comments on commit c74e32e

Please sign in to comment.