diff options
author | michel_j <michel_j@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2005-05-27 20:57:46 +0000 |
---|---|---|
committer | michel_j <michel_j@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2005-05-27 20:57:46 +0000 |
commit | 0f09672a72ac5be29757640d01ea5c5b592df36e (patch) | |
tree | 881acf5320e4b86e1494e6d006f9055cbadecbad /TAO | |
parent | c3c457efccc390f35a6b2248634b9d378c4d8f32 (diff) | |
download | ATCD-0f09672a72ac5be29757640d01ea5c5b592df36e.tar.gz |
ChangeLogTag: Fri May 27 15:54:44 2005 Justin Michel <michel_j@ociweb.com>
Diffstat (limited to 'TAO')
-rw-r--r-- | TAO/ChangeLog | 11 | ||||
-rw-r--r-- | TAO/docs/Options.html | 47 | ||||
-rw-r--r-- | TAO/tao/IIOP_Connector.cpp | 15 | ||||
-rw-r--r-- | TAO/tao/IIOP_Endpoint.cpp | 221 | ||||
-rw-r--r-- | TAO/tao/IIOP_Endpoint.h | 6 | ||||
-rw-r--r-- | TAO/tao/IIOP_Profile.cpp | 5 | ||||
-rw-r--r-- | TAO/tao/params.cpp | 71 |
7 files changed, 239 insertions, 137 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog index 8abfa82b7b9..1eeb774c228 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,3 +1,14 @@ +Fri May 27 15:54:44 2005 Justin Michel <michel_j@ociweb.com> + + * docs/Options.html: + * tao/IIOP_Connector.cpp: + * tao/IIOP_Endpoint.h: + * tao/IIOP_Endpoint.cpp: + * tao/IIOP_Profile.cpp: + * tao/params.cpp: + + Reimplemented the -ORBPreferredInterfaces option to support wildcards. + Fri May 27 15:30:21 2005 Justin Michel <michel_j@ociweb.com> * orbsvcs/ImplRepo_Service/Activator_NT_Service.h: diff --git a/TAO/docs/Options.html b/TAO/docs/Options.html index f7e3ac2cd22..4e6b3a6245b 100644 --- a/TAO/docs/Options.html +++ b/TAO/docs/Options.html @@ -459,34 +459,33 @@ more flexible address notations for IORs.</td> <tr> <td><code>-ORBPreferredInterfaces</code> <em>"targetNetwork:localNetwork,.."</em></td> - <td><a name="-ORBPreferredInterfaces"></a> This option allows - clients running on a multihomed host to pick a local - network/interface to communicate with a remote target. This - option looks for fully qualified interface names (either the - IP address or the DNS names) in the <em>targetNetwork</em> and - <em>localNetwork</em> parts. Multiple preferred tuples (a - tuple refers to a <em> target-to-local</em> network combo) can - be provided in the option using a comma seperated list. The - option doesn't yet support using jsut the network part of the - qualified name. + <td><a name="-ORBPreferredInterfaces"></a> This option allows + clients running on a multihomed host to pick a local + network/interface to communicate with a remote target. + When TAO attempts to establish a connection with a host + matching targetNetwork, then it will use the local ip address + matching localNetwork. Simple wildcards can be used for both + parameters, and multiple preferred interfaces can be specified + using comma separators. For example, for a machine with two network cards + identified by the ip addresses 192.168.1.10 and 192.168.1.20, you can + use -ORBPreferredInterfaces *=*10,*=*20. + Or to force all communication on the loopback address to try to first + use the loopback address, use -ORBPreferredInterfaces 127.0.0.1=127* . + <em>targetNetwork</em> can use any string, and must typically match + with the value read from an IOR. + <em>localNetwork</em> must use a dotted decimal address, because it + will be matched with the local ip interfaces. </tr> <tr> <td><code>-ORBEnforcePreferredInterfaces</code> <em>Yes/No</em></td> - <td><a name="-ORBEnforcePreferredInterfaces"></a> This option - specifies whether <CODE>-ORBPreferredInterfaces</CODE> option - needs to be enforced. The option is supposed to help with the following - usecase. It is possible that under some situations the - preferred local network may not have a route to the target - host/interface. The ORB can do one of the following. The ORB - coudl either choose a default local interface to send the - message or raise an exception to the application that - preferred interfaces are not usable. The option helps the ORB - decide on the course of action. If - <em> -ORBEnforcePreferredInterfaces</em> is set to true, - unusable preferred interfaces will make the ORB raise an - exception to the application. The defaul value for this option - is <em> no </em>. + <td><a name="-ORBEnforcePreferredInterfaces"></a> If this option is specified, then TAO will only try to use the interfaces + specified by the -ORBPreferredInterfaces option. By default, if a connection + cannot be made using a preferred interface, then TAO will attempt to use + the default interface. (INADDR_ANY) + Note : If none of the preferred interfaces apply to an outgoing connection + then they will not be enforced. Therefore, for this option to have any effect, + the connection through a legal preferred interface must fail. </tr> <tr> <td><code>-ORBLingerTimeout</code> <em>timeout</em></td> diff --git a/TAO/tao/IIOP_Connector.cpp b/TAO/tao/IIOP_Connector.cpp index 988d434dd59..e412edaf0bb 100644 --- a/TAO/tao/IIOP_Connector.cpp +++ b/TAO/tao/IIOP_Connector.cpp @@ -143,14 +143,12 @@ 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 (); + u_short port = 0; + const ACE_UINT32 ia_any = INADDR_ANY; + ACE_INET_Addr local_addr(port, ia_any); - ACE_INET_Addr local_addr; - - if (pn) - local_addr.set ((u_short) 0, - iiop_endpoint->preferred_network ()); + if (iiop_endpoint->is_preferred_network ()) + local_addr.set (port, iiop_endpoint->preferred_network ()); if (TAO_debug_level > 2) ACE_DEBUG ((LM_DEBUG, @@ -205,8 +203,7 @@ TAO_IIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r, // Make sure that we always do a remove_reference ACE_Event_Handler_var svc_handler_auto_ptr (svc_handler); - TAO_Transport *transport = - svc_handler->transport (); + TAO_Transport *transport = svc_handler->transport (); if (result == -1) { diff --git a/TAO/tao/IIOP_Endpoint.cpp b/TAO/tao/IIOP_Endpoint.cpp index c697c29b9a1..1a84410e3e2 100644 --- a/TAO/tao/IIOP_Endpoint.cpp +++ b/TAO/tao/IIOP_Endpoint.cpp @@ -19,6 +19,11 @@ ACE_RCSID (tao, #include "ace/OS_NS_stdio.h" #include "ace/os_include/os_netdb.h" +#include "ace/Vector_T.h" +#include "ace/ACE.h" +#include "ace/INET_Addr.h" +#include "ace/Sock_Connect.h" + TAO_IIOP_Endpoint::TAO_IIOP_Endpoint (const ACE_INET_Addr &addr, int use_dotted_decimal_addresses) : TAO_Endpoint (IOP::TAG_INTERNET_IOP) @@ -64,8 +69,8 @@ TAO_IIOP_Endpoint::TAO_IIOP_Endpoint (void) TAO_IIOP_Endpoint::TAO_IIOP_Endpoint (const char *host, CORBA::UShort port, CORBA::Short priority) - : TAO_Endpoint (IOP::TAG_INTERNET_IOP) - , host_ () + : TAO_Endpoint (IOP::TAG_INTERNET_IOP, priority) + , host_ (host) , port_ (port) , is_encodable_ (true) , object_addr_set_ (false) @@ -73,10 +78,6 @@ TAO_IIOP_Endpoint::TAO_IIOP_Endpoint (const char *host, , preferred_path_ () , next_ (0) { - if (host != 0) - this->host_ = host; - - this->priority (priority); } TAO_IIOP_Endpoint::~TAO_IIOP_Endpoint (void) @@ -84,8 +85,7 @@ TAO_IIOP_Endpoint::~TAO_IIOP_Endpoint (void) } TAO_IIOP_Endpoint::TAO_IIOP_Endpoint (const TAO_IIOP_Endpoint &rhs) - : TAO_Endpoint (rhs.tag_, - rhs.priority_) + : TAO_Endpoint (rhs.tag_, rhs.priority_) , host_ (rhs.host_) , port_ (rhs.port_) , is_encodable_ (rhs.is_encodable_) @@ -173,9 +173,7 @@ TAO_IIOP_Endpoint::duplicate (void) TAO_IIOP_Endpoint *endpoint = 0; // @@ NOTE: Not exception safe.. - ACE_NEW_RETURN (endpoint, - TAO_IIOP_Endpoint (*this), - 0); + ACE_NEW_RETURN (endpoint, TAO_IIOP_Endpoint (*this), 0); return endpoint; } @@ -230,92 +228,149 @@ TAO_IIOP_Endpoint::object_addr_i (void) const } } -CORBA::ULong -TAO_IIOP_Endpoint::preferred_interfaces (TAO_ORB_Core *oc) +static ACE_CString find_local(const ACE_Vector<ACE_CString>& local_ips, + const ACE_CString& pattern) { - ACE_CString tmp ( - oc->orb_params ()->preferred_interfaces ()); - - ssize_t pos = 0; + for (size_t i = 0; i < local_ips.size(); ++i) + { + ACE_CString ret = local_ips[i]; + if (ACE::wild_match(ret.c_str(), pattern.c_str())) + return ret; + } + return ""; +} - pos = tmp.find (this->host_.in ()); +TAO_IIOP_Endpoint* +TAO_IIOP_Endpoint::add_local_endpoint(TAO_IIOP_Endpoint* ep, const char* local) +{ + TAO_Endpoint* tmp = ep->duplicate(); + ep->next_ = static_cast<TAO_IIOP_Endpoint*>(tmp); + ep->next_->is_encodable_ = true; + ep->next_->preferred_path_.host = CORBA::string_dup(local); + return ep->next_; +} - TAO_IIOP_Endpoint *latest = this; +static void +get_ip_interfaces(ACE_Vector<ACE_CString>& local_ips) +{ + ACE_INET_Addr* tmp = 0; + size_t cnt = 0; + int err = ACE::get_ip_interfaces (cnt, tmp); + if (err != 0) + return; + // @@ Do we need to worry about IPv6 here? + ACE_TCHAR buf[32]; + for (size_t i = 0; i < cnt; ++i) + { + int err = tmp[i].addr_to_string(buf, 32); + ACE_ASSERT(err == 0); + ACE_CString tmp(ACE_TEXT_ALWAYS_CHAR(buf)); + ssize_t pos = tmp.find(':'); + if (pos != ACE_CString::npos) + tmp = tmp.substr(0, pos); + local_ips.push_back(tmp); + } + delete[] tmp; +} - CORBA::ULong count = 0; +// Given a comma separated list of preferred interface directives, which +// are of the form <wild_remote>=<wild_local>, this function will retrieve +// the list of preferred local ip addresses by matching wild_local against +// the list of all local ip interfaces, for any directive where wild_remote +// matches the host from our endpoint. +static void find_preferred_interfaces (const ACE_CString& host, + const ACE_CString& csvPreferred, + ACE_Vector<ACE_CString>& preferred) +{ + ACE_Vector<ACE_CString> local_ips; + get_ip_interfaces(local_ips); + if (local_ips.size() == 0) + return; + + // The outer loop steps through each preferred interface directive + // and chains a new endpoint if the remote interface matches the + // current endpoint. + size_t index = 0; + while (index < csvPreferred.length()) + { + ssize_t comma = csvPreferred.find(',', index); + ssize_t assign = csvPreferred.find('=', index); - while (pos != ACE_CString::npos) + if (assign == ACE_CString::npos) { - // 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) - { - pos = tmp.find (latest->host_.in (), - pos + length); - 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); + assign = csvPreferred.find(':', index); + if (assign == ACE_CString::npos) + { + ACE_ASSERT(assign != ACE_CString::npos); + return; + } + } - if (latest->next_ == 0) return count; + ACE_CString wild_local; + if (comma == ACE_CString::npos) + wild_local = csvPreferred.substr(assign + 1); + else + wild_local = csvPreferred.substr(assign + 1, comma - assign - 1); + ACE_CString wild_remote = csvPreferred.substr(index, assign - index); - latest->is_encodable_ = true; + index = static_cast<size_t>(comma) + 1; - latest = latest->next_; - ++count; - } + // For now, we just try to match against the host literally. In + // the future it might be worthwhile to resolve some aliases for + // this->host_ using DNS (and possibly reverse DNS) lookups. Then we + // could try matching against those too. + if (ACE::wild_match(host.c_str(), wild_remote.c_str(), false)) + { + // If it's a match, then it means we need to use a + // local interface that matches wild_local. + ACE_CString local = find_local(local_ips, wild_local); + if (local.length() > 0) + { + preferred.push_back(local); + } + else + { + // There is no matching local interface, so we can skip + // to the next preferred interface directive. + } } - - if (tmp.length () != 0 && - !oc->orb_params ()->enforce_pref_interfaces ()) + else { - TAO_Endpoint *tmp_ep = latest->duplicate (); - - latest->next_ = - dynamic_cast<TAO_IIOP_Endpoint *> (tmp_ep); - - if (latest->next_ == 0) return count; - - latest->is_encodable_ = true; + // The preferred interface directive is for a different + // remote endpoint. + } + if (comma == ACE_CString::npos) + break; + } +} - latest->next_->preferred_path_.host = (const char *) 0; - ++count; +CORBA::ULong +TAO_IIOP_Endpoint::preferred_interfaces (const char* csv, bool enforce) +{ + ACE_Vector<ACE_CString> preferred; + find_preferred_interfaces(this->host_.in(), csv, preferred); + CORBA::ULong count = preferred.size(); + if (count > 0) + { + this->is_encodable_ = true; + this->preferred_path_.host = CORBA::string_dup(preferred[0].c_str()); + TAO_IIOP_Endpoint* ep = this; + for (size_t i = 1; i < count; ++i) + { + ep = add_local_endpoint(ep, preferred[i].c_str()); } + // If we're not enforcing the preferred interfaces, then we can just add + // a new non-preferred endpoint to the end with a default local addr. + if (! enforce) + { + ep = add_local_endpoint(ep, ""); + } + else + { + --count; + } + } return count; } diff --git a/TAO/tao/IIOP_Endpoint.h b/TAO/tao/IIOP_Endpoint.h index 33d7429a916..3240859488f 100644 --- a/TAO/tao/IIOP_Endpoint.h +++ b/TAO/tao/IIOP_Endpoint.h @@ -122,7 +122,11 @@ private: /// Generate preferred interfaces from the options passed in by the /// user. - CORBA::ULong preferred_interfaces (TAO_ORB_Core *oc); + CORBA::ULong preferred_interfaces (const char* csvPreferred, bool enforce); + + /// Chain a new duplicate of ourself with the specified + /// local preferred interface. + TAO_IIOP_Endpoint* add_local_endpoint(TAO_IIOP_Endpoint* ep, const char* local); /// Canonical copy constructor /** diff --git a/TAO/tao/IIOP_Profile.cpp b/TAO/tao/IIOP_Profile.cpp index 3c254057dda..0ce59854060 100644 --- a/TAO/tao/IIOP_Profile.cpp +++ b/TAO/tao/IIOP_Profile.cpp @@ -100,8 +100,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 ()); + const char* csv = this->orb_core()->orb_params()->preferred_interfaces(); + bool enforce = this->orb_core()->orb_params()->enforce_pref_interfaces(); + this->count_ += this->endpoint_.preferred_interfaces(csv, enforce); return 1; } diff --git a/TAO/tao/params.cpp b/TAO/tao/params.cpp index 3c5e7b57655..0572dea4499 100644 --- a/TAO/tao/params.cpp +++ b/TAO/tao/params.cpp @@ -196,29 +196,64 @@ TAO_ORB_Parameters::parse_and_add_endpoints (const ACE_CString &endpoints, 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) + // Validates that s contains one or more comma separated + // interfaces each consisting of a string with a single + // assignment separator ('=' or ':') + // Any other char is legal, although '*' and '?' will be + // treated as wildcards. + const char* p = s; + bool expect_assign = false; + bool expect_comma = false; + bool expect_char = true; + bool expect_wild = true; + bool found_remote = false; + while (*p != 0) + { + switch (*p) { - ++comma; - ++index; + case ':': + case '=': + if (! expect_assign) + return false; + found_remote = true; + expect_assign = false; + expect_char = true; + expect_comma = false; + expect_wild = true; + break; + case ',': + if (! expect_comma) + return false; + found_remote = false; + expect_assign = false; + expect_char = true; + expect_comma = false; + expect_wild = true; + break; + case '*': + case '?': + if (! expect_wild) + return false; + expect_assign = ! found_remote; + expect_char = true; + expect_comma = found_remote; + expect_wild = false; + break; + default: + if (! expect_char) + return false; + expect_assign = ! found_remote; + expect_char = true; + expect_comma = found_remote; + expect_wild = true; + break; } - - index = 0; - - int colon = 0; - while ((index = tmp.find (":", index)) != ACE_CString::npos) - { - ++colon; - ++index; + ++p; } - - if (colon != (comma + 1)) + if (!expect_comma || expect_assign) return false; - this->pref_network_ = tmp; + this->pref_network_ = s; return true; } |