summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/fhandler_socket.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/fhandler_socket.cc')
-rw-r--r--winsup/cygwin/fhandler_socket.cc22
1 files changed, 17 insertions, 5 deletions
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index c0df1fb66..2a39d387e 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -911,17 +911,29 @@ fhandler_socket::bind (const struct sockaddr *name, int namelen)
(const char *) &on, sizeof on);
debug_printf ("%d = setsockopt (SO_EXCLUSIVEADDRUSE), %E", ret);
}
- else
+ else if (!wincap.has_enhanced_socket_security ())
{
debug_printf ("SO_REUSEADDR set");
/* There's a bug in SO_REUSEADDR handling in WinSock.
Per standards, we must not be able to reuse a complete
duplicate of a local TCP address (same IP, same port),
even if SO_REUSEADDR has been set. That's unfortunately
- possible in WinSock. So we're testing here if the local
- address is already in use and don't bind, if so. This
- only works for OSes with IP Helper support. */
- if (get_socket_type () == SOCK_STREAM
+ possible in WinSock.
+
+ So we're testing here if the local address is already in
+ use and don't bind, if so. This only works for OSes with
+ IP Helper support and is, of course, still prone to races.
+
+ However, we don't have to do this on systems supporting
+ "enhanced socket security" (2K3 and later). On these
+ systems the default binding behaviour is exactly as you'd
+ expect for SO_REUSEADDR, while setting SO_REUSEADDR re-enables
+ the wrong behaviour. So all we have to do on these newer
+ systems is never to set SO_REUSEADDR but only to note that
+ it has been set for the above SO_EXCLUSIVEADDRUSE setting.
+ See setsockopt() in net.cc. */
+ if (name->sa_family == AF_INET
+ && get_socket_type () == SOCK_STREAM
&& wincap.has_ip_helper_lib ()
&& address_in_use ((struct sockaddr_in *) name))
{