diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2006-01-29 12:23:44 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2006-01-29 12:23:44 +0000 |
commit | 5369605f4f7a8275f47e695856d42dc39bcbd3e3 (patch) | |
tree | b09aa426d96850b857d08f5ba13069c60e473101 /winsup/cygwin/fhandler_socket.cc | |
parent | 74d3f96faa7a547c4b9ebcfab3d3a850b0389202 (diff) | |
download | cygnal-5369605f4f7a8275f47e695856d42dc39bcbd3e3.tar.gz cygnal-5369605f4f7a8275f47e695856d42dc39bcbd3e3.tar.bz2 cygnal-5369605f4f7a8275f47e695856d42dc39bcbd3e3.zip |
* fhandler.h (class fhandler_socket): Add saw_reuseaddr status flag.
* fhandler_socket.cc (fhandler_socket::bind): Set socket to
SO_EXCLUSIVEADDRUSE if application didn't explicitely set SO_REUSEADDR
socket option, on systems supporting SO_EXCLUSIVEADDRUSE.
* net.cc (cygwin_setsockopt): Set fhandler's saw_reuseaddr status flag
if SO_REUSEADDR socket option has been successsfully set.
* wincap.h (wincaps::has_exclusiveaddruse): New element.
* wincap.cc: Implement above element throughout.
Diffstat (limited to 'winsup/cygwin/fhandler_socket.cc')
-rw-r--r-- | winsup/cygwin/fhandler_socket.cc | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index 2405471fe..b885b97db 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -661,10 +661,33 @@ fhandler_socket::bind (const struct sockaddr *name, int namelen) } #undef un_addr } - else if (::bind (get_socket (), name, namelen)) - set_winsock_errno (); else - res = 0; + { + /* If the application didn't explicitely call setsockopt (SO_REUSEADDR), + enforce exclusive local address use using the SO_EXCLUSIVEADDRUSE + socket option, to emulate POSIX socket behaviour more closely. + + KB 870562: Note that this option is only available since NT4 SP4. + Also note that a bug in Win2K SP1-3 and XP up to SP1 only enables + this option for users in the local administrators group. */ + if (wincap.has_exclusiveaddruse ()) + { + if (!saw_reuseaddr ()) + { + int on = 1; + int ret = ::setsockopt (get_socket (), SOL_SOCKET, + ~(SO_REUSEADDR), + (const char *) &on, sizeof on); + debug_printf ("%d = setsockopt (SO_EXCLUSIVEADDRUSE), %E", ret); + } + else + debug_printf ("SO_REUSEADDR set"); + } + if (::bind (get_socket (), name, namelen)) + set_winsock_errno (); + else + res = 0; + } out: return res; |