From c74e32e16fd828b7e26616d94ba5308f42c666c2 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Thu, 13 Jul 2023 11:25:16 +0200 Subject: [PATCH] bonjour: Fix discovery on IPv6 network 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 --- dns_sd_bonjour.c | 60 +++++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/dns_sd_bonjour.c b/dns_sd_bonjour.c index 2d7ed5e11..ff5a0cb75 100644 --- a/dns_sd_bonjour.c +++ b/dns_sd_bonjour.c @@ -28,12 +28,10 @@ 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; @@ -41,6 +39,7 @@ static void __cfnet_browser_cb(CFNetServiceBrowserRef browser, CFArrayRef addrArr; CFDataRef data; SInt32 port; + char *ptr; if ((flags & kCFNetServiceFlagIsDomain) != 0) { IIO_ERROR("DNS SD: FATAL! Callback called for domain, not service.\n"); @@ -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) { @@ -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: