]> xenbits.xensource.com Git - libvirt.git/commitdiff
Disable IPv6 socket auto-binding to IPv4 socket
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 11 Nov 2009 15:19:50 +0000 (15:19 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Thu, 12 Nov 2009 11:17:39 +0000 (11:17 +0000)
Sometimes getaddrinfo returns IPv4 addresses before IPv6 addresses.
IPv6 sockets default to attempting to bind to IPv4 addresses too.
So if the IPv4 address is activated first, then binding to IPv6
will unneccessarily fail.

* daemon/libvirtd.c: Bind to IPv6 and IPv4 addresses separately

daemon/libvirtd.c

index 2fcd9a92e496aafe0e36bc3e0816b5925dbe9001..01c9bbc6774e903653243b68c250d27f59a1beb3 100644 (file)
@@ -615,6 +615,21 @@ remoteMakeSockets (int *fds, int max_fds, int *nfds_r, const char *node, const c
         int opt = 1;
         setsockopt (fds[*nfds_r], SOL_SOCKET, SO_REUSEADDR, &opt, sizeof opt);
 
+#ifdef IPV6_V6ONLY
+        if (runp->ai_family == PF_INET6) {
+            int on = 1;
+            /*
+             * Normally on Linux an INET6 socket will bind to the INET4
+             * address too. If getaddrinfo returns results with INET4
+             * first though, this will result in INET6 binding failing.
+             * We can trivially cope with multiple server sockets, so
+             * we force it to only listen on IPv6
+             */
+            setsockopt(fds[*nfds_r], IPPROTO_IPV6,IPV6_V6ONLY,
+                       (void*)&on, sizeof on);
+        }
+#endif
+
         if (bind (fds[*nfds_r], runp->ai_addr, runp->ai_addrlen) == -1) {
             if (errno != EADDRINUSE) {
                 VIR_ERROR(_("bind: %s"), virStrerror (errno, ebuf, sizeof ebuf));