* 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.
This commit is contained in:
parent
b8fbf5d4c4
commit
23672785ee
|
@ -1,3 +1,14 @@
|
||||||
|
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>
|
2008-07-08 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* net.cc (ipv6_inited): Make NO_COPY.
|
* net.cc (ipv6_inited): Make NO_COPY.
|
||||||
|
|
|
@ -911,17 +911,29 @@ fhandler_socket::bind (const struct sockaddr *name, int namelen)
|
||||||
(const char *) &on, sizeof on);
|
(const char *) &on, sizeof on);
|
||||||
debug_printf ("%d = setsockopt (SO_EXCLUSIVEADDRUSE), %E", ret);
|
debug_printf ("%d = setsockopt (SO_EXCLUSIVEADDRUSE), %E", ret);
|
||||||
}
|
}
|
||||||
else
|
else if (!wincap.has_enhanced_socket_security ())
|
||||||
{
|
{
|
||||||
debug_printf ("SO_REUSEADDR set");
|
debug_printf ("SO_REUSEADDR set");
|
||||||
/* There's a bug in SO_REUSEADDR handling in WinSock.
|
/* There's a bug in SO_REUSEADDR handling in WinSock.
|
||||||
Per standards, we must not be able to reuse a complete
|
Per standards, we must not be able to reuse a complete
|
||||||
duplicate of a local TCP address (same IP, same port),
|
duplicate of a local TCP address (same IP, same port),
|
||||||
even if SO_REUSEADDR has been set. That's unfortunately
|
even if SO_REUSEADDR has been set. That's unfortunately
|
||||||
possible in WinSock. So we're testing here if the local
|
possible in WinSock.
|
||||||
address is already in use and don't bind, if so. This
|
|
||||||
only works for OSes with IP Helper support. */
|
So we're testing here if the local address is already in
|
||||||
if (get_socket_type () == SOCK_STREAM
|
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 ()
|
&& wincap.has_ip_helper_lib ()
|
||||||
&& address_in_use ((struct sockaddr_in *) name))
|
&& address_in_use ((struct sockaddr_in *) name))
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)
|
if (level == IPPROTO_IP && CYGWIN_VERSION_CHECK_FOR_USING_WINSOCK1_VALUES)
|
||||||
optname = convert_ws1_ip_optname (optname);
|
optname = convert_ws1_ip_optname (optname);
|
||||||
|
|
||||||
res = setsockopt (fh->get_socket (), level, optname,
|
/* On systems supporting "enhanced socket security (2K3 and later),
|
||||||
(const char *) optval, optlen);
|
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)
|
if (optlen == 4)
|
||||||
syscall_printf ("setsockopt optval=%x", *(long *) optval);
|
syscall_printf ("setsockopt optval=%x", *(long *) optval);
|
||||||
|
|
|
@ -33,6 +33,7 @@ static NO_COPY wincaps wincap_unknown = {
|
||||||
has_disabled_user_tos_setting:false,
|
has_disabled_user_tos_setting:false,
|
||||||
has_fileid_dirinfo:false,
|
has_fileid_dirinfo:false,
|
||||||
has_exclusiveaddruse:false,
|
has_exclusiveaddruse:false,
|
||||||
|
has_enhanced_socket_security:false,
|
||||||
has_buggy_restart_scan:false,
|
has_buggy_restart_scan:false,
|
||||||
has_mandatory_integrity_control:false,
|
has_mandatory_integrity_control:false,
|
||||||
needs_logon_sid_in_sid_list:true,
|
needs_logon_sid_in_sid_list:true,
|
||||||
|
@ -64,6 +65,7 @@ static NO_COPY wincaps wincap_nt4 = {
|
||||||
has_disabled_user_tos_setting:false,
|
has_disabled_user_tos_setting:false,
|
||||||
has_fileid_dirinfo:false,
|
has_fileid_dirinfo:false,
|
||||||
has_exclusiveaddruse:false,
|
has_exclusiveaddruse:false,
|
||||||
|
has_enhanced_socket_security:false,
|
||||||
has_buggy_restart_scan:false,
|
has_buggy_restart_scan:false,
|
||||||
has_mandatory_integrity_control:false,
|
has_mandatory_integrity_control:false,
|
||||||
needs_logon_sid_in_sid_list:true,
|
needs_logon_sid_in_sid_list:true,
|
||||||
|
@ -95,6 +97,7 @@ static NO_COPY wincaps wincap_nt4sp4 = {
|
||||||
has_disabled_user_tos_setting:false,
|
has_disabled_user_tos_setting:false,
|
||||||
has_fileid_dirinfo:false,
|
has_fileid_dirinfo:false,
|
||||||
has_exclusiveaddruse:true,
|
has_exclusiveaddruse:true,
|
||||||
|
has_enhanced_socket_security:false,
|
||||||
has_buggy_restart_scan:false,
|
has_buggy_restart_scan:false,
|
||||||
has_mandatory_integrity_control:false,
|
has_mandatory_integrity_control:false,
|
||||||
needs_logon_sid_in_sid_list:true,
|
needs_logon_sid_in_sid_list:true,
|
||||||
|
@ -126,6 +129,7 @@ static NO_COPY wincaps wincap_2000 = {
|
||||||
has_disabled_user_tos_setting:true,
|
has_disabled_user_tos_setting:true,
|
||||||
has_fileid_dirinfo:true,
|
has_fileid_dirinfo:true,
|
||||||
has_exclusiveaddruse:true,
|
has_exclusiveaddruse:true,
|
||||||
|
has_enhanced_socket_security:false,
|
||||||
has_buggy_restart_scan:true,
|
has_buggy_restart_scan:true,
|
||||||
has_mandatory_integrity_control:false,
|
has_mandatory_integrity_control:false,
|
||||||
needs_logon_sid_in_sid_list:true,
|
needs_logon_sid_in_sid_list:true,
|
||||||
|
@ -157,6 +161,7 @@ static NO_COPY wincaps wincap_2000sp4 = {
|
||||||
has_disabled_user_tos_setting:true,
|
has_disabled_user_tos_setting:true,
|
||||||
has_fileid_dirinfo:true,
|
has_fileid_dirinfo:true,
|
||||||
has_exclusiveaddruse:true,
|
has_exclusiveaddruse:true,
|
||||||
|
has_enhanced_socket_security:false,
|
||||||
has_buggy_restart_scan:true,
|
has_buggy_restart_scan:true,
|
||||||
has_mandatory_integrity_control:false,
|
has_mandatory_integrity_control:false,
|
||||||
needs_logon_sid_in_sid_list:true,
|
needs_logon_sid_in_sid_list:true,
|
||||||
|
@ -188,6 +193,7 @@ static NO_COPY wincaps wincap_xp = {
|
||||||
has_disabled_user_tos_setting:true,
|
has_disabled_user_tos_setting:true,
|
||||||
has_fileid_dirinfo:true,
|
has_fileid_dirinfo:true,
|
||||||
has_exclusiveaddruse:true,
|
has_exclusiveaddruse:true,
|
||||||
|
has_enhanced_socket_security:false,
|
||||||
has_buggy_restart_scan:false,
|
has_buggy_restart_scan:false,
|
||||||
has_mandatory_integrity_control:false,
|
has_mandatory_integrity_control:false,
|
||||||
needs_logon_sid_in_sid_list: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_disabled_user_tos_setting:true,
|
||||||
has_fileid_dirinfo:true,
|
has_fileid_dirinfo:true,
|
||||||
has_exclusiveaddruse:true,
|
has_exclusiveaddruse:true,
|
||||||
|
has_enhanced_socket_security:false,
|
||||||
has_buggy_restart_scan:false,
|
has_buggy_restart_scan:false,
|
||||||
has_mandatory_integrity_control:false,
|
has_mandatory_integrity_control:false,
|
||||||
needs_logon_sid_in_sid_list: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_disabled_user_tos_setting:true,
|
||||||
has_fileid_dirinfo:true,
|
has_fileid_dirinfo:true,
|
||||||
has_exclusiveaddruse:true,
|
has_exclusiveaddruse:true,
|
||||||
|
has_enhanced_socket_security:false,
|
||||||
has_buggy_restart_scan:false,
|
has_buggy_restart_scan:false,
|
||||||
has_mandatory_integrity_control:false,
|
has_mandatory_integrity_control:false,
|
||||||
needs_logon_sid_in_sid_list: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_disabled_user_tos_setting:true,
|
||||||
has_fileid_dirinfo:true,
|
has_fileid_dirinfo:true,
|
||||||
has_exclusiveaddruse:true,
|
has_exclusiveaddruse:true,
|
||||||
|
has_enhanced_socket_security:true,
|
||||||
has_buggy_restart_scan:false,
|
has_buggy_restart_scan:false,
|
||||||
has_mandatory_integrity_control:false,
|
has_mandatory_integrity_control:false,
|
||||||
needs_logon_sid_in_sid_list: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_disabled_user_tos_setting:true,
|
||||||
has_fileid_dirinfo:true,
|
has_fileid_dirinfo:true,
|
||||||
has_exclusiveaddruse:true,
|
has_exclusiveaddruse:true,
|
||||||
|
has_enhanced_socket_security:true,
|
||||||
has_buggy_restart_scan:false,
|
has_buggy_restart_scan:false,
|
||||||
has_mandatory_integrity_control:true,
|
has_mandatory_integrity_control:true,
|
||||||
needs_logon_sid_in_sid_list:false,
|
needs_logon_sid_in_sid_list:false,
|
||||||
|
|
|
@ -31,6 +31,7 @@ struct wincaps
|
||||||
unsigned has_disabled_user_tos_setting : 1;
|
unsigned has_disabled_user_tos_setting : 1;
|
||||||
unsigned has_fileid_dirinfo : 1;
|
unsigned has_fileid_dirinfo : 1;
|
||||||
unsigned has_exclusiveaddruse : 1;
|
unsigned has_exclusiveaddruse : 1;
|
||||||
|
unsigned has_enhanced_socket_security : 1;
|
||||||
unsigned has_buggy_restart_scan : 1;
|
unsigned has_buggy_restart_scan : 1;
|
||||||
unsigned has_mandatory_integrity_control : 1;
|
unsigned has_mandatory_integrity_control : 1;
|
||||||
unsigned needs_logon_sid_in_sid_list : 1;
|
unsigned needs_logon_sid_in_sid_list : 1;
|
||||||
|
@ -78,6 +79,7 @@ public:
|
||||||
bool IMPLEMENT (has_disabled_user_tos_setting)
|
bool IMPLEMENT (has_disabled_user_tos_setting)
|
||||||
bool IMPLEMENT (has_fileid_dirinfo)
|
bool IMPLEMENT (has_fileid_dirinfo)
|
||||||
bool IMPLEMENT (has_exclusiveaddruse)
|
bool IMPLEMENT (has_exclusiveaddruse)
|
||||||
|
bool IMPLEMENT (has_enhanced_socket_security)
|
||||||
bool IMPLEMENT (has_buggy_restart_scan)
|
bool IMPLEMENT (has_buggy_restart_scan)
|
||||||
bool IMPLEMENT (has_mandatory_integrity_control)
|
bool IMPLEMENT (has_mandatory_integrity_control)
|
||||||
bool IMPLEMENT (needs_logon_sid_in_sid_list)
|
bool IMPLEMENT (needs_logon_sid_in_sid_list)
|
||||||
|
|
Loading…
Reference in New Issue