summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Mesnier <mesnier_p@ociweb.com>2006-09-19 19:52:17 +0000
committerPhil Mesnier <mesnier_p@ociweb.com>2006-09-19 19:52:17 +0000
commit233554954f74be05695a5459f787770d00613dc5 (patch)
treea6b744581f93597a9e79aa6948fefdee5282137b
parentf2f067b7d70e73dac8fb41be4bf6aa6b27f5fbc3 (diff)
downloadATCD-233554954f74be05695a5459f787770d00613dc5.tar.gz
Tue Sep 19 19:31:15 UTC 2006 Phil Mesnier <mesnier_p@ociweb.com>
-rw-r--r--TAO/ChangeLog17
-rw-r--r--TAO/tao/IIOP_Acceptor.cpp120
-rw-r--r--TAO/tao/IIOP_Acceptor.h18
3 files changed, 97 insertions, 58 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog
index ffad34f4dce..5f76856e965 100644
--- a/TAO/ChangeLog
+++ b/TAO/ChangeLog
@@ -1,3 +1,20 @@
+Tue Sep 19 19:31:15 UTC 2006 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * tao/IIOP_Acceptor.h:
+ * tao/IIOP_Acceptor.cpp:
+
+ Fix the treatment of explicitly defaulted endpoints on
+ potentially dual-stack hosts. Prior to this fix, expressing
+ certain forms of defaulted endpoints are inappropriately encoded
+ in the IOR using the literal string provided, rather than using
+ the probed interface addresses. When an endpoint is specified as
+ iiop://[::]:, iiop://[]:, or iiop://0.0.0.0:, this patch now
+ treats the first two as indicating that all IPv6 interfaces
+ should be included, but no IPv4. The third indicates that only
+ IPv4 interface addresses should be listed in the IOR. Using
+ iiop://: means that both IPv4 and IPv6 interface addresses are
+ to be included.
+
Mon Sep 18 23:53:29 UTC 2006 Iliyan Jeliazkov <iliyan@ociweb.com>
* tao/TAO_Internal.cpp:
diff --git a/TAO/tao/IIOP_Acceptor.cpp b/TAO/tao/IIOP_Acceptor.cpp
index 7dbb25e35b7..32744f4cbe2 100644
--- a/TAO/tao/IIOP_Acceptor.cpp
+++ b/TAO/tao/IIOP_Acceptor.cpp
@@ -308,8 +308,12 @@ TAO_IIOP_Acceptor::open (TAO_ORB_Core *orb_core,
ACE_CString specified_hostname;
ACE_INET_Addr addr;
+ int def_type = AF_UNSPEC;
- if (this->parse_address (address, addr, specified_hostname) == -1)
+ if (this->parse_address (address,
+ addr,
+ specified_hostname,
+ &def_type) == -1)
return -1;
if (specified_hostname.length() == 0)
@@ -319,7 +323,7 @@ TAO_IIOP_Acceptor::open (TAO_ORB_Core *orb_core,
// fully qualified domain name must be obtained.
// Check for multiple network interfaces.
- if (this->probe_interfaces (orb_core) == -1)
+ if (this->probe_interfaces (orb_core, def_type) == -1)
return -1;
return this->open_i (addr, reactor);
@@ -646,7 +650,8 @@ TAO_IIOP_Acceptor::hostname (TAO_ORB_Core *orb_core,
int
TAO_IIOP_Acceptor::parse_address (const char *address,
ACE_INET_Addr &addr,
- ACE_CString &specified_hostname)
+ ACE_CString &specified_hostname,
+ int *def_type)
{
{
ACE_INET_Addr tmp;
@@ -656,11 +661,13 @@ TAO_IIOP_Acceptor::parse_address (const char *address,
const char *port_separator_loc = ACE_OS::strchr (address, ':');
char tmp_host[MAXHOSTNAMELEN + 1];
-
-#if defined (ACE_HAS_IPV6)
- // IPv6 numeric address in host string?
+ tmp_host[0] = '\0';
+ bool host_defaulted = port_separator_loc == address;
bool ipv6_in_host = false;
+ if (def_type)
+ *def_type = AF_UNSPEC;
+#if defined (ACE_HAS_IPV6)
// Check if this is a (possibly) IPv6 supporting profile containing a
// numeric IPv6 address representation.
if ((this->version_.major > TAO_MIN_IPV6_IIOP_MAJOR ||
@@ -681,26 +688,49 @@ TAO_IIOP_Acceptor::parse_address (const char *address,
}
else
{
+ ipv6_in_host = true;
+ host_defaulted = (cp_pos == address+1) ||
+ (cp_pos == address+3 && address[1] == ':' && address[2] == ':');
if (cp_pos[1] == ':') // Look for a port
port_separator_loc = cp_pos + 1;
else
port_separator_loc = 0;
+ if (def_type)
+ *def_type = AF_INET6;
// Extract out just the host part of the address.
size_t const len = cp_pos - (address + 1);
ACE_OS::memcpy (tmp_host, address + 1, len);
tmp_host[len] = '\0';
- ipv6_in_host = true; // host string contains full IPv6 numeric address
}
}
+ else if (!host_defaulted)
+ {
+ // Extract out just the host part of the address.
+ size_t const len = port_separator_loc - address;
+ ACE_OS::memcpy (tmp_host, address, len);
+ tmp_host[len] = '\0';
+ }
#endif /* ACE_HAS_IPV6 */
-
- if (port_separator_loc == address)
+ if (!ipv6_in_host && !host_defaulted)
{
- // First convert the port into a usable form.
- if (addr.set (address + sizeof (':')) != 0)
+ if (addr.set((unsigned short)0,tmp_host) != 0)
return -1;
+ host_defaulted = addr.is_any();
+ if (def_type)
+ *def_type = AF_INET;
+ }
- this->default_address_.set_port_number (addr.get_port_number ());
+ if (host_defaulted)
+ {
+ // First convert the port into a usable form.
+ unsigned short portno = 0;
+ if (port_separator_loc != 0)
+ {
+ portno =
+ static_cast<u_short> (ACE_OS::atoi (port_separator_loc +
+ sizeof (':')));
+ }
+ this->default_address_.set_port_number (portno);
// Now reset the port and set the host.
if (addr.set (this->default_address_) != 0)
@@ -710,50 +740,23 @@ TAO_IIOP_Acceptor::parse_address (const char *address,
{
// The address is a hostname. No port was specified, so assume
// port zero (port will be chosen for us).
-#if defined (ACE_HAS_IPV6)
- if (ipv6_in_host)
- {
- if (addr.set ((unsigned short) 0, tmp_host) != 0)
- return -1;
-
- specified_hostname = tmp_host;
- }
- else
- {
-#endif /* ACE_HAS_IPV6 */
- if (addr.set ((unsigned short) 0, address) != 0)
- return -1;
-
- specified_hostname = address;
-#if defined (ACE_HAS_IPV6)
- }
-#endif /* ACE_HAS_IPV6 */
+ specified_hostname = tmp_host[0] == '\0' ? address : tmp_host;
+ if (addr.set ((unsigned short) 0,
+ specified_hostname.c_str()) != 0)
+ return -1;
}
else
{
// Host and port were specified.
-#if defined (ACE_HAS_IPV6)
- if (ipv6_in_host)
- {
- u_short port =
- static_cast<u_short> (ACE_OS::atoi (port_separator_loc + sizeof (':')));
-
- if (addr.set (port, tmp_host) != 0)
- return -1;
- }
- else
+ if (addr.set (address) != 0)
+ return -1;
+ if (tmp_host[0] == '\0')
{
-#endif /* ACE_HAS_IPV6 */
- if (addr.set (address) != 0)
- return -1;
-
// Extract out just the host part of the address.
const size_t len = port_separator_loc - address;
ACE_OS::memcpy (tmp_host, address, len);
tmp_host[len] = '\0';
-#if defined (ACE_HAS_IPV6)
}
-#endif /* ACE_HAS_IPV6 */
specified_hostname = tmp_host;
}
@@ -806,7 +809,7 @@ TAO_IIOP_Acceptor::dotted_decimal_address (ACE_INET_Addr &addr,
}
int
-TAO_IIOP_Acceptor::probe_interfaces (TAO_ORB_Core *orb_core)
+TAO_IIOP_Acceptor::probe_interfaces (TAO_ORB_Core *orb_core, int def_type)
{
// Extract the hostname for each network interface, and then cache
// it. The hostnames will then be used when creating a
@@ -873,14 +876,13 @@ TAO_IIOP_Acceptor::probe_interfaces (TAO_ORB_Core *orb_core)
ACE_Auto_Basic_Array_Ptr<ACE_INET_Addr> safe_if_addrs (if_addrs);
#if defined (ACE_HAS_IPV6)
+ bool ipv4_only = def_type == AF_INET;
+ bool ipv6_only = (def_type == AF_INET6) ||
+ orb_core->orb_params ()->connect_ipv6_only ();
#if defined (ACE_WIN32)
- bool ipv4_only = this->default_address_.get_type () == AF_INET;
- bool ipv6_only =
- this->default_address_.get_type () == AF_INET6 || orb_core->orb_params ()->connect_ipv6_only ();
-#else
- bool ipv4_only = false;
- bool ipv6_only = orb_core->orb_params ()->connect_ipv6_only ();
-#endif
+ ipv4_only |= this->default_address_.get_type () == AF_INET;
+ ipv6_only |= this->default_address_.get_type () == AF_INET6;
+#endif /* ACE_WIN32 */
// If the loopback interface is the only interface then include it
// in the list of interfaces to query for a hostname, otherwise
// exclude it from the list.
@@ -930,6 +932,16 @@ TAO_IIOP_Acceptor::probe_interfaces (TAO_ORB_Core *orb_core)
this->endpoint_count_ = static_cast<CORBA::ULong> (if_cnt - lo_cnt);
#endif /* !ACE_HAS_IPV6 */
+ if (this->endpoint_count_ == 0)
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT("(%P|%t) TAO_IIOP_Acceptor::probe_interfaces ")
+ ACE_TEXT("found no usable addresses, def_type = %d\n"),
+ def_type));
+ return -1;
+ }
+
ACE_NEW_RETURN (this->addrs_,
ACE_INET_Addr[this->endpoint_count_],
-1);
diff --git a/TAO/tao/IIOP_Acceptor.h b/TAO/tao/IIOP_Acceptor.h
index 494edae196a..ea40333fa27 100644
--- a/TAO/tao/IIOP_Acceptor.h
+++ b/TAO/tao/IIOP_Acceptor.h
@@ -133,13 +133,18 @@ protected:
/**
* Helper method
- * Clear out 'addr' & 'specified_hostname' and initialize them
- * based upon 'address'.
+ * Clear out 'addr' & 'specified_hostname' and initialize them based
+ * upon 'address'. If a non-zero pointer is passed in for def_type,
+ * this will be set to AF_INET6 if IPv6 support is enabled and
+ * supplied hostname is either [] or [::]. It will be set to AF_INET
+ * if the hostname is 0.0.0.0, otherwise it is set to
+ * AF_UNSPEC. This value is then passed to probe_interfaces by open.
*/
int
parse_address (const char *address,
ACE_INET_Addr &addr,
- ACE_CString &specified_hostname);
+ ACE_CString &specified_hostname,
+ int *def_type = 0);
/**
* Set the host name for the given address using the dotted decimal
@@ -162,8 +167,13 @@ protected:
* interface. The port for each initialized ACE_INET_Addr will be
* set in the open_i() method. This method only gets invoked when
* no explicit hostname is provided in the specified endpoint.
+ *
+ * The optional argument def_type is used to constrain the resulting
+ * list of interfaces to be either only IPv6 or IPv4, or both, when
+ * ACE_HAS_IPV6 is enabled and the source endpoint was an explicitly
+ * declared wildcard.
*/
- int probe_interfaces (TAO_ORB_Core *orb_core);
+ int probe_interfaces (TAO_ORB_Core *orb_core, int def_type = AF_UNSPEC);
/**
* Parse protocol specific options.