Permalink
Browse files

Merge pull request #1667 from bluca/zsys_udp_recv_scopeid

Problems: zbeacon still not fully working with IPv6 link-local
  • Loading branch information...
2 parents 3cd40ec + e51a9bd commit e2390680e263af3db2ec655189605acf4e344e80 @sappo sappo committed on GitHub Apr 24, 2017
Showing with 31 additions and 0 deletions.
  1. +10 −0 src/zbeacon.c
  2. +9 −0 src/ziflist.c
  3. +12 −0 src/zsys.c
View
@@ -188,6 +188,16 @@ s_self_prepare_udp (self_t *self)
rc = getaddrinfo (zsys_ipv6_address (), self->port_nbr,
&hint, &bind_to);
assert (rc == 0);
+ // A user might set a link-local address without appending %iface
+ if (IN6_IS_ADDR_LINKLOCAL (&((in6addr_t *)bind_to->ai_addr)->sin6_addr) &&
+ !strchr (zsys_ipv6_address (), '%')) {
+ char address_and_iface [NI_MAXHOST] = {0};
+ strcat (address_and_iface, zsys_ipv6_address ());
+ strcat (address_and_iface, "%");
+ strcat (address_and_iface, iface);
+ rc = getaddrinfo (address_and_iface, self->port_nbr, &hint, &bind_to);
+ assert (rc == 0);
+ }
rc = getaddrinfo (zsys_ipv6_mcast_address (), self->port_nbr,
&hint, &send_to);
assert (rc == 0);
View
@@ -72,6 +72,15 @@ s_interface_new (char *name, struct sockaddr *address, struct sockaddr *netmask,
sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6),
hbuf, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
assert (rc == 0);
+ // Some platform's getnameinfo, like Solaris, appear not to append the
+ // interface name when parsing a link-local IPv6 address. These addresses
+ // cannot be used without the interface, so we must append it manually.
+ if (address->sa_family == AF_INET6 &&
+ IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *)address)->sin6_addr) &&
+ !strchr (hbuf, '%')) {
+ strcat (hbuf, "%");
+ strcat (hbuf, name);
+ }
self->address = strdup (hbuf);
assert (self->address);
View
@@ -993,6 +993,18 @@ zsys_udp_recv (SOCKET udpsock, char *peername, int peerlen)
return NULL;
}
+ // Some platform's getnameinfo, like Solaris, appear not to append the
+ // interface name when parsing a link-local IPv6 address. These addresses
+ // cannot be used without the interface, so we must append it manually.
+ if (address6.sin6_family == AF_INET6 &&
+ IN6_IS_ADDR_LINKLOCAL (&address6.sin6_addr) &&
+ !strchr (peername, '%')) {
+ char ifname [32] = {0};
+ if_indextoname (address6.sin6_scope_id, ifname);
+ strcat (peername, "%");
+ strcat (peername, ifname);
+ }
+
return zframe_new (buffer, size);
}

0 comments on commit e239068

Please sign in to comment.