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

Martin Kletzander mkletzan at redhat.com
Mon Apr 28 13:38:54 UTC 2014


On Mon, Apr 28, 2014 at 02:14:39PM +0100, Daniel P. Berrange wrote:
>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 :-)
>

ACK with that changed :-)

Martin

>
>Regards,
>Daniel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20140428/6c598387/attachment-0001.sig>


More information about the libvir-list mailing list