Commit 57440b86 authored by Steven McCoy's avatar Steven McCoy Committed by Martin Sustrik

Add IPv6 support to tcp_listener

Signed-off-by: 's avatarSteven McCoy <steven.mccoy@miru.hk>
Signed-off-by: 's avatarMartin Sustrik <sustrik@250bpm.com>
parent 3c3c0bfd
......@@ -457,4 +457,21 @@ void zmq::unblock_socket (fd_t s_)
#endif
}
void zmq::enable_ipv4_mapping (fd_t s_)
{
#ifdef IPV6_V6ONLY
#ifdef ZMQ_HAVE_WINDOWS
DWORD flag = 0;
#else
int flag = 0;
#endif
int rc = setsockopt (s_, IPPROTO_IPV6, IPV6_V6ONLY, (const char*) &flag,
sizeof (flag));
#ifdef ZMQ_HAVE_WINDOWS
wsa_assert (rc != SOCKET_ERROR);
#else
errno_assert (rc == 0);
#endif
#endif
}
......@@ -68,6 +68,9 @@ namespace zmq
// Sets the socket into non-blocking mode.
void unblock_socket (fd_t s_);
// Enable IPv4-mapping of addresses in case it is disabled by default.
void enable_ipv4_mapping (fd_t s_);
}
#endif
......@@ -199,23 +199,10 @@ int zmq::tcp_connecter_t::open ()
return -1;
#endif
// Enable IPv4-mapping of addresses in case it is disabled by default.
#ifdef IPV6_V6ONLY
if (addr.ss_family == AF_INET6) {
#ifdef ZMQ_HAVE_WINDOWS
DWORD flag = 0;
#else
int flag = 0;
#endif
int rc = setsockopt (s, IPPROTO_IPV6, IPV6_V6ONLY,
(const char*) &flag, sizeof (flag));
#ifdef ZMQ_HAVE_WINDOWS
wsa_assert (rc != SOCKET_ERROR);
#else
errno_assert (rc == 0);
#endif
}
#endif
// On some systems, IPv4 mapping in IPv6 sockets is disabled by default.
// Switch it on in such cases.
if (addr.ss_family == AF_INET6)
enable_ipv4_mapping (s);
// Set the socket to non-blocking mode so that we get async connect().
unblock_socket (s);
......
......@@ -130,6 +130,20 @@ int zmq::tcp_listener_t::set_address (const char *addr_)
// Create a listening socket.
s = ::socket (addr.ss_family, SOCK_STREAM, IPPROTO_TCP);
#ifdef ZMQ_HAVE_WINDOWS
if (s == INVALID_SOCKET)
wsa_error_to_errno ();
#endif
// IPv6 address family not supported, try automatic downgrade to IPv4.
if (addr.ss_family == AF_INET6 && errno == EAFNOSUPPORT &&
!options.ipv4only) {
rc = resolve_ip_interface (&addr, &addr_len, addr_, true);
if (rc != 0)
return rc;
s = ::socket (addr.ss_family, SOCK_STREAM, IPPROTO_TCP);
}
#ifdef ZMQ_HAVE_WINDOWS
if (s == INVALID_SOCKET) {
wsa_error_to_errno ();
......@@ -140,6 +154,11 @@ int zmq::tcp_listener_t::set_address (const char *addr_)
return -1;
#endif
// On some systems, IPv4 mapping in IPv6 sockets is disabled by default.
// Switch it on in such cases.
if (addr.ss_family == AF_INET6)
enable_ipv4_mapping (s);
// Allow reusing of the address.
int flag = 1;
#ifdef ZMQ_HAVE_WINDOWS
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment