Skip to content

Commit c74e32e

Browse files
committed
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 <[email protected]>
1 parent a590363 commit c74e32e

File tree

1 file changed

+31
-29
lines changed

1 file changed

+31
-29
lines changed

dns_sd_bonjour.c

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,18 @@ static void __cfnet_browser_cb(CFNetServiceBrowserRef browser,
2828
{
2929
const CFNetServiceRef netService = (CFNetServiceRef)domainOrService;
3030
struct dns_sd_discovery_data *dd = info;
31-
char address_v4[DNS_SD_ADDRESS_STR_MAX+1] = "";
32-
char address_v6[DNS_SD_ADDRESS_STR_MAX+1] = "";
31+
char address[DNS_SD_ADDRESS_STR_MAX+1] = "";
3332
char hostname[FQDN_LEN];
3433
char name[FQDN_LEN];
35-
bool have_v4 = false;
36-
bool have_v6 = false;
34+
struct sockaddr_in6 *sa6;
3735
struct sockaddr_in *sa;
3836
CFStreamError anError;
3937
CFStringRef targetHost;
4038
CFStringRef svcName;
4139
CFArrayRef addrArr;
4240
CFDataRef data;
4341
SInt32 port;
42+
char *ptr;
4443

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

99+
/* Set properties on the last element on the list. */
100+
while (dd->next)
101+
dd = dd->next;
102+
100103
for (CFIndex i = 0; i < CFArrayGetCount(addrArr); i++) {
101104
data = CFArrayGetValueAtIndex(addrArr, i);
102105
sa = (struct sockaddr_in *) CFDataGetBytePtr(data);
106+
sa6 = (struct sockaddr_in6 *) sa;
103107

104108
switch(sa->sin_family) {
105109
case AF_INET:
106110
if (inet_ntop(sa->sin_family, &sa->sin_addr,
107-
address_v4, sizeof(address_v4))) {
108-
have_v4 = true;
109-
}
111+
address, sizeof(address)))
112+
break;
113+
continue;
110114
case AF_INET6:
111-
if (inet_ntop(sa->sin_family, &sa->sin_addr,
112-
address_v6, sizeof(address_v6))) {
113-
have_v6 = true;
114-
}
115+
if (inet_ntop(sa->sin_family, &sa6->sin6_addr,
116+
address, sizeof(address)))
117+
break;
118+
continue;
119+
default:
120+
continue;
115121
}
116-
}
117-
118-
if (!have_v4 && !have_v6) {
119-
IIO_WARNING("DNS SD: Can't resolve valid address for "
120-
"service %s.\n", name);
121-
goto exit;
122-
}
123122

124-
/* Set properties on the last element on the list. */
125-
while (dd->next)
126-
dd = dd->next;
123+
dd->port = port;
124+
dd->hostname = strdup(hostname);
127125

128-
dd->port = port;
129-
dd->hostname = strdup(hostname);
126+
iio_strlcpy(dd->addr_str, address, sizeof(dd->addr_str));
130127

131-
if (have_v4)
132-
iio_strlcpy(dd->addr_str, address_v4, sizeof(dd->addr_str));
133-
else if(have_v6)
134-
iio_strlcpy(dd->addr_str, address_v6, sizeof(dd->addr_str));
128+
ptr = dd->addr_str + strnlen(dd->addr_str, DNS_SD_ADDRESS_STR_MAX);
135129

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

138-
if (have_v4 || have_v6) {
139137
/* A list entry was filled, prepare new item on the list. */
140138
dd->next = zalloc(sizeof(*dd->next));
141139
if (dd->next) {
@@ -144,6 +142,10 @@ static void __cfnet_browser_cb(CFNetServiceBrowserRef browser,
144142
} else {
145143
IIO_ERROR("DNS SD Bonjour Resolver : memory failure\n");
146144
}
145+
146+
IIO_DEBUG("DNS SD: added %s (%s:%d)\n", hostname, dd->addr_str, port);
147+
148+
dd = dd->next;
147149
}
148150

149151
verify_flags:

0 commit comments

Comments
 (0)