mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-18 02:25:18 +00:00
rpc: add API for checking IPv4/6 availability
The socket test suite has a function for checking if IPv4 or IPv6 are available, and returning a free socket. The first bit of that will be needed in another test, so pull that logic out into a separate helper method. Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
d587704cc7
commit
43c0a84cda
@ -172,6 +172,7 @@ virNetServerServiceToggle;
|
||||
# rpc/virnetsocket.h
|
||||
virNetSocketAccept;
|
||||
virNetSocketAddIOCallback;
|
||||
virNetSocketCheckProtocols;
|
||||
virNetSocketClose;
|
||||
virNetSocketDupFD;
|
||||
virNetSocketGetFD;
|
||||
|
@ -29,6 +29,9 @@
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef HAVE_IFADDRS_H
|
||||
# include <ifaddrs.h>
|
||||
#endif
|
||||
#include <netdb.h>
|
||||
|
||||
#ifdef HAVE_NETINET_TCP_H
|
||||
@ -142,6 +145,69 @@ static int virNetSocketForkDaemon(const char *binary)
|
||||
}
|
||||
#endif
|
||||
|
||||
int virNetSocketCheckProtocols(bool *hasIPv4,
|
||||
bool *hasIPv6)
|
||||
{
|
||||
#ifdef HAVE_IFADDRS_H
|
||||
struct ifaddrs *ifaddr = NULL, *ifa;
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *ai = NULL;
|
||||
int ret = -1;
|
||||
int gaierr;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
|
||||
*hasIPv4 = *hasIPv6 = false;
|
||||
|
||||
if (getifaddrs(&ifaddr) < 0) {
|
||||
virReportSystemError(errno, "%s",
|
||||
_("Cannot get host interface addresses"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
|
||||
if (!ifa->ifa_addr)
|
||||
continue;
|
||||
|
||||
if (ifa->ifa_addr->sa_family == AF_INET)
|
||||
*hasIPv4 = true;
|
||||
if (ifa->ifa_addr->sa_family == AF_INET6)
|
||||
*hasIPv6 = true;
|
||||
}
|
||||
|
||||
freeifaddrs(ifaddr);
|
||||
|
||||
hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
|
||||
hints.ai_family = AF_INET6;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if ((gaierr = getaddrinfo("::1", NULL, &hints, &ai)) != 0) {
|
||||
if (gaierr == EAI_ADDRFAMILY ||
|
||||
gaierr == EAI_FAMILY) {
|
||||
*hasIPv6 = false;
|
||||
} else {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Cannot resolve ::1 address: %s"),
|
||||
gai_strerror(gaierr));
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
freeaddrinfo(ai);
|
||||
|
||||
VIR_DEBUG("Protocols: v4 %d v6 %d\n", *hasIPv4, *hasIPv6);
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
return ret;
|
||||
#else
|
||||
*hasIPv4 = *hasIPv6 = false;
|
||||
virReportError(VIR_ERR_NO_SUPPORT, "%s",
|
||||
_("Cannot check address family on this platform"));
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static virNetSocketPtr virNetSocketNew(virSocketAddrPtr localAddr,
|
||||
virSocketAddrPtr remoteAddr,
|
||||
|
@ -45,6 +45,9 @@ typedef void (*virNetSocketIOFunc)(virNetSocketPtr sock,
|
||||
void *opaque);
|
||||
|
||||
|
||||
int virNetSocketCheckProtocols(bool *hasIPv4,
|
||||
bool *hasIPv6);
|
||||
|
||||
int virNetSocketNewListenTCP(const char *nodename,
|
||||
const char *service,
|
||||
int family,
|
||||
|
@ -48,47 +48,15 @@ static int
|
||||
checkProtocols(bool *hasIPv4, bool *hasIPv6,
|
||||
int *freePort)
|
||||
{
|
||||
struct ifaddrs *ifaddr = NULL, *ifa;
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *ai = NULL;
|
||||
struct sockaddr_in in4;
|
||||
struct sockaddr_in6 in6;
|
||||
int s4 = -1, s6 = -1;
|
||||
size_t i;
|
||||
int ret = -1;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
|
||||
*hasIPv4 = *hasIPv6 = false;
|
||||
*freePort = 0;
|
||||
|
||||
if (getifaddrs(&ifaddr) < 0) {
|
||||
perror("getifaddrs");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
|
||||
if (!ifa->ifa_addr)
|
||||
continue;
|
||||
|
||||
if (ifa->ifa_addr->sa_family == AF_INET)
|
||||
*hasIPv4 = true;
|
||||
if (ifa->ifa_addr->sa_family == AF_INET6)
|
||||
*hasIPv6 = true;
|
||||
}
|
||||
|
||||
hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
|
||||
hints.ai_family = AF_INET6;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if (getaddrinfo("::1", "5672", &hints, &ai) != 0)
|
||||
*hasIPv6 = false;
|
||||
|
||||
freeaddrinfo(ai);
|
||||
|
||||
VIR_DEBUG("Protocols: v4 %d v6 %d\n", *hasIPv4, *hasIPv6);
|
||||
|
||||
freeifaddrs(ifaddr);
|
||||
if (virNetSocketCheckProtocols(hasIPv4, hasIPv6) < 0)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < 50; i++) {
|
||||
int only = 1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user