Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2008-07-09 00:12:46 +0400
committerCorinna Vinschen <corinna@vinschen.de>2008-07-09 00:12:46 +0400
commit23672785ee63ee712b8ef05d0caa92e798683e53 (patch)
treee77921357b856c9fd859f298192d9b63cff7a98d
parentb8fbf5d4c4bb5998cadbc6031ada89799b69c291 (diff)
* fhandler_socket.cc (fhandler_socket::bind): Don't run explicit
local socket test in SO_REUSEADDR case on systems supporting enhanced socket security. Explain why. Only call address_in_use for AF_INET sockets. * net.cc (cygwin_setsockopt): Don't call setsockopt to set SO_REUSEADDR on systems supporting enhanced socket security. Add comment. * wincap.h (wincaps::has_enhanced_socket_security): New element. * wincap.cc: Implement above element throughout.
-rw-r--r--winsup/cygwin/ChangeLog11
-rw-r--r--winsup/cygwin/fhandler_socket.cc22
-rw-r--r--winsup/cygwin/net.cc12
-rw-r--r--winsup/cygwin/wincap.cc10
-rw-r--r--winsup/cygwin/wincap.h2
5 files changed, 50 insertions, 7 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 368ffb49e..9df84c2f5 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,16 @@
2008-07-08 Corinna Vinschen <corinna@vinschen.de>
+ * fhandler_socket.cc (fhandler_socket::bind): Don't run explicit
+ local socket test in SO_REUSEADDR case on systems supporting
+ enhanced socket security. Explain why. Only call address_in_use
+ for AF_INET sockets.
+ * net.cc (cygwin_setsockopt): Don't call setsockopt to set SO_REUSEADDR
+ on systems supporting enhanced socket security. Add comment.
+ * wincap.h (wincaps::has_enhanced_socket_security): New element.
+ * wincap.cc: Implement above element throughout.
+
+2008-07-08 Corinna Vinschen <corinna@vinschen.de>
+
* net.cc (ipv6_inited): Make NO_COPY.
2008-07-02 Corinna Vinschen <corinna@vinschen.de>
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))
{
diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc
index ded37aa05..8be32197c 100644
--- a/winsup/cygwin/net.cc
+++ b/winsup/cygwin/net.cc
@@ -649,8 +649,16 @@ cygwin_setsockopt (int fd, int level, int optname, const void *optval,
if (level == IPPROTO_IP && CYGWIN_VERSION_CHECK_FOR_USING_WINSOCK1_VALUES)
optname = convert_ws1_ip_optname (optname);
- res = setsockopt (fh->get_socket (), level, optname,
- (const char *) optval, optlen);
+ /* On systems supporting "enhanced socket security (2K3 and later),
+ the default behaviour of socket binding is equivalent to the POSIX
+ behaviour with SO_REUSEADDR. Setting SO_REUSEADDR would only result
+ in wrong behaviour. See also fhandler_socket::bind(). */
+ if (level == SOL_SOCKET && optname == SO_REUSEADDR
+ && wincap.has_enhanced_socket_security ())
+ res = 0;
+ else
+ res = setsockopt (fh->get_socket (), level, optname,
+ (const char *) optval, optlen);
if (optlen == 4)
syscall_printf ("setsockopt optval=%x", *(long *) optval);
diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc
index cf44dcc79..f2a3ef1fe 100644
--- a/winsup/cygwin/wincap.cc
+++ b/winsup/cygwin/wincap.cc
@@ -33,6 +33,7 @@ static NO_COPY wincaps wincap_unknown = {
has_disabled_user_tos_setting:false,
has_fileid_dirinfo:false,
has_exclusiveaddruse:false,
+ has_enhanced_socket_security:false,
has_buggy_restart_scan:false,
has_mandatory_integrity_control:false,
needs_logon_sid_in_sid_list:true,
@@ -64,6 +65,7 @@ static NO_COPY wincaps wincap_nt4 = {
has_disabled_user_tos_setting:false,
has_fileid_dirinfo:false,
has_exclusiveaddruse:false,
+ has_enhanced_socket_security:false,
has_buggy_restart_scan:false,
has_mandatory_integrity_control:false,
needs_logon_sid_in_sid_list:true,
@@ -95,6 +97,7 @@ static NO_COPY wincaps wincap_nt4sp4 = {
has_disabled_user_tos_setting:false,
has_fileid_dirinfo:false,
has_exclusiveaddruse:true,
+ has_enhanced_socket_security:false,
has_buggy_restart_scan:false,
has_mandatory_integrity_control:false,
needs_logon_sid_in_sid_list:true,
@@ -126,6 +129,7 @@ static NO_COPY wincaps wincap_2000 = {
has_disabled_user_tos_setting:true,
has_fileid_dirinfo:true,
has_exclusiveaddruse:true,
+ has_enhanced_socket_security:false,
has_buggy_restart_scan:true,
has_mandatory_integrity_control:false,
needs_logon_sid_in_sid_list:true,
@@ -157,6 +161,7 @@ static NO_COPY wincaps wincap_2000sp4 = {
has_disabled_user_tos_setting:true,
has_fileid_dirinfo:true,
has_exclusiveaddruse:true,
+ has_enhanced_socket_security:false,
has_buggy_restart_scan:true,
has_mandatory_integrity_control:false,
needs_logon_sid_in_sid_list:true,
@@ -188,6 +193,7 @@ static NO_COPY wincaps wincap_xp = {
has_disabled_user_tos_setting:true,
has_fileid_dirinfo:true,
has_exclusiveaddruse:true,
+ has_enhanced_socket_security:false,
has_buggy_restart_scan:false,
has_mandatory_integrity_control:false,
needs_logon_sid_in_sid_list:false,
@@ -219,6 +225,7 @@ static NO_COPY wincaps wincap_xpsp1 = {
has_disabled_user_tos_setting:true,
has_fileid_dirinfo:true,
has_exclusiveaddruse:true,
+ has_enhanced_socket_security:false,
has_buggy_restart_scan:false,
has_mandatory_integrity_control:false,
needs_logon_sid_in_sid_list:false,
@@ -250,6 +257,7 @@ static NO_COPY wincaps wincap_xpsp2 = {
has_disabled_user_tos_setting:true,
has_fileid_dirinfo:true,
has_exclusiveaddruse:true,
+ has_enhanced_socket_security:false,
has_buggy_restart_scan:false,
has_mandatory_integrity_control:false,
needs_logon_sid_in_sid_list:false,
@@ -281,6 +289,7 @@ static NO_COPY wincaps wincap_2003 = {
has_disabled_user_tos_setting:true,
has_fileid_dirinfo:true,
has_exclusiveaddruse:true,
+ has_enhanced_socket_security:true,
has_buggy_restart_scan:false,
has_mandatory_integrity_control:false,
needs_logon_sid_in_sid_list:false,
@@ -312,6 +321,7 @@ static NO_COPY wincaps wincap_vista = {
has_disabled_user_tos_setting:true,
has_fileid_dirinfo:true,
has_exclusiveaddruse:true,
+ has_enhanced_socket_security:true,
has_buggy_restart_scan:false,
has_mandatory_integrity_control:true,
needs_logon_sid_in_sid_list:false,
diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h
index 2035ecc5a..7028402c1 100644
--- a/winsup/cygwin/wincap.h
+++ b/winsup/cygwin/wincap.h
@@ -31,6 +31,7 @@ struct wincaps
unsigned has_disabled_user_tos_setting : 1;
unsigned has_fileid_dirinfo : 1;
unsigned has_exclusiveaddruse : 1;
+ unsigned has_enhanced_socket_security : 1;
unsigned has_buggy_restart_scan : 1;
unsigned has_mandatory_integrity_control : 1;
unsigned needs_logon_sid_in_sid_list : 1;
@@ -78,6 +79,7 @@ public:
bool IMPLEMENT (has_disabled_user_tos_setting)
bool IMPLEMENT (has_fileid_dirinfo)
bool IMPLEMENT (has_exclusiveaddruse)
+ bool IMPLEMENT (has_enhanced_socket_security)
bool IMPLEMENT (has_buggy_restart_scan)
bool IMPLEMENT (has_mandatory_integrity_control)
bool IMPLEMENT (needs_logon_sid_in_sid_list)