summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormichel_j <michel_j@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2005-05-27 20:57:46 +0000
committermichel_j <michel_j@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2005-05-27 20:57:46 +0000
commita22bab512b879b2b876f4eacab99c1ef37270cd8 (patch)
tree881acf5320e4b86e1494e6d006f9055cbadecbad
parent5b0dbd7ddb37eb4cd4542be4a47832675d4219e4 (diff)
downloadATCD-a22bab512b879b2b876f4eacab99c1ef37270cd8.tar.gz
ChangeLogTag: Fri May 27 15:54:44 2005 Justin Michel <michel_j@ociweb.com>
-rw-r--r--TAO/ChangeLog11
-rw-r--r--TAO/docs/Options.html47
-rw-r--r--TAO/tao/IIOP_Connector.cpp15
-rw-r--r--TAO/tao/IIOP_Endpoint.cpp221
-rw-r--r--TAO/tao/IIOP_Endpoint.h6
-rw-r--r--TAO/tao/IIOP_Profile.cpp5
-rw-r--r--TAO/tao/params.cpp71
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;
}