[libvirt] [PATCH 2/3] rpc: add API for checking IPv4/6 availability

Daniel P. Berrange berrange at redhat.com
Fri Jun 5 08:47:44 UTC 2015


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 at redhat.com>
---
 src/libvirt_remote.syms  |  1 +
 src/rpc/virnetsocket.c   | 66 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/rpc/virnetsocket.h   |  3 +++
 tests/virnetsockettest.c | 36 ++------------------------
 4 files changed, 72 insertions(+), 34 deletions(-)

diff --git a/src/libvirt_remote.syms b/src/libvirt_remote.syms
index 6b520b5..950e56e 100644
--- a/src/libvirt_remote.syms
+++ b/src/libvirt_remote.syms
@@ -171,6 +171,7 @@ virNetServerServiceToggle;
 # rpc/virnetsocket.h
 virNetSocketAccept;
 virNetSocketAddIOCallback;
+virNetSocketCheckProtocols;
 virNetSocketClose;
 virNetSocketDupFD;
 virNetSocketGetFD;
diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
index d9f3e11..2497f67 100644
--- a/src/rpc/virnetsocket.c
+++ b/src/rpc/virnetsocket.c
@@ -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,
diff --git a/src/rpc/virnetsocket.h b/src/rpc/virnetsocket.h
index a8ff8a9..5de3d92 100644
--- a/src/rpc/virnetsocket.h
+++ b/src/rpc/virnetsocket.h
@@ -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,
diff --git a/tests/virnetsockettest.c b/tests/virnetsockettest.c
index f609484..1ababad 100644
--- a/tests/virnetsockettest.c
+++ b/tests/virnetsockettest.c
@@ -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;
-- 
2.4.1




More information about the libvir-list mailing list