summaryrefslogtreecommitdiff
path: root/ACE/ace/SOCK_Acceptor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/ace/SOCK_Acceptor.cpp')
-rw-r--r--ACE/ace/SOCK_Acceptor.cpp51
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")));