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@xxxxxxxxxx> > --- > 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 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list