]> xenbits.xensource.com Git - libvirt.git/commitdiff
Don't use SO_REUSEADDR on Win32 platforms
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 25 Apr 2014 16:47:08 +0000 (17:47 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 29 Apr 2014 10:30:32 +0000 (11:30 +0100)
SO_REUSEADDR on Windows is actually akin to SO_REUSEPORT
on Linux/BSD. ie it allows 2 apps to listen to the same
port at once. Thus we must not set it on Win32 platforms

See http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
src/libvirt_private.syms
src/rpc/virnetsocket.c
src/util/virportallocator.c
src/util/virutil.c
src/util/virutil.h

index 8bbe6e76defd3de75e8011ca38b25fb978251e85..55b016d1874a7aaa8b3e478ceea26c4acfe1fcad 100644 (file)
@@ -2060,6 +2060,7 @@ virSetCloseExec;
 virSetDeviceUnprivSGIO;
 virSetInherit;
 virSetNonBlock;
+virSetSockReuseAddr;
 virSetUIDGID;
 virSetUIDGIDWithCaps;
 virStrIsPrint;
index 2e94a6ca87b1819d8981fad7e9a0bde901f9e1f9..a7e1783b82d86d726647dc6b78937163f738aa6e 100644 (file)
@@ -255,8 +255,7 @@ int virNetSocketNewListenTCP(const char *nodename,
             goto error;
         }
 
-        int opt = 1;
-        if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
+        if (virSetSockReuseAddr(fd) < 0) {
             virReportSystemError(errno, "%s", _("Unable to enable port reuse"));
             goto error;
         }
@@ -460,15 +459,13 @@ int virNetSocketNewConnectTCP(const char *nodename,
 
     runp = ai;
     while (runp) {
-        int opt = 1;
-
         if ((fd = socket(runp->ai_family, runp->ai_socktype,
                          runp->ai_protocol)) < 0) {
             virReportSystemError(errno, "%s", _("Unable to create socket"));
             goto error;
         }
 
-        if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
+        if (virSetSockReuseAddr(fd) < 0) {
             VIR_WARN("Unable to enable port reuse");
         }
 
index ed7bdc20543e384fc59d8d20993509d20607066b..b68133a1b427a10897bd18224650ee16abe5ae97 100644 (file)
@@ -116,7 +116,6 @@ static int virPortAllocatorBindToPort(bool *used,
     struct sockaddr* addr;
     size_t addrlen;
     int v6only = 1;
-    int reuse = 1;
     int ret = -1;
     int fd = -1;
     bool ipv6 = false;
@@ -143,8 +142,7 @@ static int virPortAllocatorBindToPort(bool *used,
         goto cleanup;
     }
 
-    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&reuse,
-                   sizeof(reuse)) < 0) {
+    if (virSetSockReuseAddr(fd) < 0) {
         virReportSystemError(errno, "%s",
                              _("Unable to set socket reuse addr flag"));
         goto cleanup;
index 875e2b0f1a7ecb19878f1a320e1e17948cba292b..95d1ff93241d414b03c960f979b1cb456974bb69 100644 (file)
@@ -136,6 +136,29 @@ int virSetCloseExec(int fd)
     return virSetInherit(fd, false);
 }
 
+#ifdef WIN32
+int virSetSockReuseAddr(int fd ATTRIBUTE_UNUSED)
+{
+    /*
+     * SO_REUSEADDR on Windows is actually akin to SO_REUSEPORT
+     * on Linux/BSD. ie it allows 2 apps to listen to the same
+     * port at once which is certainly not what we want here.
+     *
+     * Win32 sockets have Linux/BSD-like SO_REUSEADDR behaviour
+     * by default, so we can be a no-op.
+     *
+     * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx
+     */
+    return 0;
+}
+#else
+int virSetSockReuseAddr(int fd)
+{
+    int opt = 1;
+    return setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+}
+#endif
+
 int
 virPipeReadUntilEOF(int outfd, int errfd,
                     char **outbuf, char **errbuf) {
index 1f2efd566d360d5312a1a283b40156a5f178e313..2bb74e229b5c8e84b589bce2d2cacba3d022d1ec 100644 (file)
@@ -42,6 +42,7 @@ int virSetBlocking(int fd, bool blocking) ATTRIBUTE_RETURN_CHECK;
 int virSetNonBlock(int fd) ATTRIBUTE_RETURN_CHECK;
 int virSetInherit(int fd, bool inherit) ATTRIBUTE_RETURN_CHECK;
 int virSetCloseExec(int fd) ATTRIBUTE_RETURN_CHECK;
+int virSetSockReuseAddr(int fd) ATTRIBUTE_RETURN_CHECK;
 
 int virPipeReadUntilEOF(int outfd, int errfd,
                         char **outbuf, char **errbuf);