-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Fix dish socket multicast bind issue #4820
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -125,7 +125,6 @@ int zmq::udp_address_t::resolve (const char *name_, bool bind_, bool ipv6_) | |
| if (_is_multicast || !bind_) { | ||
| _bind_address = ip_addr_t::any (_target_address.family ()); | ||
| _bind_address.set_port (port); | ||
| _bind_interface = 0; | ||
| } else { | ||
| // If we were asked for a bind socket and the address | ||
| // provided was not multicast then it was really meant as | ||
|
|
@@ -141,9 +140,12 @@ int zmq::udp_address_t::resolve (const char *name_, bool bind_, bool ipv6_) | |
|
|
||
| // For IPv6 multicast we *must* have an interface index since we can't | ||
| // bind by address. | ||
| if (ipv6_ && _is_multicast && _bind_interface < 0) { | ||
| errno = ENODEV; | ||
| return -1; | ||
| if (ipv6_ && _is_multicast && bind_) { | ||
| if (_bind_interface < 0) { | ||
| errno = ENODEV; | ||
| return -1; | ||
| } | ||
| _target_address.ipv6.sin6_scope_id = _bind_interface; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To bind on multicast group in IPv6, it requires to set the scope id to the network interface index, otherwise it will fail. |
||
| } | ||
|
|
||
| return 0; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -261,7 +261,7 @@ MAKE_TEST_V4V6 (test_radio_dish_udp) | |
| static const char *mcast_url (int ipv6_) | ||
| { | ||
| if (ipv6_) { | ||
| return "udp://[" MCAST_IPV6 "]:5555"; | ||
| return "udp://eth0;[" MCAST_IPV6 "]:5555"; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the DISH socket now must specify the network interface for bind with this change. I'm concerned about hard-coding the network interface name here, as it might break on other OS or if the host use different names. Not sure if there is any better choice. Besides, it seems we cannot bind on |
||
| } | ||
| return "udp://" MCAST_IPV4 ":5555"; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,7 +23,8 @@ static void test_resolve (bool bind_, | |
| const char *target_addr_, | ||
| uint16_t expected_port_, | ||
| const char *bind_addr_, | ||
| bool multicast_) | ||
| bool multicast_, | ||
| uint16_t expected_zone = 0) | ||
| { | ||
| if (family_ == AF_INET6 && !is_ipv6_available ()) { | ||
| TEST_IGNORE_MESSAGE ("ipv6 is not available"); | ||
|
|
@@ -53,7 +54,7 @@ static void test_resolve (bool bind_, | |
| } | ||
|
|
||
| validate_address (family_, addr.target_addr (), target_addr_, | ||
| expected_port_); | ||
| expected_port_, expected_zone); | ||
| validate_address (family_, addr.bind_addr (), bind_addr_, expected_port_); | ||
| } | ||
|
|
||
|
|
@@ -62,10 +63,11 @@ static void test_resolve_bind (int family_, | |
| const char *dest_addr_, | ||
| uint16_t expected_port_ = 0, | ||
| const char *bind_addr_ = NULL, | ||
| bool multicast_ = false) | ||
| bool multicast_ = false, | ||
| uint16_t expected_zone = 0) | ||
| { | ||
| test_resolve (true, family_, name_, dest_addr_, expected_port_, bind_addr_, | ||
| multicast_); | ||
| multicast_, expected_zone); | ||
| } | ||
|
|
||
| static void test_resolve_connect (int family_, | ||
|
|
@@ -172,7 +174,7 @@ static void test_resolve_ipv4_bind_mcast () | |
|
|
||
| static void test_resolve_ipv6_bind_mcast () | ||
| { | ||
| test_resolve_bind (AF_INET6, "[ff00::1]:1234", "ff00::1", 1234, "::", true); | ||
| test_resolve_bind (AF_INET6, "eth0;[ff00::1]:1234", "ff00::1", 1234, "fe80::", true, 2); | ||
| } | ||
|
|
||
| static void test_resolve_ipv4_connect_mcast () | ||
|
|
@@ -232,7 +234,7 @@ static void test_resolve_ipv6_mcast_src_connect () | |
| } | ||
|
|
||
| zmq::udp_address_t addr; | ||
| int rc = addr.resolve ("[1:2:3::4];[ff01::1]:5555", false, true); | ||
| int rc = addr.resolve ("[1:2:3::4];[ff01::1]:5555", true, true); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. change bind from |
||
|
|
||
| // For the time being this fails because we only support binding multicast | ||
| // by interface name, not interface IP | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interface index is only needed if it's IPv6 multicast and the socket needs to perform
bind(), i.e., the DISH socket.