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

Problem: Zbeacon does not support IPv6 #1616

Merged
merged 7 commits into from
Jan 30, 2017
Merged

Conversation

bluca
Copy link
Member

@bluca bluca commented Jan 30, 2017

Solution: see commits

Implement support for IPv6 multicast, using ff02::1 as the default address which provides more or less the equivalent of IPv4 broadcast.

Note the hack in the last commit: due to what I think it's a Linux specific quirk it's not possible to receive v6 multicast if the socket is bound to anything other than inaddr_any, which breaks Zbeacon since the source address will be randomly picked. So I had to use 2 UDP sockets, one for sending and one for receiving.

Tested on Linux with zpinger and zbeacon_tester from zyre between a desktop, a raspberry pi 2 running Debian armv7 and a raspberry pi 3 running Fedora arm64.

Help testing on osx and on more machines with zyre would be very welcome!

Solution: add it to prelude header
Solution: initialize buffer with NI_MAXHOST length instead
Solution: clarify that if IPv6 is enabled a big enough buffer must
be allocated for the peername parameter.
Solution: always use getnameinfo instead like it's done when building
for Windows, as it's available everywhere and more reliable.
Solution: in rare case of getnameinfo failure return NULL. Failures
with getnameinfo have not been observed, but sporadic failure did
happen when using inet_ntop. Given it's a recoverable error and
avoid asserting and just print a warning.
Solution: if IPv6 is enabled use link-local all-node multicast,
fe02::1, to achieve the same result as IPv4 broadcast.
Solution: use two UDP sockets, one for sending and one for receiving.
For IPv6 we need two sockets. At least on Linux, IPv6 multicast packets
are NOT received despite joining the group and setting the interface
option UNLESS the socket is bound to in6_addrany, which means the kernel
will select an arbitrary IP address as the source when sending beacons
out. This breaks zbeacon as the protocol uses the source address of a
beacon to find the endpoint of a peer, which is then random and
useless (could even be associated with a different interface, eg: a
virtual bridge).
As a workaround, use a different socket to send packets. So the socket
that receives can be bound to in6_addrany, and the socket that sends
can be bound to the actual intended host address.
@sappo sappo merged commit 830aa29 into zeromq:master Jan 30, 2017
@bluca bluca deleted the zbeacon_ipv6 branch January 30, 2017 09:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants