summaryrefslogtreecommitdiff
path: root/TAO/tao/Strategies
diff options
context:
space:
mode:
authorvridosh <vridosh@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2007-07-12 12:06:21 +0000
committervridosh <vridosh@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2007-07-12 12:06:21 +0000
commit1d2221460dedfedc6f93a9697098d0d63eb2df86 (patch)
tree889690c6d78984a69c659d4931e309ced61303e4 /TAO/tao/Strategies
parentebc8d8113bd7dc657ec3db3600718721d6364deb (diff)
downloadATCD-1d2221460dedfedc6f93a9697098d0d63eb2df86.tar.gz
ChangeLogTag: Thu Jul 12 11:29:39 UTC 2007 Vadym Ridosh <vridosh@prismtech.com>
Diffstat (limited to 'TAO/tao/Strategies')
-rw-r--r--TAO/tao/Strategies/DIOP_Acceptor.cpp459
-rw-r--r--TAO/tao/Strategies/DIOP_Acceptor.h38
-rw-r--r--TAO/tao/Strategies/DIOP_Acceptor.inl12
-rw-r--r--TAO/tao/Strategies/DIOP_Connection_Handler.cpp72
-rw-r--r--TAO/tao/Strategies/DIOP_Connector.cpp142
-rw-r--r--TAO/tao/Strategies/DIOP_Connector.h14
-rw-r--r--TAO/tao/Strategies/DIOP_Endpoint.cpp137
-rw-r--r--TAO/tao/Strategies/DIOP_Endpoint.h12
-rw-r--r--TAO/tao/Strategies/DIOP_Profile.cpp236
-rw-r--r--TAO/tao/Strategies/DIOP_Transport.cpp9
10 files changed, 895 insertions, 236 deletions
diff --git a/TAO/tao/Strategies/DIOP_Acceptor.cpp b/TAO/tao/Strategies/DIOP_Acceptor.cpp
index 937d738068d..84d7d84c1fb 100644
--- a/TAO/tao/Strategies/DIOP_Acceptor.cpp
+++ b/TAO/tao/Strategies/DIOP_Acceptor.cpp
@@ -36,6 +36,11 @@ TAO_DIOP_Acceptor::TAO_DIOP_Acceptor (CORBA::Boolean flag)
version_ (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR),
orb_core_ (0),
lite_flag_ (flag),
+#if defined (ACE_HAS_IPV6)
+ default_address_ (static_cast<unsigned short> (0), ACE_IPV6_ANY, AF_INET6),
+#else
+ default_address_ (static_cast<unsigned short> (0), static_cast<ACE_UINT32> (INADDR_ANY)),
+#endif /* ACE_HAS_IPV6 */
connection_handler_ (0)
{
}
@@ -48,7 +53,7 @@ TAO_DIOP_Acceptor::~TAO_DIOP_Acceptor (void)
delete [] this->addrs_;
- for (size_t i = 0; i < this->endpoint_count_; ++i)
+ for (CORBA::ULong i = 0; i < this->endpoint_count_; ++i)
CORBA::string_free (this->hosts_[i]);
delete [] this->hosts_;
@@ -68,7 +73,8 @@ TAO_DIOP_Acceptor::create_profile (const TAO::ObjectKey & object_key,
// Check if multiple endpoints should be put in one profile or if
// they should be spread across multiple profiles.
- if (priority == TAO_INVALID_PRIORITY)
+ if (priority == TAO_INVALID_PRIORITY &&
+ this->orb_core_->orb_params ()->shared_profile () == 0)
return this->create_new_profile (object_key, mprofile, priority);
else
return this->create_shared_profile (object_key, mprofile, priority);
@@ -80,14 +86,20 @@ TAO_DIOP_Acceptor::create_new_profile (const TAO::ObjectKey &object_key,
CORBA::Short priority)
{
// Adding this->endpoint_count_ to the TAO_MProfile.
- int const count = mprofile.profile_count ();
+ int count = mprofile.profile_count ();
if ((mprofile.size () - count) < this->endpoint_count_
&& mprofile.grow (count + this->endpoint_count_) == -1)
return -1;
// Create a profile for each acceptor endpoint.
- for (size_t i = 0; i < this->endpoint_count_; ++i)
+ for (CORBA::ULong i = 0; i < this->endpoint_count_; ++i)
{
+ // Skip if the host name
+ if (i > 0
+ && (this->addrs_[i].get_port_number () == this->addrs_[0].get_port_number ())
+ && ACE_OS::strcmp (this->hosts_[i], this->hosts_[0]) == 0)
+ continue;
+
TAO_DIOP_Profile *pfile = 0;
ACE_NEW_RETURN (pfile,
TAO_DIOP_Profile (this->hosts_[i],
@@ -115,9 +127,9 @@ TAO_DIOP_Acceptor::create_new_profile (const TAO::ObjectKey &object_key,
pfile->tagged_components ().set_orb_type (TAO_ORB_TYPE);
- TAO_Codeset_Manager *csm = this->orb_core_->codeset_manager();
+ TAO_Codeset_Manager *csm = this->orb_core_->codeset_manager ();
if (csm)
- csm->set_codeset(pfile->tagged_components());
+ csm->set_codeset (pfile->tagged_components ());
}
return 0;
@@ -128,9 +140,9 @@ TAO_DIOP_Acceptor::create_shared_profile (const TAO::ObjectKey &object_key,
TAO_MProfile &mprofile,
CORBA::Short priority)
{
- size_t index = 0;
+ CORBA::ULong index = 0;
TAO_Profile *pfile = 0;
- TAO_DIOP_Profile *iiop_profile = 0;
+ TAO_DIOP_Profile *diop_profile = 0;
// First see if <mprofile> already contains a DIOP profile.
for (TAO_PHandle i = 0; i != mprofile.profile_count (); ++i)
@@ -138,16 +150,16 @@ TAO_DIOP_Acceptor::create_shared_profile (const TAO::ObjectKey &object_key,
pfile = mprofile.get_profile (i);
if (pfile->tag () == TAO_TAG_DIOP_PROFILE)
{
- iiop_profile = dynamic_cast<TAO_DIOP_Profile *> (pfile);
+ diop_profile = dynamic_cast<TAO_DIOP_Profile *> (pfile);
break;
}
}
// If <mprofile> doesn't contain a DIOP_Profile, we need to create
// one.
- if (iiop_profile == 0)
+ if (diop_profile == 0)
{
- ACE_NEW_RETURN (iiop_profile,
+ ACE_NEW_RETURN (diop_profile,
TAO_DIOP_Profile (this->hosts_[0],
this->addrs_[0].get_port_number (),
object_key,
@@ -155,22 +167,22 @@ TAO_DIOP_Acceptor::create_shared_profile (const TAO::ObjectKey &object_key,
this->version_,
this->orb_core_),
-1);
- iiop_profile->endpoint ()->priority (priority);
+ diop_profile->endpoint ()->priority (priority);
- if (mprofile.give_profile (iiop_profile) == -1)
+ if (mprofile.give_profile (diop_profile) == -1)
{
- iiop_profile->_decr_refcnt ();
- iiop_profile = 0;
+ diop_profile->_decr_refcnt ();
+ diop_profile = 0;
return -1;
}
if (this->orb_core_->orb_params ()->std_profile_components () != 0
&& (this->version_.major >= 1 && this->version_.minor >= 1))
{
- iiop_profile->tagged_components ().set_orb_type (TAO_ORB_TYPE);
- TAO_Codeset_Manager *csm = this->orb_core_->codeset_manager();
+ diop_profile->tagged_components ().set_orb_type (TAO_ORB_TYPE);
+ TAO_Codeset_Manager *csm = this->orb_core_->codeset_manager ();
if (csm)
- csm->set_codeset(pfile->tagged_components());
+ csm->set_codeset (pfile->tagged_components ());
}
index = 1;
@@ -181,6 +193,11 @@ TAO_DIOP_Acceptor::create_shared_profile (const TAO::ObjectKey &object_key,
index < this->endpoint_count_;
++index)
{
+ if (index > 0 &&
+ this->addrs_[index].get_port_number () == this->addrs_[0].get_port_number () &&
+ ACE_OS::strcmp (this->hosts_[index], this->hosts_[0]) == 0)
+ continue;
+
TAO_DIOP_Endpoint *endpoint = 0;
ACE_NEW_RETURN (endpoint,
TAO_DIOP_Endpoint (this->hosts_[index],
@@ -188,7 +205,7 @@ TAO_DIOP_Acceptor::create_shared_profile (const TAO::ObjectKey &object_key,
this->addrs_[index]),
-1);
endpoint->priority (priority);
- iiop_profile->add_endpoint (endpoint);
+ diop_profile->add_endpoint (endpoint);
}
return 0;
@@ -204,7 +221,7 @@ TAO_DIOP_Acceptor::is_collocated (const TAO_Endpoint *endpoint)
if (endp == 0)
return 0;
- for (size_t i = 0; i < this->endpoint_count_; ++i)
+ for (CORBA::ULong i = 0; i < this->endpoint_count_; ++i)
{
// compare the port and host name. Please do *NOT* optimize
// this code by comparing the IP address instead. That would
@@ -212,8 +229,8 @@ TAO_DIOP_Acceptor::is_collocated (const TAO_Endpoint *endpoint)
//
// http://deuce.doc.wustl.edu/bugzilla/show_bug.cgi?id=1220
//
- if (endp->port() == this->addrs_[i].get_port_number()
- && ACE_OS::strcmp(endp->host(), this->hosts_[i]) == 0)
+ if (endp->port () == this->addrs_[i].get_port_number ()
+ && ACE_OS::strcmp (endp->host (), this->hosts_[i]) == 0)
return 1; // Collocated
}
@@ -242,7 +259,7 @@ TAO_DIOP_Acceptor::open (TAO_ORB_Core *orb_core,
// This is bad mojo, i.e. an internal TAO error.
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("TAO (%P|%t) - ")
- ACE_TEXT ("DIOP_Acceptor::open - ")
+ ACE_TEXT ("DIOP_Acceptor::open, ")
ACE_TEXT ("hostname already set\n\n")),
-1);
}
@@ -257,55 +274,57 @@ TAO_DIOP_Acceptor::open (TAO_ORB_Core *orb_core,
if (this->parse_options (options) == -1)
return -1;
+ ACE_CString specified_hostname;
ACE_INET_Addr addr;
+ int def_type = AF_UNSPEC;
- const char *port_separator_loc = ACE_OS::strchr (address, ':');
- const char *specified_hostname = 0;
- char tmp_host[MAXHOSTNAMELEN + 1];
+ if (this->parse_address (address,
+ addr,
+ specified_hostname,
+ &def_type) == -1)
+ return -1;
- if (port_separator_loc == address)
+ if (specified_hostname.length () == 0)
{
// The address is a port number or port name. No hostname was
// specified. The hostname for each network interface and the
// 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;
- // First convert the port into a usable form.
- if (addr.set (address + sizeof (':')) != 0)
- return -1;
+ // Probe interfaces has a side effect of potentially modifying
+ // the default address, since that is where the address family
+ // is considered.
+ addr.set (this->default_address_);
- // Now reset the port and set the host.
- if (addr.set (addr.get_port_number (),
- static_cast<ACE_UINT32> (INADDR_ANY),
- 1) != 0)
- return -1;
- else
- return this->open_i (addr, reactor);
+ return this->open_i (addr,
+ reactor);
}
- else if (port_separator_loc == 0)
- {
- // The address is a hostname. No port was specified, so assume
- // port zero (port will be chosen for us).
- if (addr.set ((unsigned short) 0, address) != 0)
- return -1;
- specified_hostname = address;
- }
- else
+#if defined (ACE_HAS_IPV6)
+ // Check for violation of ORBConnectIPV6Only option
+ if (this->orb_core_->orb_params ()->connect_ipv6_only () &&
+ (addr.get_type () != AF_INET6 ||
+ addr.is_ipv4_mapped_ipv6 ()))
{
- // Host and port were specified.
- if (addr.set (address) != 0)
- return -1;
-
- // Extract out just the host part of the address.
- size_t len = port_separator_loc - address;
- ACE_OS::memcpy (tmp_host, address, len);
- tmp_host[len] = '\0';
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) - ")
+ ACE_TEXT ("DIOP_Acceptor::open, ")
+ ACE_TEXT ("non-IPv6 endpoints not allowed when ")
+ ACE_TEXT ("connect_ipv6_only is set\n\n")),
+ -1);
+ }
+#endif /* ACE_HAS_IPV6 */
- specified_hostname = tmp_host;
+ if (TAO_debug_level > 2)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - ")
+ ACE_TEXT ("DIOP_Acceptor::open, specified host=%s:%d\n"),
+ (specified_hostname.length () == 0 ? "<null>" : specified_hostname.c_str ()),
+ addr.get_port_number ()));
}
this->endpoint_count_ = 1; // Only one hostname to store
@@ -323,7 +342,7 @@ TAO_DIOP_Acceptor::open (TAO_ORB_Core *orb_core,
if (this->hostname (orb_core,
addr,
this->hosts_[0],
- specified_hostname) != 0)
+ specified_hostname.c_str ()) != 0)
return -1;
// Copy the addr. The port is (re)set in
@@ -355,7 +374,7 @@ TAO_DIOP_Acceptor::open_default (TAO_ORB_Core *orb_core,
-1);
}
- if (major >=0 && minor >= 0)
+ if (major >= 0 && minor >= 0)
this->version_.set_version (static_cast<CORBA::Octet> (major),
static_cast<CORBA::Octet> (minor));
@@ -372,9 +391,7 @@ TAO_DIOP_Acceptor::open_default (TAO_ORB_Core *orb_core,
// address.
ACE_INET_Addr addr;
- if (addr.set (static_cast<unsigned short> (0),
- static_cast<ACE_UINT32> (INADDR_ANY),
- 1) != 0)
+ if (addr.set (this->default_address_) != 0)
return -1;
return this->open_i (addr, reactor);
@@ -412,7 +429,7 @@ TAO_DIOP_Acceptor::open_i (const ACE_INET_Addr& addr,
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("TAO (%P|%t) DIOP_Acceptor::open_i, ")
ACE_TEXT ("%p"),
- ACE_TEXT ("cannot get local addr\n")));
+ ACE_TEXT ("cannot get local addr\n\n")));
return -1;
}
@@ -420,13 +437,15 @@ TAO_DIOP_Acceptor::open_i (const ACE_INET_Addr& addr,
// interface then the endpoint created on each interface will be on
// the same port. This is how a wildcard socket bind() is supposed
// to work.
- u_short const port = address.get_port_number ();
- for (size_t j = 0; j < this->endpoint_count_; ++j)
+ unsigned short port = address.get_port_number ();
+ for (CORBA::ULong j = 0; j < this->endpoint_count_; ++j)
this->addrs_[j].set_port_number (port, 1);
+ this->default_address_.set_port_number (port);
+
if (TAO_debug_level > 5)
{
- for (size_t i = 0; i < this->endpoint_count_; ++i)
+ for (CORBA::ULong i = 0; i < this->endpoint_count_; ++i)
{
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("TAO (%P|%t) - DIOP_Acceptor::open_i, ")
@@ -451,8 +470,7 @@ TAO_DIOP_Acceptor::hostname (TAO_ORB_Core *orb_core,
// just return ours.
return this->dotted_decimal_address (addr, host);
}
- else
- if (specified_hostname != 0)
+ else if (specified_hostname != 0)
{
// If the user specified a hostname, pass it back
// blindly as it overrides our choice of hostname.
@@ -463,7 +481,16 @@ TAO_DIOP_Acceptor::hostname (TAO_ORB_Core *orb_core,
char tmp_host[MAXHOSTNAMELEN + 1];
// Get the hostname associated with our address
+#if defined (ACE_HAS_IPV6)
+ // If we have a IPv4-compatible IPv6 address don't do hostname lookup
+ // because that gets us into trouble. Most likely we get the same hostname
+ // returned as for the actual IPv4 address but resolving that into an IPv6
+ // address at the client will fail.
+ if (addr.is_ipv4_compat_ipv6 () ||
+ addr.get_host_name (tmp_host, sizeof (tmp_host)) != 0)
+#else /* ACE_HAS_IPV6 */
if (addr.get_host_name (tmp_host, sizeof (tmp_host)) != 0)
+#endif /* !ACE_HAS_IPV6 */
{
// On failure, just return the decimal address.
return this->dotted_decimal_address (addr, host);
@@ -478,11 +505,172 @@ TAO_DIOP_Acceptor::hostname (TAO_ORB_Core *orb_core,
}
int
+TAO_DIOP_Acceptor::parse_address (const char *address,
+ ACE_INET_Addr &addr,
+ ACE_CString &specified_hostname,
+ int *def_type)
+{
+ {
+ ACE_INET_Addr tmp;
+ addr.set (tmp);
+ specified_hostname.clear();
+ }
+
+ const char *port_separator_loc = ACE_OS::strchr (address, ':');
+ char tmp_host[MAXHOSTNAMELEN + 1];
+ 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 ||
+ this->version_.minor >= TAO_MIN_IPV6_IIOP_MINOR) &&
+ address[0] == '[')
+ {
+ // In this case we have to find the end of the numeric address and
+ // start looking for the port separator from there.
+ char const * const cp_pos = ACE_OS::strchr (address, ']');
+ if (cp_pos == 0)
+ {
+ // No valid IPv6 address specified.
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) - ")
+ ACE_TEXT ("DIOP_Acceptor::open, ")
+ ACE_TEXT ("invalid IPv6 decimal address specified\n\n")),
+ -1);
+ }
+ else
+ {
+ // Extract out just the host part of the address.
+ size_t const len = cp_pos - (address + 1);
+
+ if (len >= sizeof (tmp_host))
+ return -1;
+
+ 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;
+
+ ACE_OS::memcpy (tmp_host, address + 1, len);
+ tmp_host[len] = '\0';
+ }
+ }
+ else
+#endif /* ACE_HAS_IPV6 */
+ if (!host_defaulted)
+ {
+ if (port_separator_loc != 0)
+ {
+ // Extract out just the host part of the address.
+ size_t const len = port_separator_loc - address;
+
+ if (len >= sizeof (tmp_host))
+ return -1;
+
+ ACE_OS::memcpy (tmp_host, address, len);
+ tmp_host[len] = '\0';
+ }
+ else
+ ACE_OS::strcpy (tmp_host, address);
+ }
+
+ if (!ipv6_in_host && !host_defaulted)
+ {
+ if (addr.set ((unsigned short) 0, tmp_host) != 0)
+ return -1;
+ this->default_address_.set (addr);
+ host_defaulted = addr.is_any ();
+ if (def_type)
+ *def_type = AF_INET;
+ }
+
+ 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)
+ return -1;
+ }
+ else if (port_separator_loc == 0)
+ {
+ // The address is a hostname. No port was specified, so assume
+ // port zero (port will be chosen for us).
+ 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 (addr.set (address) != 0)
+ return -1;
+ if (tmp_host[0] == '\0')
+ {
+ // Extract out just the host part of the address.
+ size_t const len = port_separator_loc - address;
+
+ if (len >= sizeof (tmp_host))
+ return -1;
+
+ ACE_OS::memcpy (tmp_host, address, len);
+ tmp_host[len] = '\0';
+ }
+ specified_hostname = tmp_host;
+ }
+
+ return 1;
+}
+
+int
TAO_DIOP_Acceptor::dotted_decimal_address (ACE_INET_Addr &addr,
char *&host)
{
- const char *tmp = addr.get_host_addr ();
- if (tmp == 0)
+ int result = 0;
+ const char *tmp = 0;
+
+ // If the IP address in the INET_Addr is the IN(6)ADDR_ANY address,
+ // then force the actual IP address to be used by initializing a new
+ // INET_Addr with the hostname from the original one. If that fails
+ // then something is seriously wrong with the systems networking
+ // setup.
+ if (addr.is_any ())
+ {
+ ACE_INET_Addr new_addr;
+#if defined (ACE_HAS_IPV6)
+ result = new_addr.set (addr.get_port_number (),
+ addr.get_host_name (),
+ 1, /* encode */
+ addr.get_type ());
+#else /* ACE_HAS_IPV6 */
+ result = new_addr.set (addr.get_port_number (),
+ addr.get_host_name ());
+#endif /* !ACE_HAS_IPV6 */
+ tmp = new_addr.get_host_addr ();
+ }
+ else
+ tmp = addr.get_host_addr ();
+
+ if (tmp == 0 || result != 0)
{
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
@@ -498,7 +686,7 @@ TAO_DIOP_Acceptor::dotted_decimal_address (ACE_INET_Addr &addr,
}
int
-TAO_DIOP_Acceptor::probe_interfaces (TAO_ORB_Core *orb_core)
+TAO_DIOP_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
@@ -537,20 +725,108 @@ TAO_DIOP_Acceptor::probe_interfaces (TAO_ORB_Core *orb_core)
// the list of cached hostnames unless it is the only interface.
size_t lo_cnt = 0; // Loopback interface count
for (size_t j = 0; j < if_cnt; ++j)
- if (if_addrs[j].get_ip_address () == INADDR_LOOPBACK)
+ if (if_addrs[j].is_loopback ())
lo_cnt++;
+#if defined (ACE_HAS_IPV6)
+ size_t ipv4_cnt = 0;
+ size_t ipv4_lo_cnt = 0;
+ size_t ipv6_ll = 0;
+ bool ipv6_non_ll = false;
+ // Scan for IPv4 interfaces since these should not be included
+ // when IPv6-only is selected.
+ for (size_t j = 0; j < if_cnt; ++j)
+ if (if_addrs[j].get_type () != AF_INET6 ||
+ if_addrs[j].is_ipv4_mapped_ipv6 ())
+ {
+ ++ipv4_cnt;
+ if (if_addrs[j].is_loopback ())
+ ++ipv4_lo_cnt; // keep track of IPv4 loopback ifs
+ }
+ else if (!if_addrs[j].is_linklocal () &&
+ !if_addrs[j].is_loopback())
+ {
+ ipv6_non_ll = true; // we have at least 1 non-local IPv6 if
+ }
+ else if (!orb_core->orb_params ()->use_ipv6_link_local () &&
+ if_addrs[j].is_linklocal ())
+ {
+ ++ipv6_ll; // count link local addrs to exclude them afterwards
+ }
+#endif /* ACE_HAS_IPV6 */
+
// The instantiation for this template is in
// tao/DIOP_Connector.cpp.
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)
+ if (this->default_address_.get_type () == AF_INET)
+ ipv4_only = true;
+ else
+ ipv6_only = true;
+#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.
+ bool ignore_lo;
+ if (ipv6_only)
+ // only exclude loopback if non-local if exists
+ ignore_lo = ipv6_non_ll;
+ else if (ipv4_only)
+ ignore_lo = ipv4_cnt != ipv4_lo_cnt;
+ else
+ ignore_lo = if_cnt != lo_cnt;
+
+ // Adjust counts for IPv6 only if required
+ size_t if_ok_cnt = if_cnt;
+ if (ipv6_only)
+ {
+ if_ok_cnt -= ipv4_cnt;
+ lo_cnt -= ipv4_lo_cnt;
+ ipv4_lo_cnt = 0;
+ }
+ else if (ipv4_only)
+ {
+ if_ok_cnt = ipv4_cnt;
+ lo_cnt = ipv4_lo_cnt;
+ }
+
+ // In case there are no non-local IPv6 ifs in the list only exclude
+ // IPv4 loopback.
+ // IPv6 loopback will be needed to successfully connect IPv6 clients
+ // in a localhost environment.
+ if (!ipv4_only && !ipv6_non_ll)
+ lo_cnt = ipv4_lo_cnt;
+
+ if (!ignore_lo)
+ this->endpoint_count_ = static_cast<CORBA::ULong> (if_ok_cnt - ipv6_ll);
+ else
+ this->endpoint_count_ = static_cast<CORBA::ULong> (if_ok_cnt - ipv6_ll - lo_cnt);
+#else /* ACE_HAS_IPV6 */
// 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.
- if (if_cnt == lo_cnt)
+ bool ignore_lo;
+ ignore_lo = if_cnt != lo_cnt;
+ if (!ignore_lo)
this->endpoint_count_ = static_cast<CORBA::ULong> (if_cnt);
else
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) - DIOP_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_],
@@ -569,11 +845,38 @@ TAO_DIOP_Acceptor::probe_interfaces (TAO_ORB_Core *orb_core)
for (size_t i = 0; i < if_cnt; ++i)
{
+#if defined (ACE_HAS_IPV6)
+ // Ignore any loopback interface if there are other
+ // non-loopback interfaces.
+ if (ignore_lo &&
+ if_addrs[i].is_loopback () &&
+ (ipv4_only ||
+ ipv6_non_ll ||
+ if_addrs[i].get_type () != AF_INET6))
+ continue;
+
+ // Ignore any non-IPv4 interfaces when so required.
+ if (ipv4_only &&
+ (if_addrs[i].get_type () != AF_INET))
+ continue;
+
+ // Ignore any non-IPv6 interfaces when so required.
+ if (ipv6_only &&
+ (if_addrs[i].get_type () != AF_INET6 ||
+ if_addrs[i].is_ipv4_mapped_ipv6 ()))
+ continue;
+
+ // Ignore all IPv6 link local interfaces when so required.
+ if (!orb_core->orb_params ()->use_ipv6_link_local () &&
+ if_addrs[i].is_linklocal ())
+ continue;
+#else /* ACE_HAS_IPV6 */
// Ignore any loopback interface if there are other
// non-loopback interfaces.
- if (if_cnt != lo_cnt &&
- if_addrs[i].get_ip_address() == INADDR_LOOPBACK)
+ if (ignore_lo &&
+ if_addrs[i].is_loopback ())
continue;
+#endif /* !ACE_HAS_IPV6 */
if (this->hostname (orb_core,
if_addrs[i],
@@ -620,7 +923,7 @@ TAO_DIOP_Acceptor::object_key (IOP::TaggedProfile &profile,
if (TAO_debug_level > 0)
{
ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("TAO (%P|%t) - DIOP_Profile::decode, v%d.%d\n"),
+ ACE_TEXT ("TAO (%P|%t) - DIOP_Profile::object_key, v%d.%d\n"),
major,
minor));
}
@@ -663,11 +966,11 @@ TAO_DIOP_Acceptor::parse_options (const char *str)
// HTTP URLs.
// e.g.: option1=foo&option2=bar
- ACE_CString options (str);
+ const ACE_CString options (str);
- size_t len = options.length ();
+ const size_t len = options.length ();
- const char option_delimiter = '&';
+ static const char option_delimiter = '&';
// Count the number of options.
diff --git a/TAO/tao/Strategies/DIOP_Acceptor.h b/TAO/tao/Strategies/DIOP_Acceptor.h
index 334ef2b47dd..6dd90a72e43 100644
--- a/TAO/tao/Strategies/DIOP_Acceptor.h
+++ b/TAO/tao/Strategies/DIOP_Acceptor.h
@@ -59,6 +59,12 @@ public:
/// Returns the array of endpoints in this acceptor
const ACE_INET_Addr *endpoints (void);
+ /// Returns address for default endpoint
+ const ACE_INET_Addr& default_address (void) const;
+
+ /// Set address for default endpoint
+ void set_default_address (const ACE_INET_Addr& addr);
+
/**
* @name The TAO_Acceptor Methods
*
@@ -95,10 +101,10 @@ public:
* hostname and the desired one cannot be determined in any
* other way.
*/
- int hostname (TAO_ORB_Core *orb_core,
- ACE_INET_Addr &addr,
- char *&host,
- const char *specified_hostname = 0);
+ virtual int hostname (TAO_ORB_Core *orb_core,
+ ACE_INET_Addr &addr,
+ char *&host,
+ const char *specified_hostname = 0);
/**
* Set the host name for the given address using the dotted decimal
@@ -110,6 +116,20 @@ public:
protected:
/**
+ * Helper method
+ * 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,
+ int *def_type = 0);
+
+ /**
* Implement the common part of the open*() methods. This method is
* virtual to allow a derived class implementation to be invoked
* instead.
@@ -123,8 +143,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.
virtual int parse_options (const char *options);
@@ -172,6 +197,9 @@ protected:
/// Should we use GIOP lite??
CORBA::Boolean lite_flag_;
+ /// Address for default endpoint
+ ACE_INET_Addr default_address_;
+
private:
// @@ Frank: From DIOP_Acceptor.h
TAO_DIOP_Connection_Handler *connection_handler_;
diff --git a/TAO/tao/Strategies/DIOP_Acceptor.inl b/TAO/tao/Strategies/DIOP_Acceptor.inl
index 2603d4e7156..8aa46f549c1 100644
--- a/TAO/tao/Strategies/DIOP_Acceptor.inl
+++ b/TAO/tao/Strategies/DIOP_Acceptor.inl
@@ -25,4 +25,16 @@ TAO_DIOP_Acceptor::endpoints (void)
return this->addrs_;
}
+ACE_INLINE const ACE_INET_Addr&
+TAO_DIOP_Acceptor::default_address (void) const
+{
+ return this->default_address_;
+}
+
+ACE_INLINE void
+TAO_DIOP_Acceptor::set_default_address (const ACE_INET_Addr& addr)
+{
+ this->default_address_.set (addr);
+}
+
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Strategies/DIOP_Connection_Handler.cpp b/TAO/tao/Strategies/DIOP_Connection_Handler.cpp
index f76d739af62..940d69d8897 100644
--- a/TAO/tao/Strategies/DIOP_Connection_Handler.cpp
+++ b/TAO/tao/Strategies/DIOP_Connection_Handler.cpp
@@ -49,7 +49,7 @@ TAO_DIOP_Connection_Handler::TAO_DIOP_Connection_Handler (TAO_ORB_Core *orb_core
{
TAO_DIOP_Transport* specific_transport = 0;
ACE_NEW (specific_transport,
- TAO_DIOP_Transport(this, orb_core, flag));
+ TAO_DIOP_Transport (this, orb_core, flag));
// store this pointer (indirectly increment ref count)
this->transport (specific_transport);
@@ -65,9 +65,9 @@ TAO_DIOP_Connection_Handler::~TAO_DIOP_Connection_Handler (void)
if (result == -1 && TAO_debug_level)
{
ACE_ERROR ((LM_ERROR,
- ACE_TEXT("TAO (%P|%t) - DIOP_Connection_Handler::")
- ACE_TEXT("~DIOP_Connection_Handler, ")
- ACE_TEXT("release_os_resources() failed %m\n")));
+ ACE_TEXT ("TAO (%P|%t) - DIOP_Connection_Handler::")
+ ACE_TEXT ("~DIOP_Connection_Handler, ")
+ ACE_TEXT ("release_os_resources() failed %m\n")));
}
this->udp_socket_.close ();
}
@@ -97,14 +97,14 @@ TAO_DIOP_Connection_Handler::addr (const ACE_INET_Addr &addr)
const ACE_INET_Addr &
TAO_DIOP_Connection_Handler::local_addr (void)
{
- return local_addr_;
+ return this->local_addr_;
}
void
TAO_DIOP_Connection_Handler::local_addr (const ACE_INET_Addr &addr)
{
- local_addr_ = addr;
+ this->local_addr_ = addr;
}
@@ -220,7 +220,7 @@ TAO_DIOP_Connection_Handler::open_server (void)
protocol_properties.recv_buffer_size_) == -1)
return -1;
- if( TAO_debug_level > 5)
+ if (TAO_debug_level > 5)
{
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT("TAO (%P|%t) - DIOP_Connection_Handler::open_server, ")
@@ -302,14 +302,64 @@ TAO_DIOP_Connection_Handler::release_os_resources (void)
}
int
+TAO_DIOP_Connection_Handler::add_transport_to_cache (void)
+{
+ ACE_INET_Addr addr;
+
+ // This function is called by the acceptor to add this
+ // transport to the transport cache. This is really
+ // important for proper shutdown. The address used
+ // is irrelevent, since DIOP is connectionless.
+
+ // Construct a DIOP_Endpoint object.
+ TAO_DIOP_Endpoint endpoint (
+ addr,
+ this->orb_core ()->orb_params ()->cache_incoming_by_dotted_decimal_address ());
+
+ // Construct a property object
+ TAO_Base_Transport_Property prop (&endpoint);
+
+ // Add the handler to Cache
+ return this->orb_core ()->lane_resources ()
+ .transport_cache ().cache_transport (&prop,
+ this->transport ());
+}
+
+int
TAO_DIOP_Connection_Handler::set_tos (int tos)
{
if (tos != this->dscp_codepoint_)
{
- int const result = this->dgram ().set_option (IPPROTO_IP,
- IP_TOS,
- (int *) &tos ,
- (int) sizeof (tos));
+ int result = 0;
+#if defined (ACE_HAS_IPV6)
+ ACE_INET_Addr local_addr;
+ if (this->dgram ().get_local_addr (local_addr) == -1)
+ return -1;
+ else if (local_addr.get_type () == AF_INET6)
+# if !defined (IPV6_TCLASS)
+ // IPv6 defines option IPV6_TCLASS for specifying traffic class/priority
+ // but not many implementations yet (very new;-).
+ {
+ if (TAO_debug_level)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - DIOP_Connection_Handler::"
+ "set_dscp_codepoint -> IPV6_TCLASS not supported yet\n"));
+ }
+ return 0;
+ }
+# else /* !IPV6_TCLASS */
+ result = this->dgram ().set_option (IPPROTO_IPV6,
+ IPV6_TCLASS,
+ (int *) &tos ,
+ (int) sizeof (tos));
+ else
+# endif /* IPV6_TCLASS */
+#endif /* ACE_HAS_IPV6 */
+ result = this->dgram ().set_option (IPPROTO_IP,
+ IP_TOS,
+ (int *) &tos ,
+ (int) sizeof (tos));
if (TAO_debug_level)
{
diff --git a/TAO/tao/Strategies/DIOP_Connector.cpp b/TAO/tao/Strategies/DIOP_Connector.cpp
index 9a4182b3822..048c2830cd9 100644
--- a/TAO/tao/Strategies/DIOP_Connector.cpp
+++ b/TAO/tao/Strategies/DIOP_Connector.cpp
@@ -14,6 +14,8 @@
#include "tao/Protocols_Hooks.h"
#include "ace/OS_NS_strings.h"
#include "ace/OS_NS_string.h"
+#include "tao/Thread_Lane_Resources.h"
+#include "ace/os_include/os_netdb.h"
#include "tao/Strategies/DIOP_Profile.h"
@@ -44,24 +46,12 @@ TAO_DIOP_Connector::open (TAO_ORB_Core *orb_core)
if (this->create_connect_strategy () == -1)
return -1;
- // @@ Michael: We do not use regular connection management.
-
return 0;
}
int
TAO_DIOP_Connector::close (void)
{
- // The list of service handlers cleans itself??
- SvcHandlerIterator iter (svc_handler_table_);
-
- while (!iter.done ())
- {
- (*iter).int_id_->remove_reference ();
- iter++;
- }
-
- // @@ Michael: We do not use regular connection management.
return 0;
}
@@ -80,7 +70,12 @@ TAO_DIOP_Connector::set_validate_endpoint (TAO_Endpoint *endpoint)
// Verify that the remote ACE_INET_Addr was initialized properly.
// Failure can occur if hostname lookup failed when initializing the
// remote ACE_INET_Addr.
+#if defined (ACE_HAS_IPV6)
+ if (remote_address.get_type () != AF_INET &&
+ remote_address.get_type () != AF_INET6)
+#else /* ACE_HAS_IPV6 */
if (remote_address.get_type () != AF_INET)
+#endif /* !ACE_HAS_IPV6 */
{
if (TAO_debug_level > 0)
{
@@ -111,34 +106,107 @@ TAO_DIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *,
const ACE_INET_Addr &remote_address =
diop_endpoint->object_addr ();
+#if defined (ACE_HAS_IPV6) && !defined (ACE_HAS_IPV6_V6ONLY)
+ // Check if we need to invalidate accepted connections
+ // from IPv4 mapped IPv6 addresses
+ if (this->orb_core ()->orb_params ()->connect_ipv6_only () &&
+ remote_address.is_ipv4_mapped_ipv6 ())
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_TCHAR remote_as_string[MAXHOSTNAMELEN + 16];
+
+ (void) remote_address.addr_to_string (remote_as_string,
+ sizeof remote_as_string);
+
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) - DIOP_Connection_Handler::open, ")
+ ACE_TEXT ("invalid connection to IPv4 mapped IPv6 interface <%s>!\n"),
+ remote_as_string));
+ }
+ return 0;
+ }
+#endif /* ACE_HAS_IPV6 && ACE_HAS_IPV6_V6ONLY */
+
TAO_DIOP_Connection_Handler *svc_handler = 0;
- if (svc_handler_table_.find (remote_address, svc_handler) == -1)
+ ACE_NEW_RETURN (svc_handler,
+ TAO_DIOP_Connection_Handler (this->orb_core (),
+ this->lite_flag_),
+ 0);
+
+ u_short port = 0;
+ const ACE_UINT32 ia_any = INADDR_ANY;
+ ACE_INET_Addr local_addr (port, ia_any);
+
+#if defined (ACE_HAS_IPV6)
+ if (remote_address.get_type () == AF_INET6)
+ local_addr.set (port,
+ ACE_IPV6_ANY);
+#endif /* ACE_HAS_IPV6 */
+
+ svc_handler->local_addr (local_addr);
+ svc_handler->addr (remote_address);
+
+ int retval = svc_handler->open (0);
+
+ // Failure to open a connection.
+ if (retval != 0)
{
- TAO_DIOP_Connection_Handler *svc_handler_i = 0;
- ACE_NEW_RETURN (svc_handler_i,
- TAO_DIOP_Connection_Handler (this->orb_core (),
- this->lite_flag_),
- 0);
-
- svc_handler_i->local_addr (ACE_sap_any_cast (ACE_INET_Addr &));
- svc_handler_i->addr (remote_address);
-
- svc_handler_i->open (0);
-
- svc_handler_table_.bind (remote_address, svc_handler_i);
- svc_handler = svc_handler_i;
-
- if (TAO_debug_level > 2)
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("TAO (%P|%t) - DIOP_Connector::connect, ")
- ACE_TEXT ("new connection on HANDLE %d\n"),
- svc_handler->get_handle ()));
- }
-
- // @@ Michael: We do not use regular connection management.
- svc_handler->add_reference ();
- TAO_Transport *transport = svc_handler->transport ();
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) - DIOP_Connector::make_connection, ")
+ ACE_TEXT ("could not make a new connection\n")));
+ }
+
+ return 0;
+ }
+
+ if (TAO_debug_level > 2)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DIOP_Connector::connect, ")
+ ACE_TEXT ("new connection on HANDLE %d\n"),
+ svc_handler->get_handle ()));
+
+ TAO_DIOP_Transport *transport =
+ dynamic_cast <TAO_DIOP_Transport *> (svc_handler->transport ());
+
+ // In case of errors transport is zero
+ if (transport == 0)
+ {
+ // Give users a clue to the problem.
+ if (TAO_debug_level > 3)
+ ACE_DEBUG ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) - DIOP_Connector::make_connection, ")
+ ACE_TEXT ("connection to <%s:%u> failed (%p)\n"),
+ ACE_TEXT_CHAR_TO_TCHAR (diop_endpoint->host ()),
+ diop_endpoint->port (),
+ ACE_TEXT ("errno")));
+
+ return 0;
+ }
+
+ // Add the handler to Cache
+ retval =
+ this->orb_core ()->lane_resources ().transport_cache ().cache_transport (&desc,
+ transport);
+
+ // Failure in adding to cache.
+ if (retval != 0)
+ {
+ // Close the handler.
+ svc_handler->close ();
+
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) - DIOP_Connector::make_connection, ")
+ ACE_TEXT ("could not add the new connection to cache\n")));
+ }
+
+ return 0;
+ }
return transport;
}
diff --git a/TAO/tao/Strategies/DIOP_Connector.h b/TAO/tao/Strategies/DIOP_Connector.h
index 90061e3d823..2e4befc78b8 100644
--- a/TAO/tao/Strategies/DIOP_Connector.h
+++ b/TAO/tao/Strategies/DIOP_Connector.h
@@ -99,20 +99,6 @@ private:
/// Return the remote endpoint, a helper function
TAO_DIOP_Endpoint *remote_endpoint (TAO_Endpoint *ep);
-
-private:
- // @@ Michael: UDP Addition
- ACE_Hash_Map_Manager_Ex < ACE_INET_Addr,
- TAO_DIOP_Connection_Handler *,
- ACE_Hash < ACE_INET_Addr >,
- ACE_Equal_To < ACE_INET_Addr >,
- ACE_Null_Mutex > svc_handler_table_;
-
- typedef ACE_Hash_Map_Iterator_Ex < ACE_INET_Addr,
- TAO_DIOP_Connection_Handler *,
- ACE_Hash < ACE_INET_Addr >,
- ACE_Equal_To < ACE_INET_Addr >,
- ACE_Null_Mutex > SvcHandlerIterator;
};
TAO_END_VERSIONED_NAMESPACE_DECL
diff --git a/TAO/tao/Strategies/DIOP_Endpoint.cpp b/TAO/tao/Strategies/DIOP_Endpoint.cpp
index 5efa0efd332..ace8929ad97 100644
--- a/TAO/tao/Strategies/DIOP_Endpoint.cpp
+++ b/TAO/tao/Strategies/DIOP_Endpoint.cpp
@@ -33,6 +33,9 @@ TAO_DIOP_Endpoint::TAO_DIOP_Endpoint (const ACE_INET_Addr &addr,
: TAO_Endpoint (TAO_TAG_DIOP_PROFILE)
, host_ ()
, port_ (0)
+#if defined (ACE_HAS_IPV6)
+ , is_ipv6_decimal_ (false)
+#endif /* ACE_HAS_IPV6 */
, object_addr_ (addr)
, object_addr_set_ (false)
, next_ (0)
@@ -48,18 +51,23 @@ TAO_DIOP_Endpoint::TAO_DIOP_Endpoint (const char *host,
priority)
, host_ ()
, port_ (port)
+#if defined (ACE_HAS_IPV6)
+ , is_ipv6_decimal_ (false)
+#endif /* ACE_HAS_IPV6 */
, object_addr_ (addr)
, object_addr_set_ (false)
, next_ (0)
{
- if (host != 0)
- this->host_ = host;
+ this->host (host); // With IPv6 performs check for decimal address
}
TAO_DIOP_Endpoint::TAO_DIOP_Endpoint (void)
: TAO_Endpoint (TAO_TAG_DIOP_PROFILE),
host_ (),
port_ (0),
+#if defined (ACE_HAS_IPV6)
+ is_ipv6_decimal_ (false),
+#endif /* ACE_HAS_IPV6 */
object_addr_ (),
object_addr_set_ (false),
next_ (0)
@@ -69,17 +77,17 @@ TAO_DIOP_Endpoint::TAO_DIOP_Endpoint (void)
TAO_DIOP_Endpoint::TAO_DIOP_Endpoint (const char *host,
CORBA::UShort port,
CORBA::Short priority)
- : TAO_Endpoint (TAO_TAG_DIOP_PROFILE),
+ : TAO_Endpoint (TAO_TAG_DIOP_PROFILE, priority),
host_ (),
port_ (port),
+#if defined (ACE_HAS_IPV6)
+ is_ipv6_decimal_ (false),
+#endif /* ACE_HAS_IPV6 */
object_addr_ (),
object_addr_set_ (false),
next_ (0)
{
- if (host != 0)
- this->host_ = host;
-
- this->priority (priority);
+ this->host (host); // With IPv6 performs check for decimal address
}
TAO_DIOP_Endpoint::~TAO_DIOP_Endpoint (void)
@@ -92,9 +100,21 @@ TAO_DIOP_Endpoint::set (const ACE_INET_Addr &addr,
{
char tmp_host[MAXHOSTNAMELEN + 1];
+#if defined (ACE_HAS_IPV6)
+ this->is_ipv6_decimal_ = false; // Reset
+#endif /* ACE_HAS_IPV6 */
+
if (use_dotted_decimal_addresses
|| addr.get_host_name (tmp_host, sizeof (tmp_host)) != 0)
{
+ if (use_dotted_decimal_addresses == 0 && TAO_debug_level > 5)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - DIOP_Endpoint::set, ")
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("cannot determine hostname")));
+ }
+
const char *tmp = addr.get_host_addr ();
if (tmp == 0)
{
@@ -102,17 +122,23 @@ TAO_DIOP_Endpoint::set (const ACE_INET_Addr &addr,
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("TAO (%P|%t) - ")
ACE_TEXT ("DIOP_Endpoint::set, ")
- ACE_TEXT ("%p\n\n"),
+ ACE_TEXT ("%p\n"),
ACE_TEXT ("cannot determine hostname\n")));
return -1;
}
else
- this->host_ = tmp;
+ {
+ this->host_ = tmp;
+#if defined (ACE_HAS_IPV6)
+ if (addr.get_type () == PF_INET6)
+ this->is_ipv6_decimal_ = true;
+#endif /* ACE_HAS_IPV6 */
+ }
}
else
this->host_ = CORBA::string_dup (tmp_host);
- this->port_ = addr.get_port_number();
+ this->port_ = addr.get_port_number ();
return 0;
}
@@ -120,15 +146,26 @@ TAO_DIOP_Endpoint::set (const ACE_INET_Addr &addr,
int
TAO_DIOP_Endpoint::addr_to_string (char *buffer, size_t length)
{
- size_t const actual_len =
+ size_t actual_len =
ACE_OS::strlen (this->host_.in ()) // chars in host name
+ sizeof (':') // delimiter
+ ACE_OS::strlen ("65536") // max port
+ sizeof ('\0');
+#if defined (ACE_HAS_IPV6)
+ if (this->is_ipv6_decimal_)
+ actual_len += 2; // '[' + ']'
+#endif /* ACE_HAS_IPV6 */
+
if (length < actual_len)
return -1;
+#if defined (ACE_HAS_IPV6)
+ if (this->is_ipv6_decimal_)
+ ACE_OS::sprintf (buffer, "[%s]:%d",
+ this->host_.in (), this->port_);
+ else
+#endif /* ACE_HAS_IPV6 */
ACE_OS::sprintf (buffer, "%s:%d",
this->host_.in (), this->port_);
@@ -139,6 +176,10 @@ const char *
TAO_DIOP_Endpoint::host (const char *h)
{
this->host_ = h;
+#if defined (ACE_HAS_IPV6)
+ if (ACE_OS::strchr (h, ':') != 0)
+ this->is_ipv6_decimal_ = true;
+#endif /* ACE_HAS_IPV6 */
return this->host_.in ();
}
@@ -174,7 +215,7 @@ TAO_DIOP_Endpoint::is_equivalent (const TAO_Endpoint *other_endpoint)
return 0;
return (this->port () == endpoint->port ()
- && ACE_OS::strcmp(this->host (), endpoint->host()) == 0);
+ && ACE_OS::strcmp (this->host (), endpoint->host ()) == 0);
}
CORBA::ULong
@@ -211,40 +252,66 @@ TAO_DIOP_Endpoint::object_addr (void) const
// Double checked locking optimization.
if (!this->object_addr_set_)
{
- // We need to modify the object_addr_ in this method. Do so
- // using a non-const copy of the <this> pointer.
- TAO_DIOP_Endpoint *endpoint =
- const_cast<TAO_DIOP_Endpoint *> (this);
-
ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
guard,
- endpoint->addr_lookup_lock_,
+ this->addr_lookup_lock_,
this->object_addr_ );
if (!this->object_addr_set_)
{
- if (endpoint->object_addr_.set (this->port_,
- this->host_.in ()) == -1)
- {
- // If this call fails, it most likely due a hostname
- // lookup failure caused by a DNS misconfiguration. If
- // a request is made to the object at the given host and
- // port, then a CORBA::TRANSIENT() exception should be
- // thrown.
-
- // Invalidate the ACE_INET_Addr. This is used as a flag
- // to denote that ACE_INET_Addr initialization failed.
- endpoint->object_addr_.set_type (-1);
- }
- else
- {
- endpoint->object_addr_set_ = true;
- }
+ (void) this->object_addr_i ();
}
}
return this->object_addr_;
}
+void
+TAO_DIOP_Endpoint::object_addr_i (void) const
+{
+ // We should have already held the lock
+
+#if defined (ACE_HAS_IPV6)
+ bool is_ipv4_decimal_ = false;
+ if (!this->is_ipv6_decimal_)
+ is_ipv4_decimal_ =
+ ACE_OS::strspn (this->host_.in (), ".0123456789") ==
+ ACE_OS::strlen (this->host_.in ());
+
+ // If this is *not* an IPv4 decimal address at first try to
+ // resolve the address as an IPv6 address; if that fails
+ // (or it's an IPv4 address) and the address is *not* an IPv6
+ // decimal address try to resolve it as an IPv4 address.
+ if ((is_ipv4_decimal_ ||
+ this->object_addr_.set (this->port_,
+ this->host_.in (),
+ 1,
+ AF_INET6) == -1) &&
+ (this->is_ipv6_decimal_ ||
+ this->object_addr_.set (this->port_,
+ this->host_.in (),
+ 1,
+ AF_INET) == -1))
+#else
+ if (this->object_addr_.set (this->port_,
+ this->host_.in ()) == -1)
+#endif /* ACE_HAS_IPV6 */
+ {
+ // If this call fails, it most likely due a hostname
+ // lookup failure caused by a DNS misconfiguration. If
+ // a request is made to the object at the given host and
+ // port, then a CORBA::TRANSIENT() exception should be
+ // thrown.
+
+ // Invalidate the ACE_INET_Addr. This is used as a flag
+ // to denote that ACE_INET_Addr initialization failed.
+ this->object_addr_.set_type (-1);
+ }
+ else
+ {
+ this->object_addr_set_ = true;
+ }
+}
+
TAO_END_VERSIONED_NAMESPACE_DECL
#endif /* TAO_HAS_DIOP && TAO_HAS_DIOP != 0 */
diff --git a/TAO/tao/Strategies/DIOP_Endpoint.h b/TAO/tao/Strategies/DIOP_Endpoint.h
index 3c664bc4096..0a54dec186e 100644
--- a/TAO/tao/Strategies/DIOP_Endpoint.h
+++ b/TAO/tao/Strategies/DIOP_Endpoint.h
@@ -117,18 +117,26 @@ private:
int set (const ACE_INET_Addr &addr,
int use_dotted_decimal_addresses);
+ /// Helper method for object_addr () call.
+ void object_addr_i (void) const;
+
/// String representing the host name.
CORBA::String_var host_;
/// TCP port number.
CORBA::UShort port_;
+#if defined (ACE_HAS_IPV6)
+ /// Does the host string represent an IPv6 decimal address.
+ bool is_ipv6_decimal_;
+#endif /* ACE_HAS_IPV6 */
+
/// Cached instance of <ACE_INET_Addr> for use in making
/// invocations, etc.
- ACE_INET_Addr object_addr_;
+ mutable ACE_INET_Addr object_addr_;
/// Flag to indicate if the address has been resolved and set.
- bool object_addr_set_;
+ mutable bool object_addr_set_;
/// DIOP Endpoints can be stringed into a list. Return the next
/// endpoint in the list, if any.
diff --git a/TAO/tao/Strategies/DIOP_Profile.cpp b/TAO/tao/Strategies/DIOP_Profile.cpp
index ccac587348c..14ef4fbd3b1 100644
--- a/TAO/tao/Strategies/DIOP_Profile.cpp
+++ b/TAO/tao/Strategies/DIOP_Profile.cpp
@@ -101,7 +101,7 @@ TAO_DIOP_Profile::decode_profile (TAO_InputCDR& cdr)
{
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("TAO (%P|%t) - DIOP_Profile::decode - ")
+ ACE_TEXT ("TAO (%P|%t) - DIOP_Profile::decode_profile, ")
ACE_TEXT ("error while decoding host/port\n")));
return -1;
}
@@ -139,6 +139,45 @@ TAO_DIOP_Profile::parse_string_i (const char *ior)
CORBA::ULong length_host = 0;
const char *cp_pos = ACE_OS::strchr (ior, ':'); // Look for a port
+#if defined (ACE_HAS_IPV6)
+ // IPv6 numeric address in host string?
+ bool ipv6_in_host = false;
+
+ // Check if this is a (possibly) IPv6 supporting profile containing a
+ // decimal IPv6 address representation.
+ if ((this->version ().major > TAO_MIN_IPV6_IIOP_MAJOR ||
+ this->version ().minor >= TAO_MIN_IPV6_IIOP_MINOR) &&
+ ior[0] == '[')
+ {
+ // In this case we have to find the end of the numeric address and
+ // start looking for the port separator from there.
+ const char *cp_pos_a = ACE_OS::strchr (ior, ']');
+ if (cp_pos_a == 0)
+ {
+ // No valid IPv6 address specified.
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_ERROR,
+ ACE_TEXT ("\nTAO (%P|%t) - DIOP_Profile::parse_string_i, ")
+ ACE_TEXT ("invalid IPv6 decimal address specified.\n")));
+ }
+
+ ACE_THROW (CORBA::INV_OBJREF (
+ CORBA::SystemException::_tao_minor_code (
+ 0,
+ EINVAL),
+ CORBA::COMPLETED_NO));
+ }
+ else
+ {
+ if (cp_pos_a[1] == ':') // Look for a port
+ cp_pos = cp_pos_a + 1;
+ else
+ cp_pos = 0;
+ ipv6_in_host = true; // host string contains full IPv6 numeric address
+ }
+ }
+#endif /* ACE_HAS_IPV6 */
if (cp_pos == ior)
{
@@ -159,21 +198,53 @@ TAO_DIOP_Profile::parse_string_i (const char *ior)
ACE_OS::strncpy (tmp.inout (), cp_pos + 1, length_port);
tmp[length_port] = '\0';
- this->endpoint_.port_ =
- static_cast<CORBA::UShort> (ACE_OS::atoi (tmp.in ()));
+ if (ACE_OS::strspn (tmp.in (), "1234567890") == length_port)
+ {
+ this->endpoint_.port_ =
+ static_cast<CORBA::UShort> (ACE_OS::atoi (tmp.in ()));
+ }
+ else
+ {
+ ACE_INET_Addr ia;
+ if (ia.string_to_addr (tmp.in ()) == -1)
+ {
+ ACE_THROW (CORBA::INV_OBJREF (
+ CORBA::SystemException::_tao_minor_code (
+ 0,
+ EINVAL),
+ CORBA::COMPLETED_NO));
+ }
+ else
+ {
+ this->endpoint_.port_ = ia.get_port_number ();
+ }
+ }
length_host = cp_pos - ior;
}
else
length_host = okd - ior;
+#if defined (ACE_HAS_IPV6)
+ if (ipv6_in_host)
+ length_host -= 2; // don't store '[' and ']'
+#endif /* ACE_HAS_IPV6 */
+
CORBA::String_var tmp = CORBA::string_alloc (length_host);
+#if defined (ACE_HAS_IPV6)
+ if (ipv6_in_host)
+ ACE_OS::strncpy (tmp.inout (), ior + 1, length_host);
+ else
+#endif /* ACE_HAS_IPV6 */
// Skip the trailing '/'
ACE_OS::strncpy (tmp.inout (), ior, length_host);
tmp[length_host] = '\0';
this->endpoint_.host_ = tmp._retn ();
+#if defined (ACE_HAS_IPV6)
+ this->endpoint_.is_ipv6_decimal_ = ipv6_in_host;
+#endif /* ACE_HAS_IPV6 */
if (ACE_OS::strcmp (this->endpoint_.host_.in (), "") == 0)
{
@@ -192,8 +263,8 @@ TAO_DIOP_Profile::parse_string_i (const char *ior)
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("TAO (%P|%t) - ")
- ACE_TEXT ("DIOP_Profile::parse_string ")
- ACE_TEXT ("- %p\n\n"),
+ ACE_TEXT ("DIOP_Profile::parse_string_i, ")
+ ACE_TEXT ("%p\n\n"),
ACE_TEXT ("cannot determine hostname")));
// @@ What's the right exception to throw here?
@@ -221,6 +292,10 @@ TAO_DIOP_Profile::do_is_equivalent (const TAO_Profile *other_profile)
const TAO_DIOP_Profile *op =
dynamic_cast<const TAO_DIOP_Profile *> (other_profile);
+ // Make sure we have a TAO_DIOP_Profile.
+ if (op == 0)
+ return 0;
+
// Check endpoints equivalence.
const TAO_DIOP_Endpoint *other_endp = &op->endpoint_;
for (TAO_DIOP_Endpoint *endp = &this->endpoint_;
@@ -289,35 +364,83 @@ TAO_DIOP_Profile::add_endpoint (TAO_DIOP_Endpoint *endp)
char *
TAO_DIOP_Profile::to_string (void)
{
+ // corbaloc:diop:1.2@host:port,diop:1.2@host:port,.../key
+
CORBA::String_var key;
- TAO::ObjectKey::encode_sequence_to_string (key.inout(),
- this->ref_object_key_->object_key ());
-
- size_t buflen = (8 /* "corbaloc" */ +
- 1 /* colon separator */ +
- ACE_OS::strlen (::the_prefix) +
- 1 /* colon separator */ +
- 1 /* major version */ +
- 1 /* decimal point */ +
- 1 /* minor version */ +
- 1 /* `@' character */ +
- ACE_OS::strlen (this->endpoint_.host ()) +
- 1 /* colon separator */ +
- 5 /* port number */ +
- 1 /* object key separator */ +
- ACE_OS::strlen (key.in ()));
+ TAO::ObjectKey::encode_sequence_to_string (key.inout (),
+ this->ref_object_key_->object_key ());
+
+ size_t buflen = (
+ 8 /* "corbaloc" */ +
+ 1 /* colon separator */ +
+ 1 /* object key separator */ +
+ ACE_OS::strlen (key.in ()));
+ size_t pfx_len = (
+ ACE_OS::strlen (::the_prefix) /* "diop" */ +
+ 1 /* colon separator */);
+
+ const TAO_DIOP_Endpoint *endp = 0;
+ for (endp = &this->endpoint_; endp != 0; endp = endp->next_)
+ {
+ buflen += (
+ pfx_len +
+ 1 /* major version */ +
+ 1 /* decimal point */ +
+ 1 /* minor version */ +
+ 1 /* `@' character */ +
+ ACE_OS::strlen (endp->host ()) +
+ 1 /* colon separator */ +
+ 5 /* port number */ +
+ 1 /* comma */);
+#if defined (ACE_HAS_IPV6)
+ if (endp->is_ipv6_decimal_)
+ buflen += 2; // room for '[' and ']'
+#endif /* ACE_HAS_IPV6 */
+ }
+
+ static const char digits [] = "0123456789";
char * buf = CORBA::string_alloc (static_cast<CORBA::ULong> (buflen));
- static const char digits [] = "0123456789";
+ ACE_OS::strcpy (buf, "corbaloc:");
+
+ for (endp = &this->endpoint_; endp != 0; endp = endp->next_)
+ {
+ if (&this->endpoint_ != endp)
+ ACE_OS::strcat (buf, ",");
- ACE_OS::sprintf (buf,
- "corbaloc:%s:%c.%c@%s:%d%c%s",
- ::the_prefix,
- digits [this->version_.major],
- digits [this->version_.minor],
- this->endpoint_.host (),
- this->endpoint_.port (),
+#if defined (ACE_HAS_IPV6)
+ if (endp->is_ipv6_decimal_)
+ {
+ // Don't publish scopeid if included.
+ ACE_CString tmp (endp->host ());
+ ACE_CString::size_type pos = tmp.find ('%');
+ if (pos != ACE_CString::npos)
+ {
+ tmp = tmp.substr (0, pos + 1);
+ tmp[pos] = '\0';
+ }
+ ACE_OS::sprintf (buf + ACE_OS::strlen (buf),
+ "%s:%c.%c@[%s]:%d",
+ ::the_prefix,
+ digits [this->version_.major],
+ digits [this->version_.minor],
+ tmp.c_str (),
+ endp->port ());
+ }
+ else
+#endif
+ ACE_OS::sprintf (buf + ACE_OS::strlen (buf),
+ "%s:%c.%c@%s:%d",
+ ::the_prefix,
+ digits [this->version_.major],
+ digits [this->version_.minor],
+ endp->host (),
+ endp->port ());
+
+ }
+ ACE_OS::sprintf (buf + ACE_OS::strlen (buf),
+ "%c%s",
this->object_key_delimiter_,
key.in ());
@@ -340,6 +463,21 @@ TAO_DIOP_Profile::create_profile_body (TAO_OutputCDR &encap) const
encap.write_octet (this->version_.minor);
// STRING hostname from profile
+#if defined (ACE_HAS_IPV6)
+ // For IPv6 decimal addresses make sure the possibly included scopeid
+ // is not published as this has only local meaning.
+ const char* host;
+ const char* pos;
+ if (this->endpoint_.is_ipv6_decimal_ &&
+ (pos = ACE_OS::strchr (host = this->endpoint_.host (), '%')) != 0)
+ {
+ ACE_CString tmp;
+ size_t len = pos - host;
+ tmp.set (this->endpoint_.host (), len, 1);
+ encap.write_string (tmp.c_str ());
+ }
+ else
+#endif /* ACE_HAS_IPV6 */
encap.write_string (this->endpoint_.host ());
// UNSIGNED SHORT port number
@@ -351,7 +489,7 @@ TAO_DIOP_Profile::create_profile_body (TAO_OutputCDR &encap) const
else
{
ACE_ERROR ((LM_ERROR,
- "TAO (%P|%t) - DIOP_Profile::create_profile_body "
+ "TAO (%P|%t) - DIOP_Profile::create_profile_body, "
"no object key marshalled\n"));
}
@@ -378,6 +516,23 @@ TAO_DIOP_Profile::encode_endpoints (void)
i < this->count_;
++i)
{
+#if defined (ACE_HAS_IPV6)
+ if (endpoint->is_ipv6_decimal_)
+ {
+ // Don't publish scopeid if included.
+ ACE_CString tmp (endpoint->host ());
+ ACE_CString::size_type pos = tmp.find ('%');
+ if (pos != ACE_CString::npos)
+ {
+ tmp = tmp.substr (0, pos + 1);
+ tmp[pos] = '\0';
+ endpoints[i].host = tmp.c_str ();
+ }
+ else
+ endpoints[i].host = tmp.c_str ();
+ }
+ else
+#endif /* ACE_HAS_IPV6 */
endpoints[i].host = endpoint->host ();
endpoints[i].port = endpoint->port ();
endpoints[i].priority = endpoint->priority ();
@@ -391,27 +546,8 @@ TAO_DIOP_Profile::encode_endpoints (void)
== 0)
|| (out_cdr << endpoints) == 0)
return -1;
- size_t length = out_cdr.total_length ();
-
- IOP::TaggedComponent tagged_component;
- tagged_component.tag = TAO_TAG_ENDPOINTS;
- tagged_component.component_data.length (static_cast<CORBA::ULong> (length));
- CORBA::Octet *buf =
- tagged_component.component_data.get_buffer ();
-
- for (const ACE_Message_Block *iterator = out_cdr.begin ();
- iterator != 0;
- iterator = iterator->cont ())
- {
- size_t i_length = iterator->length ();
- ACE_OS::memcpy (buf, iterator->rd_ptr (), i_length);
-
- buf += i_length;
- }
- // Add component with encoded endpoint data to this profile's
- // TaggedComponents.
- tagged_components_.set_component (tagged_component);
+ this->set_tagged_components (out_cdr);
return 0;
}
diff --git a/TAO/tao/Strategies/DIOP_Transport.cpp b/TAO/tao/Strategies/DIOP_Transport.cpp
index 180317673b3..9541913700f 100644
--- a/TAO/tao/Strategies/DIOP_Transport.cpp
+++ b/TAO/tao/Strategies/DIOP_Transport.cpp
@@ -117,7 +117,7 @@ TAO_DIOP_Transport::recv (char *buf,
if (TAO_debug_level > 0)
{
ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - DIOP_Transport::recv_i: received %d bytes from %s:%d %d\n",
+ "TAO (%P|%t) - DIOP_Transport::recv, received %d bytes from %s:%d %d\n",
n,
ACE_TEXT_CHAR_TO_TCHAR (from_addr.get_host_name ()),
from_addr.get_port_number (),
@@ -129,7 +129,7 @@ TAO_DIOP_Transport::recv (char *buf,
if (n == -1 && TAO_debug_level > 4)
{
ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("TAO (%P|%t) - %p \n"),
+ ACE_TEXT ("TAO (%P|%t) - DIOP_Transport::recv, %p \n"),
ACE_TEXT ("TAO - read message failure ")
ACE_TEXT ("recv () \n")));
}
@@ -277,7 +277,7 @@ TAO_DIOP_Transport::send_request (TAO_Stub *stub,
return -1;
- this->first_request_sent();
+ this->first_request_sent ();
return 0;
}
@@ -306,7 +306,8 @@ TAO_DIOP_Transport::send_message (TAO_OutputCDR &stream,
{
if (TAO_debug_level)
ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("TAO (%P|%t) - DIOP_Transport, closing transport %d after fault %p\n"),
+ ACE_TEXT ("TAO (%P|%t) - DIOP_Transport::send_message, ")
+ ACE_TEXT ("closing transport %d after fault %p\n"),
this->id (),
ACE_TEXT ("send_message ()\n")));