diff options
author | bala <balanatarajan@users.noreply.github.com> | 2004-11-28 05:44:15 +0000 |
---|---|---|
committer | bala <balanatarajan@users.noreply.github.com> | 2004-11-28 05:44:15 +0000 |
commit | 89da42cecb810ed2a1747c5e6c30d099b5109371 (patch) | |
tree | c1bfd1845cf0d5e249792dae5ac41f4434d2421e | |
parent | 10c2818bc889d3fdc46e1fbd060882823532d52a (diff) | |
download | ATCD-89da42cecb810ed2a1747c5e6c30d099b5109371.tar.gz |
ChangeLogTag:Sun Nov 28 05:14:24 2004 Balachandran Natarajan <bala@dre.vanderbilt.edu>
-rw-r--r-- | TAO/ChangeLog | 70 | ||||
-rw-r--r-- | TAO/tao/Connector_Registry.cpp | 15 | ||||
-rw-r--r-- | TAO/tao/Endpoint.h | 13 | ||||
-rw-r--r-- | TAO/tao/IIOP_Connection_Handler.cpp | 6 | ||||
-rw-r--r-- | TAO/tao/IIOP_Connector.cpp | 23 | ||||
-rw-r--r-- | TAO/tao/IIOP_Endpoint.cpp | 163 | ||||
-rw-r--r-- | TAO/tao/IIOP_Endpoint.h | 27 | ||||
-rw-r--r-- | TAO/tao/IIOP_Profile.cpp | 10 | ||||
-rw-r--r-- | TAO/tao/IIOP_Profile.h | 23 | ||||
-rw-r--r-- | TAO/tao/ORB_Core.cpp | 67 | ||||
-rw-r--r-- | TAO/tao/Strategies/SCIOP_Connection_Handler.cpp | 7 | ||||
-rw-r--r-- | TAO/tao/Strategies/SCIOP_Connector.cpp | 43 | ||||
-rw-r--r-- | TAO/tao/Strategies/SCIOP_Endpoint.cpp | 168 | ||||
-rw-r--r-- | TAO/tao/Strategies/SCIOP_Endpoint.h | 23 | ||||
-rw-r--r-- | TAO/tao/Strategies/SCIOP_Profile.cpp | 24 | ||||
-rw-r--r-- | TAO/tao/Strategies/SCIOP_Profile.h | 23 | ||||
-rw-r--r-- | TAO/tao/params.cpp | 80 | ||||
-rw-r--r-- | TAO/tao/params.h | 12 |
18 files changed, 616 insertions, 181 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog index 8e1f20f3bb8..6276f70fe66 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,3 +1,73 @@ +Sun Nov 28 05:14:24 2004 Balachandran Natarajan <bala@dre.vanderbilt.edu> + + * tao/Connector_Registry.cpp: + + Used an auto_ptr <> instead of using delete's in the error + paths. + + The following checkin adds a simple command line option which + allows configuring the client ORB during initializing with a + capability to choose preferred interface(s). This is very useful + for clients on a multihomed hosts, allowing clients to choose + specific interfaces/networks to communicate with a remote + target. This capability comes through two options + -ORBPreferredInterfaces, and + -ORBEnforcePreferredInterfaces. Please see docs/Options.html for + more details. + + * tao/Endpoint.h: + + Cosmetic fixes. + + * tao/IIOP_Connection_Handler.cpp: + + Added a debug statement + + * tao/IIOP_Connector.cpp: + + Used the local addr for connect () instead of using the default + ACE_Addr::sap_any. + + * tao/IIOP_Endpoint.cpp: + * tao/IIOP_Endpoint.h: + + Added preferred_interfaces (), and a copy constructor. The + former is used to parse the option and store the preferred path + for every target end point. A list of preferred paths are + organized as multiple endpoints (with same target) with different + preferred networks stringed through the next_ pointer. This + allows the Invocation code path to pick things through its + iteration process. + + * tao/IIOP_Profile.cpp: + + Called TAO_IIOP_Endpoint::preferred_interfaces () from within + decode_profile (). + + * tao/IIOP_Profile.h: + + Added documentation. + + * tao/ORB_Core.cpp: + + Added the two new options. + + * tao/params.cpp: + * tao/params.h: + + Stored the options. + + * tao/Strategies/SCIOP_Connection_Handler.cpp: + * tao/Strategies/SCIOP_Connector.cpp: + * tao/Strategies/SCIOP_Endpoint.cpp: + * tao/Strategies/SCIOP_Endpoint.h: + * tao/Strategies/SCIOP_Profile.cpp: + * tao/Strategies/SCIOP_Profile.h: + + Cut and pasted the changes from IIOP for SCIOP. There is too + much of similar code out here. We can do some nice + implementation inheritance to save some footprint. + Sat Nov 27 12:52:57 2004 Ciju John <john_c@ociweb.com> * orbsvcs/orbsvcs/Notify/XML_Loader.h: diff --git a/TAO/tao/Connector_Registry.cpp b/TAO/tao/Connector_Registry.cpp index 12659bb973b..587bcd1a72b 100644 --- a/TAO/tao/Connector_Registry.cpp +++ b/TAO/tao/Connector_Registry.cpp @@ -52,7 +52,8 @@ TAO_Connector_Registry::get_connector (CORBA::ULong tag) int TAO_Connector_Registry::open (TAO_ORB_Core *orb_core) { - TAO_ProtocolFactorySet *pfs = orb_core->protocol_factories (); + TAO_ProtocolFactorySet *pfs = + orb_core->protocol_factories (); // The array containing the TAO_Connectors will never contain more // than the number of loaded protocols in the ORB core. @@ -68,22 +69,22 @@ TAO_Connector_Registry::open (TAO_ORB_Core *orb_core) factory != end; ++factory) { - TAO_Connector * connector = - (*factory)->factory ()->make_connector (); + auto_ptr <TAO_Connector> connector ( + (*factory)->factory ()->make_connector ()); - if (connector) + if (connector.get ()) { if (connector->open (orb_core) != 0) { - delete connector; - ACE_ERROR_RETURN ((LM_ERROR, ACE_LIB_TEXT ("TAO (%P|%t) unable to open connector for ") ACE_LIB_TEXT ("<%s>.\n"), ACE_TEXT_CHAR_TO_TCHAR((*factory)->protocol_name ().c_str ())), -1); } - this->connectors_[this->size_++] = connector; + + this->connectors_[this->size_++] = + connector.release (); } else return -1; diff --git a/TAO/tao/Endpoint.h b/TAO/tao/Endpoint.h index 88dad57dc35..4e214943836 100644 --- a/TAO/tao/Endpoint.h +++ b/TAO/tao/Endpoint.h @@ -109,14 +109,6 @@ protected: /// Cache the hash value CORBA::ULong hash_val_; -private: - - /// Endpoints should not be copied. - ACE_UNIMPLEMENTED_FUNC (TAO_Endpoint (const TAO_Endpoint&)) - ACE_UNIMPLEMENTED_FUNC (void operator= (const TAO_Endpoint&)) - -private: - /// IOP tag, identifying the protocol for which this endpoint /// contains addressing info. CORBA::ULong tag_; @@ -128,6 +120,11 @@ private: */ CORBA::Short priority_; +private: + + /// Endpoints should not be copied. + ACE_UNIMPLEMENTED_FUNC (TAO_Endpoint (const TAO_Endpoint&)) + ACE_UNIMPLEMENTED_FUNC (void operator= (const TAO_Endpoint&)) }; diff --git a/TAO/tao/IIOP_Connection_Handler.cpp b/TAO/tao/IIOP_Connection_Handler.cpp index 33d476e0806..a42e8f49e97 100644 --- a/TAO/tao/IIOP_Connection_Handler.cpp +++ b/TAO/tao/IIOP_Connection_Handler.cpp @@ -142,6 +142,12 @@ TAO_IIOP_Connection_Handler::open (void*) if (this->peer ().get_local_addr (local_addr) == -1) return -1; + if (TAO_debug_level > 2) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("TAO(%P|%t) - IIOP_Connection_Handler::open, ") + ACE_TEXT("The local addr is (%s) \n"), + local_addr. get_host_addr ())); + if (local_addr.get_ip_address () == remote_addr.get_ip_address () && local_addr.get_port_number () == remote_addr.get_port_number ()) { diff --git a/TAO/tao/IIOP_Connector.cpp b/TAO/tao/IIOP_Connector.cpp index f8eefc25128..367f636c3a5 100644 --- a/TAO/tao/IIOP_Connector.cpp +++ b/TAO/tao/IIOP_Connector.cpp @@ -41,10 +41,10 @@ template class ACE_NonBlocking_Connect_Handler<TAO_IIOP_Connection_Handler>; #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ TAO_IIOP_Connector::TAO_IIOP_Connector (CORBA::Boolean flag) - : TAO_Connector (IOP::TAG_INTERNET_IOP), - lite_flag_ (flag), - connect_strategy_ (), - base_connector_ () + : TAO_Connector (IOP::TAG_INTERNET_IOP) + , lite_flag_ (flag) + , connect_strategy_ () + , base_connector_ () { } @@ -143,6 +143,15 @@ TAO_IIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r, const ACE_INET_Addr &remote_address = iiop_endpoint->object_addr (); + bool pn = + iiop_endpoint->is_preferred_network (); + + ACE_INET_Addr local_addr; + + if (pn) + local_addr.set ((u_short) 0, + iiop_endpoint->preferred_network ()); + if (TAO_debug_level > 2) ACE_DEBUG ((LM_DEBUG, "TAO (%P|%t) - IIOP_Connector::make_connection, " @@ -168,11 +177,11 @@ TAO_IIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r, TAO_IIOP_Connection_Handler *svc_handler = 0; - // Connect. int result = this->base_connector_.connect (svc_handler, remote_address, - synch_options); + synch_options, + local_addr); // The connect() method creates the service handler and bumps the // #REFCOUNT# up one extra. There are four possibilities from @@ -347,7 +356,7 @@ TAO_IIOP_Connector::check_prefix (const char *endpoint) const size_t slot = ACE_OS::strchr (endpoint, ':') - endpoint; if (slot == 0) // an empty string is valid for corbaloc. return 0; - + const size_t len0 = ACE_OS::strlen (protocol[0]); const size_t len1 = ACE_OS::strlen (protocol[1]); diff --git a/TAO/tao/IIOP_Endpoint.cpp b/TAO/tao/IIOP_Endpoint.cpp index 3f08ce0943a..0b9b6a91138 100644 --- a/TAO/tao/IIOP_Endpoint.cpp +++ b/TAO/tao/IIOP_Endpoint.cpp @@ -1,6 +1,7 @@ #include "IIOP_Endpoint.h" -#include "IOPC.h" +#include "IOP_IORC.h" #include "debug.h" +#include "ORB_Core.h" #include "ace/Log_Msg.h" #include "ace/Guard_T.h" @@ -21,11 +22,12 @@ ACE_RCSID (tao, TAO_IIOP_Endpoint::TAO_IIOP_Endpoint (const ACE_INET_Addr &addr, int use_dotted_decimal_addresses) : TAO_Endpoint (IOP::TAG_INTERNET_IOP) - , host_ () - , port_ (683) // default port (IANA assigned) - , object_addr_ (addr) - , object_addr_set_ (false) - , next_ (0) + , host_ () + , port_ (683) // default port (IANA assigned) + , object_addr_ (addr) + , object_addr_set_ (false) + , preferred_path_ () + , next_ (0) { this->set (addr, use_dotted_decimal_addresses); } @@ -36,23 +38,23 @@ TAO_IIOP_Endpoint::TAO_IIOP_Endpoint (const char *host, CORBA::Short priority) : TAO_Endpoint (IOP::TAG_INTERNET_IOP, priority) - , host_ () - , port_ (port) - , object_addr_ (addr) - , object_addr_set_ (false) - , next_ (0) + , host_ (host) + , port_ (port) + , object_addr_ (addr) + , object_addr_set_ (false) + , preferred_path_ () + , next_ (0) { - if (host != 0) - this->host_ = host; } TAO_IIOP_Endpoint::TAO_IIOP_Endpoint (void) : TAO_Endpoint (IOP::TAG_INTERNET_IOP) - , host_ () - , port_ (683) // default port (IANA assigned) - , object_addr_ () - , object_addr_set_ (false) - , next_ (0) + , host_ () + , port_ (683) // default port (IANA assigned) + , object_addr_ () + , object_addr_set_ (false) + , preferred_path_ () + , next_ (0) { } @@ -60,11 +62,12 @@ TAO_IIOP_Endpoint::TAO_IIOP_Endpoint (const char *host, CORBA::UShort port, CORBA::Short priority) : TAO_Endpoint (IOP::TAG_INTERNET_IOP) - , host_ () - , port_ (port) - , object_addr_ () - , object_addr_set_ (false) - , next_ (0) + , host_ () + , port_ (port) + , object_addr_ () + , object_addr_set_ (false) + , preferred_path_ () + , next_ (0) { if (host != 0) this->host_ = host; @@ -76,6 +79,18 @@ TAO_IIOP_Endpoint::~TAO_IIOP_Endpoint (void) { } +TAO_IIOP_Endpoint::TAO_IIOP_Endpoint (const TAO_IIOP_Endpoint &rhs) + : TAO_Endpoint (rhs.tag_, + rhs.priority_) + , host_ (rhs.host_) + , port_ (rhs.port_) + , object_addr_ (rhs.object_addr_) + , object_addr_set_ (rhs.object_addr_set_) + , preferred_path_ (rhs.preferred_path_) + , next_ (0) +{ +} + int TAO_IIOP_Endpoint::set (const ACE_INET_Addr &addr, int use_dotted_decimal_addresses) @@ -155,11 +170,9 @@ TAO_IIOP_Endpoint::duplicate (void) { TAO_IIOP_Endpoint *endpoint = 0; + // @@ NOTE: Not exception safe.. ACE_NEW_RETURN (endpoint, - TAO_IIOP_Endpoint (this->host_.in (), - this->port_, - this->object_addr_, - this->priority ()), + TAO_IIOP_Endpoint (*this), 0); return endpoint; @@ -215,6 +228,90 @@ TAO_IIOP_Endpoint::object_addr_i (void) const } } +CORBA::ULong +TAO_IIOP_Endpoint::preferred_interfaces (TAO_ORB_Core *oc) +{ + ACE_CString tmp ( + oc->orb_params ()->preferred_interfaces ()); + + ssize_t pos = 0; + + pos = tmp.find (this->host_.in ()); + + TAO_IIOP_Endpoint *latest = this; + + CORBA::ULong count = 0; + + while (pos != ACE_CString::npos) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) Pos value is [%d] \n", + pos)); + + // Do we have a "," or an '\0'? + ssize_t new_pos = tmp.find (",", + pos + 1); + + // Length of the preferred path + int length = 0; + + if (new_pos == ACE_CString::npos) + length = tmp.length () - pos; + else + length = new_pos - pos; + + ACE_CString rem_tmp = tmp.substr (pos, length); + + // Search for the ":" + ssize_t col_pos = rem_tmp.find (":"); + + if (col_pos == ACE_CString::npos) continue; + + ACE_CString path = rem_tmp.substr (col_pos + 1); + + latest->preferred_path_.host = + CORBA::string_dup (path.c_str ()); + + if (TAO_debug_level > 3) + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) Adding path [%s] " + " as preferred path for [%s] \n", + path.c_str (), this->host_.in ())); + + pos = tmp.find (latest->host_.in (), + pos + length); + + if (pos != ACE_CString::npos) + { + TAO_Endpoint *tmp_ep = + latest->duplicate (); + + latest->next_ = dynamic_cast<TAO_IIOP_Endpoint *> (tmp_ep); + + if (latest->next_ == 0) return count; + + latest = latest->next_; + ++count; + } + } + + if (tmp.c_str () != 0 && + !oc->orb_params ()->enforce_pref_interfaces ()) + { + TAO_Endpoint *tmp_ep = latest->duplicate (); + + latest->next_ = + dynamic_cast<TAO_IIOP_Endpoint *> (tmp_ep); + + if (latest->next_ == 0) return count; + + latest->next_->preferred_path_.host = (const char *) 0; + ++count; + } + + return count; +} + CORBA::Boolean TAO_IIOP_Endpoint::is_equivalent (const TAO_Endpoint *other_endpoint) { @@ -258,3 +355,15 @@ TAO_IIOP_Endpoint::hash (void) return this->hash_val_; } + +bool +TAO_IIOP_Endpoint::is_preferred_network (void) const +{ + return (this->preferred_path_.host.in () != 0); +} + +const char * +TAO_IIOP_Endpoint::preferred_network (void) const +{ + return this->preferred_path_.host.in (); +} diff --git a/TAO/tao/IIOP_Endpoint.h b/TAO/tao/IIOP_Endpoint.h index d2c7d30459a..be22c89ef4a 100644 --- a/TAO/tao/IIOP_Endpoint.h +++ b/TAO/tao/IIOP_Endpoint.h @@ -12,7 +12,6 @@ */ //============================================================================= - #ifndef TAO_IIOP_ENDPOINT_H #define TAO_IIOP_ENDPOINT_H @@ -25,6 +24,7 @@ #include "tao/Endpoint.h" #include "tao/CORBA_String.h" +#include "tao/IIOP_EndpointsC.h" class TAO_IIOP_Connection_Handler; @@ -64,6 +64,8 @@ public: CORBA::UShort port, CORBA::Short priority); + + /// Destructor. ~TAO_IIOP_Endpoint (void); @@ -71,6 +73,7 @@ public: // Endpoint.h for their documentation. virtual TAO_Endpoint *next (void); + virtual int addr_to_string (char *buffer, size_t length); /// Makes a copy of @c this @@ -102,6 +105,12 @@ public: /// Set the port number. CORBA::UShort port (CORBA::UShort p); + /// Do we have a preferred local network for the target? + bool is_preferred_network (void) const; + + /// Return the preferred network if any. + const char *preferred_network (void) const; + private: /// Helper method for setting INET_Addr. @@ -111,6 +120,18 @@ private: /// Helper method for object_addr () call. void object_addr_i (void) const; + /// Generate preferred interfaces from the options passed in by the + /// user. + CORBA::ULong preferred_interfaces (TAO_ORB_Core *oc); + + /// Canonical copy constructor + /** + * In private section to prevent clients from invoking this + * accidentally. Clients should only use duplicate () to make a depp + * copy + */ + TAO_IIOP_Endpoint (const TAO_IIOP_Endpoint &); + private: /// String representing the host name. @@ -126,10 +147,12 @@ private: /// Flag to indicate if the address has been resolved and set. mutable bool object_addr_set_; + /// Preferred path for this endpoint. + TAO::IIOP_Endpoint_Info preferred_path_; + /// IIOP Endpoints can be stringed into a list. Return the next /// endpoint in the list, if any. TAO_IIOP_Endpoint *next_; - }; diff --git a/TAO/tao/IIOP_Profile.cpp b/TAO/tao/IIOP_Profile.cpp index af4d0b85cc3..1d07a977833 100644 --- a/TAO/tao/IIOP_Profile.cpp +++ b/TAO/tao/IIOP_Profile.cpp @@ -64,7 +64,8 @@ TAO_IIOP_Profile::TAO_IIOP_Profile (const char* host, TAO_IIOP_Profile::TAO_IIOP_Profile (TAO_ORB_Core *orb_core) : TAO_Profile (IOP::TAG_INTERNET_IOP, orb_core, - TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR)), + TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR, + TAO_DEF_GIOP_MINOR)), endpoint_ (), count_ (1) { @@ -104,6 +105,9 @@ TAO_IIOP_Profile::decode_profile (TAO_InputCDR& cdr) // Invalidate the object_addr_ until first access. this->endpoint_.object_addr_.set_type (-1); + this->count_ += + this->endpoint_.preferred_interfaces (this->orb_core ()); + return 1; } @@ -144,7 +148,7 @@ TAO_IIOP_Profile::parse_string_i (const char *ior ACE_LIB_TEXT ("\nTAO (%P|%t) IIOP_Profile: ") ACE_LIB_TEXT ("Host address may be omited only when no port has been specified.\n"))); } - + ACE_THROW (CORBA::INV_OBJREF ( CORBA::SystemException::_tao_minor_code ( 0, @@ -309,7 +313,7 @@ TAO_IIOP_Profile::add_endpoint (TAO_IIOP_Endpoint *endp) endp->next_ = this->endpoint_.next_; this->endpoint_.next_ = endp; - this->count_++; + ++this->count_; } char * diff --git a/TAO/tao/IIOP_Profile.h b/TAO/tao/IIOP_Profile.h index 2a3ecffb1bd..fc2cf1043d2 100644 --- a/TAO/tao/IIOP_Profile.h +++ b/TAO/tao/IIOP_Profile.h @@ -102,10 +102,25 @@ protected: * one endpoint. * * Currently, a profile contains more than one endpoint, i.e., - * list contains more than just the head, only when RTCORBA is enabled. - * However, in the near future, this will be used in nonRT - * mode as well, e.g., to support TAG_ALTERNATE_IIOP_ADDRESS - * feature. + * list contains more than just the head, only for two cases + * (1) when RTCORBA is enabled and + * (2) the ORB is initialized with -ORBPreferredInterfaces option. + * However, in the near future, this will be used in for mode as + * well, e.g., to support TAG_ALTERNATE_IIOP_ADDRESS feature. + * + * This is probably as good a place to discuss how the list of + * endpoints is used for #2. If the ORB is configured to use + * preferred interfaces for invocation, TAO creates an endpoint per + * preferred interface. To be clear, every tuple + * <destination:target> will have an endpoint. What TAO essentially + * does is that creates it multiple endpoints so that the invocation + * code path can use existing iterating techniques to try one + * preferred interface after another (if the first did not work). If + * the ORB is configured with -ORBEnforcePreferredInterface set to + * false in addition to the ORBPreferredInterfaces option , TAO + * creates another endpoint with the preferred bit set to null, so + * that the invocation code can fall back to a TCP stack returned + * local address. * Addressing info of the default endpoint, i.e., head of the list, * is transmitted using standard IIOP ProfileBody components. See * <encode_endpoints> method documentation above for how the rest of diff --git a/TAO/tao/ORB_Core.cpp b/TAO/tao/ORB_Core.cpp index f769ff98941..46be618d904 100644 --- a/TAO/tao/ORB_Core.cpp +++ b/TAO/tao/ORB_Core.cpp @@ -516,59 +516,28 @@ TAO_ORB_Core::init (int &argc, char *argv[] ACE_ENV_ARG_DECL) arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter - (ACE_TEXT("-ORBPreconnect")))) + (ACE_TEXT("-ORBPreferredInterfaces")))) { -#if 0 - /* - * - * TODO: Needs to go. Leaving it around for things to - * settle down. - */ - // Get a string which describes the connections we want to - // cache up-front, thus reducing the latency of the first call. - // - // For example, specify -ORBpreconnect once for each - // protocol: - // - // -ORBpreconnect iiop://tango:10015,watusi:10016 - // -ORBpreconnect busX_iop://board1:0x07450000,board2,0x08450000 - // - // Or chain all possible endpoint designations together: - // - // -ORBpreconnect iiop://tango:10015,watusi:10016/; - // busX_iop://board1:0x07450000,board2,0x08450000/ - // - // The old style command line only works for IIOP: - // -ORBpreconnect tango:10015,tango:10015,watusi:10016 - - ACE_CString preconnections (ACE_TEXT_ALWAYS_CHAR(current_arg)); - - - if (this->orb_params ()->preconnects (preconnections) != 0) - { - ACE_ERROR ((LM_ERROR, - ACE_TEXT ("(%P|%t)\n") - ACE_TEXT ("Invalid preconnect(s)") - ACE_TEXT ("specified:\n%s\n"), - preconnections.c_str ())); - ACE_THROW_RETURN (CORBA::BAD_PARAM ( + if (this->orb_params ()->preferred_interfaces ( + current_arg) == false) + ACE_THROW_RETURN (CORBA::INTERNAL ( CORBA::SystemException::_tao_minor_code ( TAO_ORB_CORE_INIT_LOCATION_CODE, - EINVAL), + 0), CORBA::COMPLETED_NO), -1); - } -#endif /*if 0*/ - - // validate_connection() supports the same functionality as - // the -ORBPreconnect option, and more. Multiple - // preconnections are also provided by validate_connection() - // via "banded connections." - ACE_ERROR ((LM_WARNING, - ACE_TEXT ("(%P|%t) -ORBPreconnect is ") - ACE_TEXT ("deprecated.\n") - ACE_TEXT ("(%P|%t) Use validate_connection()") - ACE_TEXT ("at runtime, instead.\n"))); + + arg_shifter.consume_arg (); + } + else if ((current_arg = arg_shifter.get_the_parameter + (ACE_TEXT("-ORBEnforcePreferredInterfaces")))) + { + if (ACE_OS::strcasecmp (current_arg, + ACE_TEXT("YES")) == 0) + this->orb_params ()->enforce_pref_interfaces (true); + else if (ACE_OS::strcasecmp (current_arg, + ACE_TEXT("NO")) == 0) + this->orb_params ()->enforce_pref_interfaces (false); arg_shifter.consume_arg (); } @@ -1928,7 +1897,7 @@ TAO_ORB_Core::run (ACE_Time_Value *tv, if (this->has_shutdown () == 1 && this->server_factory_->activate_server_connections ()) this->tm_.wait (); - + if (TAO_debug_level > 2) { ACE_DEBUG ((LM_DEBUG, diff --git a/TAO/tao/Strategies/SCIOP_Connection_Handler.cpp b/TAO/tao/Strategies/SCIOP_Connection_Handler.cpp index fc0cbb0c656..f439eaa4cfe 100644 --- a/TAO/tao/Strategies/SCIOP_Connection_Handler.cpp +++ b/TAO/tao/Strategies/SCIOP_Connection_Handler.cpp @@ -160,6 +160,13 @@ TAO_SCIOP_Connection_Handler::open (void*) if (this->peer ().get_local_addr (local_addr) == -1) return -1; + + if (TAO_debug_level > 2) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("TAO(%P|%t) - SCIOP_Connection_Handler::open, ") + ACE_TEXT("The local addr is (%s) \n"), + local_addr. get_host_addr ())); + if (local_addr.get_ip_address () == remote_addr.get_ip_address () && local_addr.get_port_number () == remote_addr.get_port_number ()) { diff --git a/TAO/tao/Strategies/SCIOP_Connector.cpp b/TAO/tao/Strategies/SCIOP_Connector.cpp index 3b49f84ae57..1f476dc6185 100644 --- a/TAO/tao/Strategies/SCIOP_Connector.cpp +++ b/TAO/tao/Strategies/SCIOP_Connector.cpp @@ -157,16 +157,25 @@ TAO_SCIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r, TAO_Transport *transport = 0; - while (tao_endpoint != 0) { - TAO_SCIOP_Endpoint *sciop_endpoint = this->remote_endpoint (tao_endpoint); - if (sciop_endpoint != 0) { - transport = make_connection_i (r, desc, timeout, sciop_endpoint); - if (transport) { - break; - } + // @@ ATL folks, is this while loop needed? + // TAO_Default_Endpoint_Selector has this code already, i.e., the + // loop. + while (tao_endpoint != 0) + { + TAO_SCIOP_Endpoint *sciop_endpoint = + this->remote_endpoint (tao_endpoint); + + if (sciop_endpoint != 0) + { + transport = + this->make_connection_i (r, desc, timeout, sciop_endpoint); + if (transport) + { + break; + } + } + tao_endpoint = tao_endpoint->next(); } - tao_endpoint = tao_endpoint->next(); - } return transport; } @@ -214,10 +223,18 @@ TAO_SCIOP_Connector::make_connection_i (TAO::Profile_Transport_Resolver *r, ACE_Multihomed_INET_Addr local_address; - int result = this->base_connector_.connect (svc_handler, - multihomed, - synch_options, - local_address); + bool pn = + sciop_endpoint->is_preferred_network (); + + if (pn) + local_addr.set ((u_short) 0, + sciop_endpoint->preferred_network ()); + + int result = + this->base_connector_.connect (svc_handler, + multihomed, + synch_options, + local_address); // This call creates the service handler and bumps the #REFCOUNT# up // one extra. There are three possibilities: (a) connection diff --git a/TAO/tao/Strategies/SCIOP_Endpoint.cpp b/TAO/tao/Strategies/SCIOP_Endpoint.cpp index 16ef07973b9..59bb220fd9e 100644 --- a/TAO/tao/Strategies/SCIOP_Endpoint.cpp +++ b/TAO/tao/Strategies/SCIOP_Endpoint.cpp @@ -11,6 +11,7 @@ #include "ace/Log_Msg.h" #include "ace/Synch.h" #include "ace/OS_NS_stdio.h" +#include "ORB_Core.h" ACE_RCSID (Strategies, SCIOP_Endpoint, @@ -25,11 +26,12 @@ ACE_RCSID (Strategies, TAO_SCIOP_Endpoint::TAO_SCIOP_Endpoint (const ACE_INET_Addr &addr, int use_dotted_decimal_addresses) : TAO_Endpoint (TAO_TAG_SCIOP_PROFILE) - , host_ () - , port_ (683) // default port (IANA assigned) - , object_addr_ (addr) - , object_addr_set_ (0) - , next_ (0) + , host_ () + , port_ (683) // default port (IANA assigned) + , object_addr_ (addr) + , object_addr_set_ (0) + , preferred_path_ () + , next_ (0) { this->set (addr, use_dotted_decimal_addresses); } @@ -40,39 +42,37 @@ TAO_SCIOP_Endpoint::TAO_SCIOP_Endpoint (const char *host, CORBA::Short priority) : TAO_Endpoint (TAO_TAG_SCIOP_PROFILE, priority) - , host_ () - , port_ (port) - , object_addr_ (addr) - , object_addr_set_ (0) - , next_ (0) + , host_ (host) + , port_ (port) + , object_addr_ (addr) + , object_addr_set_ (0) + , preferred_path_ () + , next_ (0) { - if (host != 0) - this->host_ = host; } TAO_SCIOP_Endpoint::TAO_SCIOP_Endpoint (void) : TAO_Endpoint (TAO_TAG_SCIOP_PROFILE) - , host_ () - , port_ (683) // default port (IANA assigned) - , object_addr_ () - , object_addr_set_ (0) - , next_ (0) + , host_ () + , port_ (683) // default port (IANA assigned) + , object_addr_ () + , object_addr_set_ (0) + , preferred_path_ () + , next_ (0) { } TAO_SCIOP_Endpoint::TAO_SCIOP_Endpoint (const char *host, - CORBA::UShort port, - CORBA::Short priority) + CORBA::UShort port, + CORBA::Short priority) : TAO_Endpoint (TAO_TAG_SCIOP_PROFILE) - , host_ () - , port_ (port) - , object_addr_ () - , object_addr_set_ (0) - , next_ (0) + , host_ (host) + , port_ (port) + , object_addr_ () + , object_addr_set_ (0) + , preferred_path_ () + , next_ (0) { - if (host != 0) - this->host_ = host; - this->priority (priority); } @@ -80,6 +80,18 @@ TAO_SCIOP_Endpoint::~TAO_SCIOP_Endpoint (void) { } +TAO_SCIOP_Endpoint::TAO_IIOP_Endpoint (const TAO_SCIOP_Endpoint &rhs) + : TAO_Endpoint (rhs.tag_, + rhs.priority_) + , host_ (rhs.host_) + , port_ (rhs.port_) + , object_addr_ (rhs.object_addr_) + , object_addr_set_ (rhs.object_addr_set_) + , preferred_path_ (rhs.preferred_path_) + , next_ (0) +{ +} + int TAO_SCIOP_Endpoint::set (const ACE_INET_Addr &addr, int use_dotted_decimal_addresses) @@ -148,11 +160,9 @@ TAO_SCIOP_Endpoint::duplicate (void) { TAO_SCIOP_Endpoint *endpoint = 0; + // @@NOTE: Not at all exception safe ACE_NEW_RETURN (endpoint, - TAO_SCIOP_Endpoint (this->host_.in (), - this->port_, - this->object_addr_, - this->priority ()), + TAO_SCIOP_Endpoint (*this), 0); return endpoint; @@ -252,4 +262,100 @@ TAO_SCIOP_Endpoint::object_addr_i (void) const } } +CORBA::ULong +TAO_SCIOP_Endpoint::preferred_interfaces (TAO_ORB_Core *oc) +{ + ACE_CString tmp ( + oc->orb_params ()->preferred_interfaces ()); + + ssize_t pos = 0; + + pos = tmp.find (this->host_.in ()); + + TAO_IIOP_Endpoint *latest = this; + + CORBA::ULong count = 0; + + while (pos != ACE_CString::npos) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) Pos value is [%d] \n", + pos)); + + // Do we have a "," or an '\0'? + ssize_t new_pos = tmp.find (",", + pos + 1); + + // Length of the preferred path + int length = 0; + + if (new_pos == ACE_CString::npos) + length = tmp.length () - pos; + else + length = new_pos - pos; + + ACE_CString rem_tmp = tmp.substr (pos, length); + + // Search for the ":" + ssize_t col_pos = rem_tmp.find (":"); + + if (col_pos == ACE_CString::npos) continue; + + ACE_CString path = rem_tmp.substr (col_pos + 1); + + latest->preferred_path_.host = + CORBA::string_dup (path.c_str ()); + + if (TAO_debug_level > 3) + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) Adding path [%s] " + " as preferred path for [%s] \n", + path.c_str (), this->host_.in ())); + + pos = tmp.find (latest->host_.in (), + pos + length); + + if (pos != ACE_CString::npos) + { + TAO_Endpoint *tmp_ep = + latest->duplicate (); + + latest->next_ = dynamic_cast<TAO_IIOP_Endpoint *> (tmp_ep); + + if (latest->next_ == 0) return count; + + latest = latest->next_; + ++count; + } + } + + if (tmp.c_str () != 0 && + !oc->orb_params ()->enforce_pref_interfaces ()) + { + TAO_Endpoint *tmp_ep = latest->duplicate (); + + latest->next_ = + dynamic_cast<TAO_IIOP_Endpoint *> (tmp_ep); + + if (latest->next_ == 0) return count; + + latest->next_->preferred_path_.host = (const char *) 0; + ++count; + } + + return count; +} + +bool +TAO_SCIOP_Endpoint::is_preferred_network (void) const +{ + return (this->preferred_path_.host.in () != 0); +} + +const char * +TAO_SCIOP_Endpoint::preferred_network (void) const +{ + return this->preferred_path_.host.in (); +} + #endif /* TAO_HAS_SCIOP == 1 */ diff --git a/TAO/tao/Strategies/SCIOP_Endpoint.h b/TAO/tao/Strategies/SCIOP_Endpoint.h index c36d809202f..7c7791bf007 100644 --- a/TAO/tao/Strategies/SCIOP_Endpoint.h +++ b/TAO/tao/Strategies/SCIOP_Endpoint.h @@ -107,6 +107,12 @@ public: /// Set the port number. CORBA::UShort port (CORBA::UShort p); + /// Do we have a preferred local network for the target? + bool is_preferred_network (void) const; + + /// Return the preferred network if any. + const char *preferred_network (void) const; + private: /// Helper method for setting INET_Addr. @@ -116,6 +122,19 @@ private: /// Helper method for object_addr (). void object_addr_i (void) const; + /// Generate preferred interfaces from the options passed in by the + /// user. + CORBA::ULong preferred_interfaces (TAO_ORB_Core *oc); + + /// Canonical copy constructor + /** + * In private section to prevent clients from invoking this + * accidentally. Clients should only use duplicate () to make a depp + * copy + */ + TAO_SCIOP_Endpoint (const TAO_SCIOP_Endpoint &); + + /// String representing the host name. CORBA::String_var host_; @@ -129,10 +148,12 @@ private: /// Flag to indicate if the address has been resolved and set. mutable int object_addr_set_; + /// Preferred path for this endpoint. + TAO::IIOP_Endpoint_Info preferred_path_; + /// SCIOP Endpoints can be stringed into a list. Return the next /// endpoint in the list, if any. TAO_SCIOP_Endpoint *next_; - }; diff --git a/TAO/tao/Strategies/SCIOP_Profile.cpp b/TAO/tao/Strategies/SCIOP_Profile.cpp index d01935260ac..52330ee07bc 100644 --- a/TAO/tao/Strategies/SCIOP_Profile.cpp +++ b/TAO/tao/Strategies/SCIOP_Profile.cpp @@ -89,7 +89,6 @@ int TAO_SCIOP_Profile::decode_profile (TAO_InputCDR& cdr) { // Decode multiple endpoints, starting with the primary (endpoint_) - CORBA::StringSeq endpointSeq; cdr >> endpointSeq; @@ -106,15 +105,20 @@ TAO_SCIOP_Profile::decode_profile (TAO_InputCDR& cdr) // Add multiple endpoints > 1 - for (int i=endpointSeq.length() - 1; i > 0 ; i--) { - TAO_SCIOP_Endpoint *endpoint = 0; - ACE_NEW_RETURN (endpoint, - TAO_SCIOP_Endpoint (endpointSeq[i].in(), - this->endpoint_.port_, - this->endpoint_.priority()), - -1); - this->add_endpoint (endpoint); - } + for (int i=endpointSeq.length() - 1; i > 0 ; i--) + { + TAO_SCIOP_Endpoint *endpoint = 0; + ACE_NEW_RETURN (endpoint, + TAO_SCIOP_Endpoint (endpointSeq[i].in(), + this->endpoint_.port_, + this->endpoint_.priority()), + -1); + + this->count_ += + endpoint->preferred_interfaces (this->orb_core ()); + + this->add_endpoint (endpoint); + } // SCIOR has a max_streams variable // We are ignoring it for now since ACE SCTP code fixes at 1 anyway. diff --git a/TAO/tao/Strategies/SCIOP_Profile.h b/TAO/tao/Strategies/SCIOP_Profile.h index 8076034ef79..017f255f363 100644 --- a/TAO/tao/Strategies/SCIOP_Profile.h +++ b/TAO/tao/Strategies/SCIOP_Profile.h @@ -103,10 +103,25 @@ protected: * one endpoint. * * Currently, a profile contains more than one endpoint, i.e., - * list contains more than just the head, only when RTCORBA is enabled. - * However, in the near future, this will be used in nonRT - * mode as well, e.g., to support TAG_ALTERNATE_SCIOP_ADDRESS - * feature. + * list contains more than just the head, only for two cases + * (1) when RTCORBA is enabled and + * (2) the ORB is initialized with -ORBPreferredInterfaces option. + * However, in the near future, this will be used in for mode as + * well, e.g., to support TAG_ALTERNATE_IIOP_ADDRESS feature. + * + * This is probably as good a place to discuss how the list of + * endpoints is used for #2. If the ORB is configured to use + * preferred interfaces for invocation, TAO creates an endpoint per + * preferred interface. To be clear, every tuple + * <destination:target> will have an endpoint. What TAO essentially + * does is that creates it multiple endpoints so that the invocation + * code path can use existing iterating techniques to try one + * preferred interface after another (if the first did not work). If + * the ORB is configured with -ORBEnforcePreferredInterface set to + * false in addition to the ORBPreferredInterfaces option , TAO + * creates another endpoint with the preferred bit set to null, so + * that the invocation code can fall back to a SCTP stack returned + * local address. * Addressing info of the default endpoint, i.e., head of the list, * is transmitted using standard SCIOP ProfileBody components. See * <encode_endpoints> method documentation above for how the rest of diff --git a/TAO/tao/params.cpp b/TAO/tao/params.cpp index 1add777ba58..acd06795c40 100644 --- a/TAO/tao/params.cpp +++ b/TAO/tao/params.cpp @@ -15,21 +15,23 @@ ACE_RCSID (tao, TAO_ORB_Parameters::TAO_ORB_Parameters (void) - : endpoints_map_ (10), - mcast_discovery_endpoint_ (), - default_init_ref_ (TAO_DEFAULT_INIT_REFERENCE_INITIALIZER), - sock_rcvbuf_size_ (ACE_DEFAULT_MAX_SOCKET_BUFSIZ), - sock_sndbuf_size_ (ACE_DEFAULT_MAX_SOCKET_BUFSIZ), - nodelay_ (1), - cdr_memcpy_tradeoff_ (ACE_DEFAULT_CDR_MEMCPY_TRADEOFF), - use_lite_protocol_ (0), - use_dotted_decimal_addresses_ (0), - std_profile_components_ (1), - ace_sched_policy_ (ACE_SCHED_OTHER), - sched_policy_ (THR_SCHED_DEFAULT), - scope_policy_ (THR_SCOPE_PROCESS), - single_read_optimization_ (1), - disable_rt_collocation_resolver_ (false) + : endpoints_map_ (10) + , mcast_discovery_endpoint_ () + , default_init_ref_ (TAO_DEFAULT_INIT_REFERENCE_INITIALIZER) + , sock_rcvbuf_size_ (ACE_DEFAULT_MAX_SOCKET_BUFSIZ) + , sock_sndbuf_size_ (ACE_DEFAULT_MAX_SOCKET_BUFSIZ) + , nodelay_ (1) + , cdr_memcpy_tradeoff_ (ACE_DEFAULT_CDR_MEMCPY_TRADEOFF) + , use_lite_protocol_ (0) + , use_dotted_decimal_addresses_ (0) + , std_profile_components_ (1) + , ace_sched_policy_ (ACE_SCHED_OTHER) + , sched_policy_ (THR_SCHED_DEFAULT) + , scope_policy_ (THR_SCOPE_PROCESS) + , single_read_optimization_ (1) + , disable_rt_collocation_resolver_ (false) + , pref_network_ () + , enforce_preferred_interfaces_ (false) { for (int i = 0; i != TAO_NO_OF_MCAST_SERVICES; ++i) { @@ -189,3 +191,51 @@ TAO_ORB_Parameters::parse_and_add_endpoints (const ACE_CString &endpoints, return status; } + +bool +TAO_ORB_Parameters::preferred_interfaces (const char *s) +{ + ACE_CString tmp (s); + + ssize_t index = 0; + int comma = 0; + while ((index = tmp.find (",", index)) != ACE_CString::npos) + { + ++comma; + ++index; + } + + index = 0; + + int colon = 0; + while ((index = tmp.find (":", index)) != ACE_CString::npos) + { + ++colon; + ++index; + } + + if (colon != (comma + 1)) + return false; + + this->pref_network_ = tmp; + + return true; +} + +const char * +TAO_ORB_Parameters::preferred_interfaces (void) const +{ + return this->pref_network_.c_str (); +} + +void +TAO_ORB_Parameters::enforce_pref_interfaces (bool p) +{ + this->enforce_preferred_interfaces_ = p; +} + +bool +TAO_ORB_Parameters::enforce_pref_interfaces (void) const +{ + return this->enforce_preferred_interfaces_; +} diff --git a/TAO/tao/params.h b/TAO/tao/params.h index 186f11360f4..621f245d6d3 100644 --- a/TAO/tao/params.h +++ b/TAO/tao/params.h @@ -168,6 +168,13 @@ public: bool disable_rt_collocation_resolver (void) const; void disable_rt_collocation_resolver (bool); + /// Accepts the list of preferred interfaces and does a simple + /// semantic check on the string + bool preferred_interfaces (const char *s); + const char *preferred_interfaces (void) const; + + void enforce_pref_interfaces (bool p); + bool enforce_pref_interfaces (void) const; private: // Each "endpoint" is of the form: // @@ -269,6 +276,11 @@ private: * loaded if the RTORB is used. */ bool disable_rt_collocation_resolver_; + + /// Preferred network interfaces as a string + ACE_CString pref_network_; + + bool enforce_preferred_interfaces_; }; #if defined (__ACE_INLINE__) |