mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-29 00:32:34 +08:00
Problem: no way to specify source interface for UDP multicast sender sockets
Solution: if a binding interface is provided in the sender URL we pass it to IP[V6]_MULTICAST_IF setsockopt
This commit is contained in:
parent
f6e528443e
commit
a833ace204
@ -110,13 +110,15 @@ void zmq::udp_engine_t::plug (io_thread_t *io_thread_, session_base_t *session_)
|
||||
io_object_t::plug (io_thread_);
|
||||
handle = add_fd (fd);
|
||||
|
||||
const struct udp_address_t *udp_addr = address->resolved.udp_addr;
|
||||
|
||||
// Bind the socket to a device if applicable
|
||||
if (!options.bound_device.empty ())
|
||||
bind_to_device (fd, options.bound_device);
|
||||
|
||||
if (send_enabled) {
|
||||
if (!options.raw_socket) {
|
||||
const ip_addr_t *out = address->resolved.udp_addr->target_addr ();
|
||||
const ip_addr_t *out = udp_addr->target_addr ();
|
||||
out_address = out->as_sockaddr ();
|
||||
out_addrlen = out->sockaddr_len ();
|
||||
|
||||
@ -136,6 +138,36 @@ void zmq::udp_engine_t::plug (io_thread_t *io_thread_, session_base_t *session_)
|
||||
int rc = setsockopt (fd, level, optname, (char *) &loop,
|
||||
sizeof (loop));
|
||||
|
||||
#ifdef ZMQ_HAVE_WINDOWS
|
||||
wsa_assert (rc != SOCKET_ERROR);
|
||||
#else
|
||||
errno_assert (rc == 0);
|
||||
#endif
|
||||
|
||||
if (out->family () == AF_INET6) {
|
||||
int bind_if = udp_addr->bind_if ();
|
||||
|
||||
if (bind_if > 0) {
|
||||
// If a bind interface is provided we tell the
|
||||
// kernel to use it to send multicast packets
|
||||
rc = setsockopt (fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
|
||||
(char *) &bind_if, sizeof (bind_if));
|
||||
} else {
|
||||
rc = 0;
|
||||
}
|
||||
} else {
|
||||
struct in_addr bind_addr =
|
||||
udp_addr->bind_addr ()->ipv4.sin_addr;
|
||||
|
||||
if (bind_addr.s_addr != INADDR_ANY) {
|
||||
rc =
|
||||
setsockopt (fd, IPPROTO_IP, IP_MULTICAST_IF,
|
||||
(char *) &bind_addr, sizeof (bind_addr));
|
||||
} else {
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ZMQ_HAVE_WINDOWS
|
||||
wsa_assert (rc != SOCKET_ERROR);
|
||||
#else
|
||||
@ -161,11 +193,11 @@ void zmq::udp_engine_t::plug (io_thread_t *io_thread_, session_base_t *session_)
|
||||
errno_assert (rc == 0);
|
||||
#endif
|
||||
|
||||
const ip_addr_t *bind_addr = address->resolved.udp_addr->bind_addr ();
|
||||
const ip_addr_t *bind_addr = udp_addr->bind_addr ();
|
||||
ip_addr_t any = ip_addr_t::any (bind_addr->family ());
|
||||
const ip_addr_t *real_bind_addr;
|
||||
|
||||
bool multicast = address->resolved.udp_addr->is_mcast ();
|
||||
bool multicast = udp_addr->is_mcast ();
|
||||
|
||||
if (multicast) {
|
||||
// In multicast we should bind ANY and use the mreq struct to
|
||||
@ -192,8 +224,7 @@ void zmq::udp_engine_t::plug (io_thread_t *io_thread_, session_base_t *session_)
|
||||
#endif
|
||||
|
||||
if (multicast) {
|
||||
const ip_addr_t *mcast_addr =
|
||||
address->resolved.udp_addr->target_addr ();
|
||||
const ip_addr_t *mcast_addr = udp_addr->target_addr ();
|
||||
|
||||
if (mcast_addr->family () == AF_INET) {
|
||||
struct ip_mreq mreq;
|
||||
|
Loading…
x
Reference in New Issue
Block a user