diff options
Diffstat (limited to 'ACE/ace/SOCK_Acceptor.cpp')
-rw-r--r-- | ACE/ace/SOCK_Acceptor.cpp | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/ACE/ace/SOCK_Acceptor.cpp b/ACE/ace/SOCK_Acceptor.cpp index 9128232fed2..c329029e33a 100644 --- a/ACE/ace/SOCK_Acceptor.cpp +++ b/ACE/ace/SOCK_Acceptor.cpp @@ -220,12 +220,15 @@ ACE_SOCK_Acceptor::dump (void) const int ACE_SOCK_Acceptor::shared_open (const ACE_Addr &local_sap, int protocol_family, - int backlog) + int backlog, + int ipv6_only) { ACE_TRACE ("ACE_SOCK_Acceptor::shared_open"); int error = 0; -#if defined (ACE_HAS_IPV6) +#if !defined (ACE_HAS_IPV6) || (!defined (IPPROTO_IPV6) || !defined (IPV6_V6ONLY)) + ACE_UNUSED_ARG (ipv6_only); +#else /* !defined (ACE_HAS_IPV6) || (!defined (IPPROTO_IPV6) || !defined (IPV6_V6ONLY)) */ if (protocol_family == PF_INET6) { sockaddr_in6 local_inet6_addr; @@ -241,7 +244,23 @@ ACE_SOCK_Acceptor::shared_open (const ACE_Addr &local_sap, } else local_inet6_addr = *reinterpret_cast<sockaddr_in6 *> (local_sap.get_addr ()); - + /* + * Handle IPv6-only requests. On Windows, v6-only is the default + * unless it is turned off. On Linux, v4/v6 dual is the default + * unless v6-only is turned on. + * This must be done before attempting to bind the address. + * On Windows older than Vista this will fail. + */ +# if defined (IPPROTO_IPV6) && defined (IPV6_V6ONLY) + int setting = !!ipv6_only; + if (-1 == ACE_OS::setsockopt (this->get_handle (), + IPPROTO_IPV6, + IPV6_V6ONLY, + (char *)&setting, + sizeof (setting))) + error = 1; + else +# endif /* IPPROTO_V6 && IPV6_ONLY */ // We probably don't need a bind_port written here. // There are currently no supported OS's that define // ACE_LACKS_WILDCARD_BIND. @@ -251,7 +270,7 @@ ACE_SOCK_Acceptor::shared_open (const ACE_Addr &local_sap, error = 1; } else -#endif +#endif /* !defined (ACE_HAS_IPV6) || (!defined (IPPROTO_IPV6) || !defined (IPV6_V6ONLY)) */ if (protocol_family == PF_INET) { sockaddr_in local_inet_addr; @@ -301,7 +320,8 @@ ACE_SOCK_Acceptor::open (const ACE_Addr &local_sap, int reuse_addr, int protocol_family, int backlog, - int protocol) + int protocol, + int ipv6_only) { ACE_TRACE ("ACE_SOCK_Acceptor::open"); @@ -319,7 +339,8 @@ ACE_SOCK_Acceptor::open (const ACE_Addr &local_sap, else return this->shared_open (local_sap, protocol_family, - backlog); + backlog, + ipv6_only); } ACE_SOCK_Acceptor::ACE_SOCK_Acceptor (const ACE_Addr &local_sap, @@ -329,7 +350,8 @@ ACE_SOCK_Acceptor::ACE_SOCK_Acceptor (const ACE_Addr &local_sap, int reuse_addr, int protocol_family, int backlog, - int protocol) + int protocol, + int ipv6_only) { ACE_TRACE ("ACE_SOCK_Acceptor::ACE_SOCK_Acceptor"); if (this->open (local_sap, @@ -339,7 +361,8 @@ ACE_SOCK_Acceptor::ACE_SOCK_Acceptor (const ACE_Addr &local_sap, reuse_addr, protocol_family, backlog, - protocol) == -1) + protocol, + ipv6_only) == -1) ACELIB_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("ACE_SOCK_Acceptor"))); @@ -352,7 +375,8 @@ ACE_SOCK_Acceptor::open (const ACE_Addr &local_sap, int reuse_addr, int protocol_family, int backlog, - int protocol) + int protocol, + int ipv6_only) { ACE_TRACE ("ACE_SOCK_Acceptor::open"); @@ -375,7 +399,8 @@ ACE_SOCK_Acceptor::open (const ACE_Addr &local_sap, else return this->shared_open (local_sap, protocol_family, - backlog); + backlog, + ipv6_only); } // General purpose routine for performing server ACE_SOCK creation. @@ -384,14 +409,16 @@ ACE_SOCK_Acceptor::ACE_SOCK_Acceptor (const ACE_Addr &local_sap, int reuse_addr, int protocol_family, int backlog, - int protocol) + int protocol, + int ipv6_only) { ACE_TRACE ("ACE_SOCK_Acceptor::ACE_SOCK_Acceptor"); if (this->open (local_sap, reuse_addr, protocol_family, backlog, - protocol) == -1) + protocol, + ipv6_only) == -1) ACELIB_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("ACE_SOCK_Acceptor"))); |