0
0
mirror of https://github.com/zeromq/libzmq.git synced 2024-12-26 23:01:04 +08:00

Problem: can't test if IPv6 is available in tests

Solution: add helper function is_ipv6_available to testutil.hpp to
test if IPv6 is available on the building platform.
This function will try to open and bind a socket to ::1:*, as it's
the ultimate way of knowing if, at least on the loopback, IPv6 is
enabled.
This commit is contained in:
Luca Boccassi 2016-04-18 16:20:58 +01:00
parent 8d49650ac8
commit ac0e97e5dc

View File

@ -51,6 +51,7 @@
#include <string.h>
#if defined _WIN32
# include "windows.hpp"
# if defined _MSC_VER
# include <crtdbg.h>
# pragma warning(disable:4996)
@ -61,6 +62,9 @@
# include <signal.h>
# include <stdlib.h>
# include <sys/wait.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
#endif
// Bounce a message from client to server and back
@ -318,5 +322,53 @@ msleep (int milliseconds)
#endif
}
// check if IPv6 is available (0/false if not, 1/true if it is)
// only way to reliably check is to actually open a socket and try to bind it
int
is_ipv6_available(void)
{
int rc, ipv6 = 1;
struct sockaddr_in6 test_addr;
memset (&test_addr, 0, sizeof (test_addr));
test_addr.sin6_family = AF_INET6;
inet_pton (AF_INET6, "::1", &(test_addr.sin6_addr));
#ifdef ZMQ_HAVE_WINDOWS
SOCKET fd = socket (AF_INET6, SOCK_STREAM, IPPROTO_IP);
if (fd == INVALID_SOCKET)
ipv6 = 0;
else {
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&ipv6, sizeof(int));
rc = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)&ipv6, sizeof(int));
if (rc == SOCKET_ERROR)
ipv6 = 0;
else {
rc = bind (fd, (struct sockaddr *)&test_addr, sizeof (test_addr));
if (rc == SOCKET_ERROR)
ipv6 = 0;
}
closesocket (fd);
}
#else
int fd = socket (AF_INET6, SOCK_STREAM, IPPROTO_IP);
if (fd == -1)
ipv6 = 0;
else {
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &ipv6, sizeof(int));
rc = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6, sizeof(int));
if (rc != 0)
ipv6 = 0;
else {
rc = bind (fd, (struct sockaddr *)&test_addr, sizeof (test_addr));
if (rc != 0)
ipv6 = 0;
}
close (fd);
}
#endif
return ipv6;
}
#endif