[libvirt] [PATCH v2] Don't use SO_REUSEADDR on Win32 platforms

Daniel P. Berrange berrange at redhat.com
Mon Apr 28 13:14:39 UTC 2014


On Mon, Apr 28, 2014 at 02:05:23PM +0100, Daniel P. Berrange wrote:
> 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 at redhat.com>
> ---
>  src/libvirt_private.syms    |  1 +
>  src/rpc/virnetsocket.c      |  7 ++-----
>  src/util/virportallocator.c |  4 +---
>  src/util/virutil.c          | 23 +++++++++++++++++++++++
>  src/util/virutil.h          |  1 +
>  5 files changed, 28 insertions(+), 8 deletions(-)
> 
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 5788468..ee2f57b 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -2059,6 +2059,7 @@ virSetCloseExec;
>  virSetDeviceUnprivSGIO;
>  virSetInherit;
>  virSetNonBlock;
> +virSetSockReuseAddr;
>  virSetUIDGID;
>  virSetUIDGIDWithCaps;
>  virStrIsPrint;
> diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
> index 2e94a6c..a7e1783 100644
> --- a/src/rpc/virnetsocket.c
> +++ b/src/rpc/virnetsocket.c
> @@ -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");
>          }
>  
> diff --git a/src/util/virportallocator.c b/src/util/virportallocator.c
> index ed7bdc2..b68133a 100644
> --- a/src/util/virportallocator.c
> +++ b/src/util/virportallocator.c
> @@ -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;
> diff --git a/src/util/virutil.c b/src/util/virutil.c
> index 9be1590..65b10b8 100644
> --- a/src/util/virutil.c
> +++ b/src/util/virutil.c
> @@ -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
> +}

Obviously this } should be before the #endif :-)


Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|




More information about the libvir-list mailing list