#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
}
#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,
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;