From 1efdd1ac4f544644c62c929bddea94f4a69e4187 Mon Sep 17 00:00:00 2001 From: sma Date: Thu, 16 May 2013 09:01:45 +0000 Subject: Thu May 16 09:01:00 UTC 2013 Simon Massey add -ORBListenerInterface to UDP/MIOP --- TAO/ChangeLog | 27 +++ TAO/bin/tao_other_tests.lst | 1 + TAO/docs/Options.html | 37 +++- .../orbsvcs/PortableGroup/UIPMC_Acceptor.cpp | 58 ++++++- TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Acceptor.h | 7 +- .../orbsvcs/PortableGroup/UIPMC_Factory.cpp | 65 +++++-- TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Factory.h | 4 + .../UIPMC_Mcast_Connection_Handler.cpp | 186 +++++++++++++++------ .../PortableGroup/UIPMC_Mcast_Connection_Handler.h | 13 +- TAO/orbsvcs/tests/Miop/McastLocal/McastHello.cpp | 65 +++++++ TAO/orbsvcs/tests/Miop/McastLocal/McastHello.h | 47 ++++++ TAO/orbsvcs/tests/Miop/McastLocal/McastLocal.mpc | 34 ++++ TAO/orbsvcs/tests/Miop/McastLocal/README | 19 +++ TAO/orbsvcs/tests/Miop/McastLocal/Test.idl | 26 +++ TAO/orbsvcs/tests/Miop/McastLocal/client.cpp | 92 ++++++++++ TAO/orbsvcs/tests/Miop/McastLocal/run_test.pl | 126 ++++++++++++++ TAO/orbsvcs/tests/Miop/McastLocal/server.cpp | 121 ++++++++++++++ TAO/orbsvcs/tests/Miop/McastLocal/svc_client.conf | 6 + TAO/orbsvcs/tests/Miop/McastLocal/svc_server1.conf | 6 + TAO/orbsvcs/tests/Miop/McastLocal/svc_server2.conf | 6 + TAO/tao/params.cpp | 50 +++--- TAO/tao/params.h | 5 +- 22 files changed, 906 insertions(+), 95 deletions(-) create mode 100644 TAO/orbsvcs/tests/Miop/McastLocal/McastHello.cpp create mode 100644 TAO/orbsvcs/tests/Miop/McastLocal/McastHello.h create mode 100644 TAO/orbsvcs/tests/Miop/McastLocal/McastLocal.mpc create mode 100644 TAO/orbsvcs/tests/Miop/McastLocal/README create mode 100644 TAO/orbsvcs/tests/Miop/McastLocal/Test.idl create mode 100644 TAO/orbsvcs/tests/Miop/McastLocal/client.cpp create mode 100755 TAO/orbsvcs/tests/Miop/McastLocal/run_test.pl create mode 100644 TAO/orbsvcs/tests/Miop/McastLocal/server.cpp create mode 100644 TAO/orbsvcs/tests/Miop/McastLocal/svc_client.conf create mode 100644 TAO/orbsvcs/tests/Miop/McastLocal/svc_server1.conf create mode 100644 TAO/orbsvcs/tests/Miop/McastLocal/svc_server2.conf diff --git a/TAO/ChangeLog b/TAO/ChangeLog index db34adb5734..45548a5157b 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,3 +1,30 @@ +Thu May 16 09:01:00 UTC 2013 Simon Massey + + * docs/Options.html: + * tao/params.h: + * tao/params.cpp: + * orbsvcs/orbsvcs/PortableGroup/UIPMC_Acceptor.h: + * orbsvcs/orbsvcs/PortableGroup/UIPMC_Acceptor.cpp: + * orbsvcs/orbsvcs/PortableGroup/UIPMC_Factory.h: + * orbsvcs/orbsvcs/PortableGroup/UIPMC_Factory.cpp: + * orbsvcs/orbsvcs/PortableGroup/UIPMC_Mcast_Connection_Handler.h: + * orbsvcs/orbsvcs/PortableGroup/UIPMC_Mcast_Connection_Handler.cpp: + * orbsvcs/tests/Miop/McastLocal/client.cpp: + * orbsvcs/tests/Miop/McastLocal/McastHello.cpp: + * orbsvcs/tests/Miop/McastLocal/McastHello.h: + * orbsvcs/tests/Miop/McastLocal/McastLocal.mpc: + * orbsvcs/tests/Miop/McastLocal/README: + * orbsvcs/tests/Miop/McastLocal/run_test.pl: + * orbsvcs/tests/Miop/McastLocal/server.cpp: + * orbsvcs/tests/Miop/McastLocal/svc_client.conf: + * orbsvcs/tests/Miop/McastLocal/svc_server1.conf: + * orbsvcs/tests/Miop/McastLocal/svc_server2.conf: + * orbsvcs/tests/Miop/McastLocal/Test.idl: + * bin/tao_other_tests.lst: + + Provide UIPMC Factory configuration option -ORBListenerInterfaces + see docs/Options.html for details. + Wed May 15 18:21:40 UTC 2013 Johnny Willemsen * tao/Exception.cpp: diff --git a/TAO/bin/tao_other_tests.lst b/TAO/bin/tao_other_tests.lst index deca7a3ed5a..68ff86d2cfd 100644 --- a/TAO/bin/tao_other_tests.lst +++ b/TAO/bin/tao_other_tests.lst @@ -205,6 +205,7 @@ TAO/orbsvcs/tests/Security/EndpointPolicy/run_test.pl: SSL !STATIC !DISABLE_INTE TAO/orbsvcs/tests/Security/Null_Cipher/run_test.pl: SSL !STATIC !DISABLE_INTERCEPTORS !ACE_FOR_TAO !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO TAO/orbsvcs/tests/Security/MT_BiDir_SSL/run_test.pl: SSL !STATIC !DISABLE_INTERCEPTORS !ACE_FOR_TAO !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !GIOP10 !DISABLE_BIDIR !LynxOS TAO/orbsvcs/tests/Miop/McastHello/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !STATIC !NO_MCAST +TAO/orbsvcs/tests/Miop/McastLocal/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !STATIC !NO_MCAST TAO/orbsvcs/tests/Miop/McastZIOP/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !STATIC !NO_MCAST ZLIB TAO/orbsvcs/tests/Miop/McastPreferredInterfaces/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !STATIC !NO_MCAST TAO/orbsvcs/tests/Miop/McastPreferredInterfaces/run_test_ipv6.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !STATIC !NO_MCAST IPV6 diff --git a/TAO/docs/Options.html b/TAO/docs/Options.html index 7d075cabdff..50938b3278b 100644 --- a/TAO/docs/Options.html +++ b/TAO/docs/Options.html @@ -1842,7 +1842,9 @@ strategy. ‑ORBListenOnAll 0 | 1 - This is a server-side (listener) option that by default is disabled. + This is a server-side (listener) option that by default is disabled; however + this option only takes effect where no ‑ORBListenerInterfaces + directives (if any, see below) match the actual multicast address being set-up.

If disabled (0) the multicast address will be listened for only on the default multicast interface associated with the INADDR_ANY local address (normally the first such local interface on the system), the loopback interface is normally excluded.

@@ -1850,6 +1852,39 @@ strategy. interface(s) which are multicast enabled (again the loopback interface is normally excluded). + + ‑ORBListenerInterfaces targetNetwork=localNetwork[,...] | CopyPreferredInterfaces + This is a server-side (listener) option that specifies, on a multihomed host, + which network/interface(s) are to be used to listen for communications from the multicast addressed + remote client(s). If this option is unspecified (or if none of the given + targetNetwork=localNetwork patterns match the current addresses being set-up for + the attempted listener) then the default listener will be set-up as specified or defaulted with the + ‑ORBListenOnAll see above. + Otherwise when TAO attempts to establish the listeners for a targetNetwork multicast + address(es), it will use the local ip address(es) matching the localNetwork string. Simple + wildcards can be used for both parameters, and multiple paired targetNetwork=localNetwork + strings can be specified using comma separators (no embedded spaces allowed) or via additional + ‑ORBListenerInterfaces directives. It is also possiable to specify loopback + and/or multiple interfaces at the same time for each listener established via such + ‑ORBListenerInterfaces directives. +

+ 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 the single directive + ‑ORBListenerInterfaces 239.255.*=*10,224.255.*=*20 or the pair of directives + ‑ORBListenerInterfaces 239.255.*=*10 ‑ORBListenerInterfaces 224.255.*=*20 + to establish the link to listen for 239.255.* multicast addresses on the first interface, and + 224.255.* multicast addresses on the second interface.

+ targetNetwork can use any string, but must typically match the value writen into the IOR and so + will usually be a dotted decimal multicast address in the administrative "site local" range, + (224.255.0.0 to 238.255.255.255) or (239.255.0.0 to 239.255.255.255). +

localNetwork must use a local dotted decimal address, because it will be matched with + the local ip interfaces.

+ The same client-side (sender) assignments as specified by the ORB_init supplied command line option(s) + ‑ORBPreferredInterfaces can be duplicated by specifying the single special + CopyPreferredInterfaces parameter as in ‑ORBListenerInterfaces CopyPreferredInterfaces + (which may be prefixed and/or postfixed by other ‑ORBListenerInterfaces targetNetwork=localNetwork + options as required). + diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Acceptor.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Acceptor.cpp index 9b0629baa60..22aae4554e0 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Acceptor.cpp +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Acceptor.cpp @@ -17,14 +17,16 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL TAO_UIPMC_Acceptor::TAO_UIPMC_Acceptor ( - bool listen_on_all_ifs) + bool listen_on_all_ifs, + const char *listener_interfaces) : TAO_Acceptor (IOP::TAG_UIPMC), addrs_ (0), hosts_ (0), endpoint_count_ (0), version_ (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR), orb_core_ (0), - listen_on_all_ (listen_on_all_ifs) + listen_on_all_ (listen_on_all_ifs), + listener_interfaces_ (listener_interfaces) { } @@ -228,6 +230,56 @@ TAO_UIPMC_Acceptor::open_i ( const ACE_INET_Addr &addr, ACE_Reactor *reactor) { + // Check for the special "CopyPreferredInterfaces" token(s) stored in the + // listener_interfaces_ string. If found, subsitute each one for the actual + // -ORBPreferredInterfaces string set on the ORB_init command line. + for (ACE_CString::size_type foundToken = + this->listener_interfaces_.find (CopyPreferredInterfaceToken); + ACE_CString::npos != foundToken; + foundToken = + this->listener_interfaces_.find (CopyPreferredInterfaceToken)) + { + ACE_CString + left = this->listener_interfaces_.substr (0, foundToken), + right = this->listener_interfaces_.substr (foundToken + + static_cast ( + sizeof (CopyPreferredInterfaceToken)-1u )); + const char *preferred_interfaces = + this->orb_core_->orb_params ()->preferred_interfaces (); + if (preferred_interfaces && preferred_interfaces[0]) + { + // Subsitute the token for the actual string, if not null + // left/right will always end/start with a ',' + this->listener_interfaces_ = + left + preferred_interfaces + right; + } + else + { + // No preferred_interfaces specified + if (',' == right[0]) // Right is not null + { + // Need to remove the token, AND one of the seporating ',' + this->listener_interfaces_ = + left + right.substr (1); + } + else // Since right must also be a null string + { + const ACE_CString::size_type length= left.length (); + if (length) + { + // Since we only have the left, remove the trailing ',' + this->listener_interfaces_ = left.substr (0, length-1); + } + else + { + // Since BOTH left and right are empty, removing the + // token leaves an empty string. + this->listener_interfaces_ = ""; + } + } + } + } // End loop replacing all preferred_interfaces tokens. + // Create our connection handler and pass it our configurtion options. TAO_UIPMC_Mcast_Connection_Handler *connection_handler = 0; ACE_NEW_RETURN (connection_handler, @@ -235,6 +287,8 @@ TAO_UIPMC_Acceptor::open_i ( -1); connection_handler->local_addr (addr); connection_handler->listen_on_all (this->listen_on_all_); + connection_handler->listener_interfaces ( + this->listener_interfaces_.c_str ()); if (connection_handler->open (0)) { ORBSVCS_DEBUG ((LM_ERROR, diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Acceptor.h b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Acceptor.h index 92cfacea3fc..aa3add29a2f 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Acceptor.h +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Acceptor.h @@ -32,6 +32,9 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL +// Note [] as sizeof used to infer length +static const char CopyPreferredInterfaceToken[]= "$$$$"; + // TAO UIPMC_Acceptor concrete call definition /** @@ -45,7 +48,8 @@ class TAO_PortableGroup_Export TAO_UIPMC_Acceptor : public TAO_Acceptor { public: /// Constructor. - TAO_UIPMC_Acceptor (bool listen_on_all_ifs); + TAO_UIPMC_Acceptor (bool listen_on_all_ifs, + const char *listener_interfaces); /// Destructor. ~TAO_UIPMC_Acceptor (void); @@ -143,6 +147,7 @@ protected: private: bool listen_on_all_; + ACE_CString listener_interfaces_; }; TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Factory.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Factory.cpp index 7dc9964246c..bd89d905f7b 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Factory.cpp +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Factory.cpp @@ -5,8 +5,10 @@ #include "orbsvcs/PortableGroup/UIPMC_Acceptor.h" #include "orbsvcs/PortableGroup/UIPMC_Connector.h" #include "tao/ORB_Constants.h" +#include "tao/params.h" // TAO_ORB_Parameters::check_preferred_interfaces_string () #include "ace/OS_NS_strings.h" #include "ace/UUID.h" +#include "ace/Arg_Shifter.h" static const char the_prefix[] = "uipmc"; @@ -16,7 +18,8 @@ TAO_UIPMC_Protocol_Factory::TAO_UIPMC_Protocol_Factory (void) : TAO_Protocol_Factory (IOP::TAG_UIPMC), major_ (TAO_DEF_GIOP_MAJOR), minor_ (TAO_DEF_GIOP_MINOR), - listen_on_all_(false) + listen_on_all_ (false), + listener_interfaces_ () { } @@ -48,7 +51,9 @@ TAO_UIPMC_Protocol_Factory::make_acceptor (void) { TAO_Acceptor *acceptor = 0; ACE_NEW_RETURN (acceptor, - TAO_UIPMC_Acceptor (this->listen_on_all_), + TAO_UIPMC_Acceptor ( + this->listen_on_all_, + this->listener_interfaces_.c_str ()), 0); return acceptor; @@ -58,25 +63,65 @@ int TAO_UIPMC_Protocol_Factory::init (int argc, ACE_TCHAR* argv []) { - for (int curarg = 0; curarg < argc; ++curarg) + ACE_Arg_Shifter arg_shifter (argc, argv); + + while (arg_shifter.is_anything_left ()) { + const ACE_TCHAR *current_arg = 0; + // This option lets you override the default - if (ACE_OS::strcasecmp (argv[curarg], - ACE_TEXT ("-ORBListenOnAll")) == 0) + if (0 != (current_arg = arg_shifter.get_the_parameter + (ACE_TEXT("-ORBListenOnAll")))) + { + this->listen_on_all_ = !!ACE_OS::atoi (current_arg); + arg_shifter.consume_arg (); + } + else if (0 != (current_arg = arg_shifter.get_the_parameter + (ACE_TEXT("-ORBListenerInterfaces"))) || + 0 != (current_arg = arg_shifter.get_the_parameter + (ACE_TEXT("-ORBListenerInterface"))) || + 0 != (current_arg = arg_shifter.get_the_parameter + (ACE_TEXT("-ORBListenInterfaces"))) || + 0 != (current_arg = arg_shifter.get_the_parameter + (ACE_TEXT("-ORBListenInterface"))) ) { - ++curarg; - if (curarg < argc) + if (0 == ACE_OS::strcasecmp (current_arg, ACE_TEXT ("CopyPreferredInterfaces")) || + 0 == ACE_OS::strcasecmp (current_arg, ACE_TEXT ("CopyPreferredInterface")) ) { - if (curarg < argc) - this->listen_on_all_ = (bool) ACE_OS::atoi (argv[curarg]); + // Add a special token (see TAO_UIPMC_Acceptor) which will be + // subsituted (when we have access to the orb->params). + if (this->listener_interfaces_.length ()) + this->listener_interfaces_+= ','; + this->listener_interfaces_+= CopyPreferredInterfaceToken; } + else + { + const char *const always_char = ACE_TEXT_ALWAYS_CHAR (current_arg); + if (TAO_ORB_Parameters::check_preferred_interfaces_string (always_char)) + { + // Append any valid string to those already specified + // (by other -ORBListenerInterfaces options that have been + // seen previously) + if (this->listener_interfaces_.length ()) + this->listener_interfaces_+= ','; + this->listener_interfaces_+= always_char; + } + else + ORBSVCS_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO_UIPMC_Protocol_Factory::init - ") + ACE_TEXT ("ignoring invalid -ORBListenerInterfaces %C\n"), + always_char)); + } + + arg_shifter.consume_arg (); } else { ORBSVCS_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO_UIPMC_Protocol_Factory::init - ") ACE_TEXT ("ignoring unknown option <%s>\n"), - argv[curarg])); + arg_shifter.get_current ())); + arg_shifter.ignore_arg (); } } diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Factory.h b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Factory.h index 3b08b2e64e2..1caf60ae296 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Factory.h +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Factory.h @@ -60,9 +60,13 @@ private: /// compatibility with old clients. int major_; int minor_; + /// Should we override the default behaviour (whatever it is) to listen on /// all interfaces bool listen_on_all_; + + /// Any specified and valid -ORBListenerInterfaces option string + ACE_CString listener_interfaces_; }; TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Mcast_Connection_Handler.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Mcast_Connection_Handler.cpp index 134a37ff253..9e388afa55e 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Mcast_Connection_Handler.cpp +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Mcast_Connection_Handler.cpp @@ -17,6 +17,10 @@ #include "tao/Base_Transport_Property.h" #include "tao/Resume_Handle.h" #include "tao/Protocols_Hooks.h" +#include "tao/IIOP_Endpoint.h" // TAO_IIOP_Endpoint::find_preferred_interfaces () + +#include "ace/Vector_T.h" + TAO_BEGIN_VERSIONED_NAMESPACE_DECL @@ -24,13 +28,18 @@ TAO_UIPMC_Mcast_Connection_Handler::TAO_UIPMC_Mcast_Connection_Handler ( ACE_Thread_Manager *t) : TAO_UIPMC_MCAST_SVC_HANDLER (t, 0 , 0), TAO_Connection_Handler (0), - listen_on_all_(false) + listen_on_all_ (false), + listener_interfaces_ () { // This constructor should *never* get called, it is just here to // make the compiler happy: the default implementation of the // Creation_Strategy requires a constructor with that signature, we // don't use that implementation, but some (most?) compilers // instantiate it anyway. + ORBSVCS_DEBUG ((LM_DEBUG, + ACE_TEXT("TAO (%P|%t) - UIPMC_Mcast_Connection_Handler, ") + ACE_TEXT("this constructor should never be called.\n") + ACE_TEXT(" Check svc.conf configuration.\n") )); ACE_ASSERT (0); } @@ -38,11 +47,12 @@ TAO_UIPMC_Mcast_Connection_Handler::TAO_UIPMC_Mcast_Connection_Handler ( TAO_ORB_Core *orb_core) : TAO_UIPMC_MCAST_SVC_HANDLER (orb_core->thr_mgr (), 0, 0), TAO_Connection_Handler (orb_core), - listen_on_all_(false) + listen_on_all_ (false), + listener_interfaces_ () { TAO_UIPMC_Mcast_Transport *specific_transport = 0; - ACE_NEW(specific_transport, - TAO_UIPMC_Mcast_Transport (this, orb_core)); + ACE_NEW (specific_transport, + TAO_UIPMC_Mcast_Transport (this, orb_core)); // store this pointer (indirectly increment ref count) this->transport (specific_transport); @@ -59,7 +69,7 @@ TAO_UIPMC_Mcast_Connection_Handler::~TAO_UIPMC_Mcast_Connection_Handler (void) ORBSVCS_ERROR ((LM_ERROR, ACE_TEXT ("TAO (%P|%t) - UIPMC_Mcast_Connection_Handler::") ACE_TEXT ("~UIPMC_Mcast_Connection_Handler, ") - ACE_TEXT ("release_os_resources() failed '%m'\n"))); + ACE_TEXT ("release_os_resources() failed (Errno: '%m')\n"))); } } @@ -94,72 +104,133 @@ TAO_UIPMC_Mcast_Connection_Handler::open_handler (void *v) } int -TAO_UIPMC_Mcast_Connection_Handler::open (void*) +TAO_UIPMC_Mcast_Connection_Handler::open (void *) { - if (this->listen_on_all_) + // Stingify the target multicast group IP address + char target_multicast_group[INET6_ADDRSTRLEN]; + this->local_addr_.get_host_addr (target_multicast_group, sizeof target_multicast_group); + + // Check if we are supposed to be listening on specified interface(s) + CORBA::ULong preferred_size= 0u; + if (this->listener_interfaces_[0]) + { + // Since we have been told to match some targetNetwork=localNetwork listener interface + // strings, attempt to match the actual targetHost and our actual network interface cards + // to see how many joins we need to attempt. + ACE_Vector preferred; + TAO_IIOP_Endpoint::find_preferred_interfaces ( + target_multicast_group, + this->listener_interfaces_, + preferred); + preferred_size= preferred.size (); + +#ifndef ALLOW_UNICAST_MIOP + // If we are attempting to join ANY preferred listener interfaces, at least one join must + // complete in the loop below for a successful outcome. If we have NO valid preferred + // listener interfaces, then we are concidered successful HERE so as to allow the + // default join to be attempted later. + bool success= !preferred_size; +#endif // ALLOW_UNICAST_MIOP + for (CORBA::ULong i= 0u; i < preferred_size; ++i) + if (0 == this->peer ().join (this->local_addr_, 1, preferred[i].c_str ())) + { + success= true; // At least one perferred listener interface join succeeded + if (TAO_debug_level > 5) + ORBSVCS_DEBUG ((LM_DEBUG, + ACE_TEXT("TAO (%P|%t) - UIPMC_Mcast_Connection_Handler::open, ") + ACE_TEXT("listening for multicast %C:%u on %C\n"), + target_multicast_group, + this->local_addr_.get_port_number (), + preferred[i].c_str () + )); + } + else if (TAO_debug_level) + ORBSVCS_DEBUG ((LM_ERROR, + ACE_TEXT("TAO (%P|%t) - UIPMC_Mcast_Connection_Handler::open, ") + ACE_TEXT("failed to join multicast %C:%u on %C (Errno: '%m')\n"), + target_multicast_group, + this->local_addr_.get_port_number (), + preferred[i].c_str () + )); + +#ifndef ALLOW_UNICAST_MIOP + if (!success) + return -1; // No joins worked, we are not listening. +#endif // ALLOW_UNICAST_MIOP + } + + // If we have NO valid preferred listener interfaces matches, then we attempt the + // normal default join to the system default/all interface(s). + if (!preferred_size) { - this->peer ().opts(ACE_SOCK_Dgram_Mcast::OPT_NULLIFACE_ALL | this->peer ().opts()); + if (this->listen_on_all_) + this->peer ().opts(ACE_SOCK_Dgram_Mcast::OPT_NULLIFACE_ALL | this->peer ().opts()); + + if (0 == this->peer ().join (this->local_addr_)) + { + if (TAO_debug_level > 5) + ORBSVCS_DEBUG ((LM_DEBUG, + ACE_TEXT("TAO (%P|%t) - UIPMC_Mcast_Connection_Handler::open, ") + ACE_TEXT("listening for multicast %C:%u on %C\n"), + target_multicast_group, + this->local_addr_.get_port_number (), + ((this->listen_on_all_) ? "All" : "Default") + )); + } + else + { + if (TAO_debug_level) + ORBSVCS_DEBUG ((LM_ERROR, + ACE_TEXT("TAO (%P|%t) - UIPMC_Mcast_Connection_Handler::open, ") + ACE_TEXT("failed to join multicast %C:%u on %C (Errno: '%m')\n"), + target_multicast_group, + this->local_addr_.get_port_number (), + ((this->listen_on_all_) ? "All" : "Default") + )); + +#ifndef ALLOW_UNICAST_MIOP + return -1; // No joins worked, we are not listening. +#endif // ALLOW_UNICAST_MIOP + } } + // Attempt to set the socket's receive buffer size. TAO_MIOP_Resource_Factory *const factory = ACE_Dynamic_Service::instance ( - this->orb_core ()->configuration(), + this->orb_core ()->configuration (), ACE_TEXT ("MIOP_Resource_Factory")); TAO_DIOP_Protocol_Properties protocol_properties; protocol_properties.recv_buffer_size_ = factory->receive_buffer_size () ? factory->receive_buffer_size () : this->orb_core ()->orb_params ()->sock_rcvbuf_size (); - - if (this->peer ().join (this->local_addr_) == 0) - { - if (TAO_debug_level > 5) - { - char tmp[INET6_ADDRSTRLEN]; - this->local_addr_.get_host_addr (tmp, sizeof tmp); - ORBSVCS_DEBUG ((LM_DEBUG, - ACE_TEXT("TAO (%P|%t) - UIPMC_Mcast_Connection_Handler::open, ") - ACE_TEXT("subscribed to multicast group at %C:%u\n"), - tmp, - this->local_addr_.get_port_number () - )); - } - } -#ifndef ALLOW_UNICAST_MIOP - else - { - char tmp[INET6_ADDRSTRLEN]; - this->local_addr_.get_host_addr (tmp, sizeof tmp); - ORBSVCS_DEBUG ((LM_ERROR, - ACE_TEXT("TAO (%P|%t) - UIPMC_Mcast_Connection_Handler::open, ") - ACE_TEXT("failed to subscribe to multicast group at %C:%u '%m'\n"), - tmp, - this->local_addr_.get_port_number () + if (-1 == this->set_socket_option ( + this->peer (), + 0, + protocol_properties.recv_buffer_size_)) + ORBSVCS_ERROR ((LM_ERROR, + ACE_TEXT ("TAO (%P|%t) - UIPMC_Mcast_Connection_Handler::") + ACE_TEXT ("open, failed to set RCVBUF ") + ACE_TEXT ("for multicast %C:%u (Errno: '%m')\n"), + target_multicast_group, + this->local_addr_.get_port_number () )); - return -1; - } -#endif // ALLOW_UNICAST_MIOP - if (this->set_socket_option (this->peer (), - 0, - protocol_properties.recv_buffer_size_) == -1) - { - return -1; - } - - // The socket has to be set in non-blocking mode in order to work with + // The socket also has to be set in non-blocking mode in order to work with // TAO_UIPMC_Mcast_Transport::handle_input(). if (this->peer ().enable (ACE_NONBLOCK) == -1) { - if (TAO_debug_level) - ORBSVCS_ERROR ((LM_ERROR, - ACE_TEXT ("TAO (%P|%t) - UIPMC_Mcast_Connection_Handler::") - ACE_TEXT ("open, failed to set to non-blocking mode ") - ACE_TEXT ("'%m'\n"))); - - return -1; + ORBSVCS_ERROR ((LM_ERROR, + ACE_TEXT ("TAO (%P|%t) - UIPMC_Mcast_Connection_Handler::") + ACE_TEXT ("open, failed to set non-blocking ") + ACE_TEXT ("for multicast %C:%u (Errno: '%m')\n"), + target_multicast_group, + this->local_addr_.get_port_number () + )); + return -1; // Can't work without this setting. } + // Pass the connection over to the transport. this->transport ()->id ((size_t) this->peer ().get_handle ()); return 0; } @@ -198,8 +269,9 @@ TAO_UIPMC_Mcast_Connection_Handler::handle_output (ACE_HANDLE handle) } int -TAO_UIPMC_Mcast_Connection_Handler::handle_timeout (const ACE_Time_Value &, - const void *) +TAO_UIPMC_Mcast_Connection_Handler::handle_timeout ( + const ACE_Time_Value &, + const void *) { // Using this to ensure this instance will be deleted (if necessary) // only after reset_state(). Without this, when this refcount==1 - @@ -279,4 +351,10 @@ TAO_UIPMC_Mcast_Connection_Handler::listen_on_all(bool value) this->listen_on_all_ = value; } +void +TAO_UIPMC_Mcast_Connection_Handler::listener_interfaces (const char *value) +{ + this->listener_interfaces_ = value; +} + TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Mcast_Connection_Handler.h b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Mcast_Connection_Handler.h index 91653af3549..2ec8a772b73 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Mcast_Connection_Handler.h +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Mcast_Connection_Handler.h @@ -52,9 +52,7 @@ class TAO_PortableGroup_Export TAO_UIPMC_Mcast_Connection_Handler : public TAO_UIPMC_MCAST_SVC_HANDLER, public TAO_Connection_Handler { - public: - TAO_UIPMC_Mcast_Connection_Handler (ACE_Thread_Manager* t = 0); /// Constructor. arg parameter is used by the Acceptor to pass the @@ -100,14 +98,13 @@ public: void local_addr (const ACE_INET_Addr &addr); /// Set this to listen on all interfaces - void listen_on_all(bool value); + void listen_on_all (bool value); - // UIPMC Additions - End + /// Set this to specify ListenerInterfaces pairs + /// (Same as -ORBPreferredInterfaces but for listeners) + void listener_interfaces (const char *); protected: - - // UIPMC Additions - Begin - // This is always the remote address ACE_INET_Addr addr_; @@ -117,6 +114,8 @@ protected: // Should we listen on all interfaces bool listen_on_all_; + // Which interfaces are to be listening for the group address + ACE_CString listener_interfaces_; // UIPMC Additions - End //@{ diff --git a/TAO/orbsvcs/tests/Miop/McastLocal/McastHello.cpp b/TAO/orbsvcs/tests/Miop/McastLocal/McastHello.cpp new file mode 100644 index 00000000000..f195a6e5c9a --- /dev/null +++ b/TAO/orbsvcs/tests/Miop/McastLocal/McastHello.cpp @@ -0,0 +1,65 @@ +// +// $Id$ +// +#include "McastHello.h" + + + +McastHello::McastHello (CORBA::ORB_ptr orb, + int instance) + : orb_ (CORBA::ORB::_duplicate (orb)), + instance_ (instance), + small_request_status_ (0), + large_request_status_ (0) +{ +} + +void +McastHello::send_forty_two (CORBA::Long forty_two) +{ + if (this->small_request_status_ == 0 && + forty_two == 42) + { + this->small_request_status_ = 1; + } + else + this->small_request_status_ = 0; +} + +void +McastHello::send_large_octet_array (const Test::Octets &payload) +{ + CORBA::Boolean valid_payload = 1; + for (CORBA::ULong i = 0; i < payload.length (); ++i) + { + if ((CORBA::ULong) payload [i] != i % 256) + { + ACE_ERROR ((LM_ERROR, + "ERROR: (%P|%t) McastHello::send_large_octet_array, " + "unexpected value at index %d (%d != %d)\n", + i, payload [i], i % 256)); + valid_payload = 0; + break; + } + } + + if (this->large_request_status_ == 0 && + valid_payload == 1) + { + this->large_request_status_ = 1; + } + else + this->large_request_status_ = 0; +} + +void +McastHello::shutdown (void) +{ + this->orb_->shutdown (0); +} + +CORBA::Boolean +McastHello::get_status () +{ + return this->large_request_status_ && this->small_request_status_; +} diff --git a/TAO/orbsvcs/tests/Miop/McastLocal/McastHello.h b/TAO/orbsvcs/tests/Miop/McastLocal/McastHello.h new file mode 100644 index 00000000000..c6a85237a95 --- /dev/null +++ b/TAO/orbsvcs/tests/Miop/McastLocal/McastHello.h @@ -0,0 +1,47 @@ +// +// $Id$ +// + +#ifndef MCASTHELLO_H +#define MCASTHELLO_H +#include /**/ "ace/pre.h" + +#include "TestS.h" + +/// Implement the Test::McastHello interface +class McastHello + : public virtual POA_Test::McastHello +{ +public: + /// Constructor + McastHello (CORBA::ORB_ptr orb, + int instance); + + // = The skeleton methods + virtual void send_forty_two (CORBA::Long forty_two); + + virtual void shutdown (void); + + /// Return whether all test requests have been received successfully. + CORBA::Boolean get_status (); + + // Silence the builds + void send_large_octet_array (const Test::Octets &); + +private: + /// Use an ORB reference to convert strings to objects and shutdown + /// the application. + CORBA::ORB_var orb_; + + /// The instance number. (Useful when debugging multiple servants) + int instance_; + + /// Track the success/failure of the small request. + CORBA::Boolean small_request_status_; + + /// Track the success/failure of the large request. + CORBA::Boolean large_request_status_; +}; + +#include /**/ "ace/post.h" +#endif /* MCASTHELLO_H */ diff --git a/TAO/orbsvcs/tests/Miop/McastLocal/McastLocal.mpc b/TAO/orbsvcs/tests/Miop/McastLocal/McastLocal.mpc new file mode 100644 index 00000000000..71b6551358b --- /dev/null +++ b/TAO/orbsvcs/tests/Miop/McastLocal/McastLocal.mpc @@ -0,0 +1,34 @@ +// -*- MPC -*- +// $Id$ + +project(*idl): taoidldefaults { + IDL_Files { + Test.idl + } + custom_only = 1 +} + +project(*server): orbsvcsexe, portablegroup, portableserver { + after += *idl + exename = server + Source_Files { + McastHello.cpp + TestS.cpp + TestC.cpp + server.cpp + } + IDL_Files { + } +} + +project(*client): orbsvcsexe, portablegroup, portableserver { + after += *idl + exename = client + Source_Files { + TestC.cpp + client.cpp + } + IDL_Files { + } +} + diff --git a/TAO/orbsvcs/tests/Miop/McastLocal/README b/TAO/orbsvcs/tests/Miop/McastLocal/README new file mode 100644 index 00000000000..c9a64727ba0 --- /dev/null +++ b/TAO/orbsvcs/tests/Miop/McastLocal/README @@ -0,0 +1,19 @@ +/** +$Id$ + +@page McastLocal Test README File + +This test is a copy of the McastHello test but modified so that the +servers are listening only on the loopback interface (via the + "-ORBListenerInterface *=127.0.0.1" in the svc_server1.conf for server1 +and the + "-ORBListenerInterface CopyPreferredInterfaces" in the svc_server2.conf +and the server2's otherwise redundant command line + "-ORBPreferredInterface *=127.0.0.1" orb_init parameter). +The client has also been modified to send the broadcast out on the +loopback interface (via its + "-ORBPreferredInterface *=127.0.0.1" orb_init parameter). + +This is testing that these configuartion options are correctly working +for MIOP. +**/ diff --git a/TAO/orbsvcs/tests/Miop/McastLocal/Test.idl b/TAO/orbsvcs/tests/Miop/McastLocal/Test.idl new file mode 100644 index 00000000000..e3babc5d5a2 --- /dev/null +++ b/TAO/orbsvcs/tests/Miop/McastLocal/Test.idl @@ -0,0 +1,26 @@ +// +// $Id$ +// + +/// Put the interfaces in a module, to avoid global namespace pollution +module Test +{ + /// A sequence of octets for sending large messages. + typedef sequence Octets; + + /// A very simple interface + interface McastHello + { + /// A method to test out a small request + oneway void send_forty_two (in long forty_two); + + /// A method to test bigger requests + oneway void send_large_octet_array (in Octets payload); + + /// A method to shutdown the ORB + /** + * This method is used to simplify the test shutdown process + */ + oneway void shutdown (); + }; +}; diff --git a/TAO/orbsvcs/tests/Miop/McastLocal/client.cpp b/TAO/orbsvcs/tests/Miop/McastLocal/client.cpp new file mode 100644 index 00000000000..38b253edba4 --- /dev/null +++ b/TAO/orbsvcs/tests/Miop/McastLocal/client.cpp @@ -0,0 +1,92 @@ +// $Id$ + +#include "TestC.h" +#include "ace/Get_Opt.h" +#include "tao/Object_T.h" +#include "orbsvcs/PortableGroup/MIOP.h" + + + +#define MAX_MIOP_OCTET_SEQUENCE (ACE_MAX_DGRAM_SIZE - 272 /* MIOP_MAX_HEADER_SIZE */) + +const ACE_TCHAR *ior = ACE_TEXT("file://test.ior"); + +int +parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("k:")); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'k': + ior = get_opts.opt_arg (); + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-k " + "\n", + argv [0]), + -1); + } + // Indicates successful parsing of the command line + return 0; +} + +int +ACE_TMAIN(int argc, ACE_TCHAR *argv[]) +{ + try + { + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv); + + if (parse_args (argc, argv) != 0) + return 1; + + CORBA::Object_var tmp = + orb->string_to_object(ior); + + /* Do an unchecked narrow since there's no way to do an is_a on + * a multicast reference (yet...). + */ + Test::McastHello_var hello = + TAO::Narrow_Utils::unchecked_narrow ( + tmp.in ()); + + if (CORBA::is_nil (hello.in ())) + { + ACE_ERROR_RETURN ((LM_DEBUG, + "Nil Test::Hello reference <%s>\n", + ior), + 1); + } + + hello->send_forty_two (42); + + Test::Octets payload (MAX_MIOP_OCTET_SEQUENCE); + payload.length (MAX_MIOP_OCTET_SEQUENCE); + + for (CORBA::ULong j = 0; j != MAX_MIOP_OCTET_SEQUENCE; ++j) + { + payload[j] = j % 256; + } + + hello->send_large_octet_array (payload); + + hello->shutdown (); + + orb->destroy (); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Exception caught:"); + return 1; + } + + return 0; +} diff --git a/TAO/orbsvcs/tests/Miop/McastLocal/run_test.pl b/TAO/orbsvcs/tests/Miop/McastLocal/run_test.pl new file mode 100755 index 00000000000..0f377557daa --- /dev/null +++ b/TAO/orbsvcs/tests/Miop/McastLocal/run_test.pl @@ -0,0 +1,126 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::TestTarget; + +$status = 0; +$debug_level = '0'; + +foreach $i (@ARGV) { + if ($i eq '-debug') { + $debug_level = '10'; + } +} + +my $server1 = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n"; +my $server2 = PerlACE::TestTarget::create_target (2) || die "Create target 2 failed\n"; +my $client = PerlACE::TestTarget::create_target (3) || die "Create target 3 failed\n"; + +my $ior1file = "server1.ior"; +my $ior2file = "server2.ior.unused"; + +#Files which used by server1 +my $server1_ior1file = $server1->LocalFile ($ior1file); +$server1->DeleteFile($ior1file); + +#Files which used by server2 +my $server2_ior2file = $server2->LocalFile ($ior2file); +$server2->DeleteFile($ior2file); + +#Files which used by server2 +my $client_ior1file = $client->LocalFile ($ior1file); +$client->DeleteFile($ior1file); + +$SV1 = $server1->CreateProcess ("server", + "-ORBdebuglevel $debug_level " . + "-ORBSvcconf svc_server1.conf " . + "-o $server1_ior1file"); + +$SV2 = $server2->CreateProcess ("server", + "-ORBdebuglevel $debug_level " . + "-ORBSvcconf svc_server2.conf " . + "-ORBPreferredInterfaces *=127.0.0.1 " . + "-o $server2_ior2file"); + +$CL = $client->CreateProcess ("client", + "-ORBSvcconf svc_client.conf " . + "-ORBPreferredInterfaces *=127.0.0.1 " . + "-k file://$ior1file"); + +$server_status = $SV1->Spawn (); + +if ($server_status != 0) { + print STDERR "ERROR: server returned $server_status\n"; + exit 1; +} + +$server_status = $SV2->Spawn (); + +if ($server_status != 0) { + print STDERR "ERROR: server returned $server_status\n"; + exit 1; +} + +sub KillServers{ + $SV1->Kill (); $SV1->TimedWait (1); + $SV2->Kill (); $SV2->TimedWait (1); +} + +if ($server1->WaitForFileTimed ($ior1file, + $server1->ProcessStartWaitInterval()) == -1) { + print STDERR "ERROR: cannot find file <$server1_ior1file>\n"; + KillServers (); + exit 1; +} + +if ($server2->WaitForFileTimed ($ior2file, + $server2->ProcessStartWaitInterval()) == -1) { + print STDERR "ERROR: cannot find file <$server2_ior2file>\n"; + KillServers (); + exit 1; +} + +if ($server1->GetFile ($ior1file) == -1) { + print STDERR "ERROR: cannot retrieve file <$server1_ior1file>\n"; + KillServers (); + exit 1; +} +if ($client->PutFile ($ior1file) == -1) { + print STDERR "ERROR: cannot set file <$client_ior1file>\n"; + KillServers (); + exit 1; +} + + +$client_status = $CL->SpawnWaitKill ($client->ProcessStartWaitInterval() + 285); + +if ($client_status != 0) { + print STDERR "ERROR: client returned $client_status\n"; + $status = 1; +} + +$server_status = $SV1->WaitKill ($server1->ProcessStopWaitInterval()); + +if ($server_status != 0) { + print STDERR "ERROR: server returned $server_status\n"; + $status = 1; +} + +$server_status = $SV2->WaitKill ($server2->ProcessStopWaitInterval()); + +if ($server_status != 0) { + print STDERR "ERROR: server returned $server_status\n"; + $status = 1; +} + + +$server1->DeleteFile($ior1file); +$server2->DeleteFile($ior2file); +$client->DeleteFile($ior1file); + +exit $status; diff --git a/TAO/orbsvcs/tests/Miop/McastLocal/server.cpp b/TAO/orbsvcs/tests/Miop/McastLocal/server.cpp new file mode 100644 index 00000000000..c29b43793c7 --- /dev/null +++ b/TAO/orbsvcs/tests/Miop/McastLocal/server.cpp @@ -0,0 +1,121 @@ +// $Id$ + +#include "McastHello.h" +#include "ace/Get_Opt.h" +#include "ace/OS_NS_stdio.h" +#include "orbsvcs/PortableGroup/MIOP.h" +#include "orbsvcs/PortableGroup/GOA.h" + +static const ACE_TCHAR *ior_output_file = ACE_TEXT("test.ior"); + +// Use a multicast address in the administrative "site local" range, 239.255.0.0 to +// 239.255.255.255. The range 224.255.0.0 to 238.255.255.255 should also be valid +// too. +//static const char *group_ior = "corbaloc:miop:1.0@1.0-TestDomain-1/239.255.0.1:16000"; +static const ACE_TCHAR *group_ior = ACE_TEXT("corbaloc:miop:1.0@1.0-TestDomain-1/224.1.239.2:1234"); + +int +parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("o:")); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'o': + ior_output_file = get_opts.opt_arg (); + break; + + case 'g': + group_ior = get_opts.opt_arg (); + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-o " + "-g " + "\n", + argv [0]), + -1); + } + // Indicates successful parsing of the command line + return 0; +} + +int +ACE_TMAIN(int argc, ACE_TCHAR *argv[]) +{ + try + { + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv); + + CORBA::Object_var poa_object = + orb->resolve_initial_references("RootPOA"); + + PortableGroup::GOA_var root_poa = + PortableGroup::GOA::_narrow (poa_object.in ()); + + if (CORBA::is_nil (root_poa.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Panic: nil RootPOA\n"), + 1); + + PortableServer::POAManager_var poa_manager = + root_poa->the_POAManager (); + + if (parse_args (argc, argv) != 0) + return 1; + + CORBA::Object_var group1 = + orb->string_to_object (group_ior); + + // Output the Group IOR to the + FILE *output_file= ACE_OS::fopen (ior_output_file, "w"); + if (output_file == 0) + ACE_ERROR_RETURN ((LM_ERROR, + "Cannot open output file for writing IOR: %s", + ior_output_file), + 1); + ACE_OS::fprintf (output_file, "%s", ACE_TEXT_ALWAYS_CHAR (group_ior)); + ACE_OS::fclose (output_file); + + PortableServer::ObjectId_var id = + root_poa->create_id_for_reference (group1.in ()); + + // Create and activate an instance of our servant. + McastHello server_impl (orb.in (), 0); + + root_poa->activate_object_with_id (id.in (), + &server_impl); + + + poa_manager->activate (); + + orb->run (); + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) server - event loop finished\n")); + + root_poa->destroy (1, 1); + + orb->destroy (); + + // Validate that our servants got the right requests. + if (server_impl.get_status () == 0) + ACE_ERROR_RETURN ((LM_ERROR, + "Multicast Servant did not receive expected requests!\n"), + 1); + else + ACE_DEBUG ((LM_DEBUG, "(%P|%t) server - Success!\n")); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Exception caught:"); + return 1; + } + + return 0; +} diff --git a/TAO/orbsvcs/tests/Miop/McastLocal/svc_client.conf b/TAO/orbsvcs/tests/Miop/McastLocal/svc_client.conf new file mode 100644 index 00000000000..84ef77cf1c6 --- /dev/null +++ b/TAO/orbsvcs/tests/Miop/McastLocal/svc_client.conf @@ -0,0 +1,6 @@ +# $Id$ + +dynamic UIPMC_Factory Service_Object * TAO_PortableGroup:_make_TAO_UIPMC_Protocol_Factory() "" +static Resource_Factory "-ORBProtocolFactory IIOP_Factory -ORBProtocolFactory UIPMC_Factory" +#static PortableGroup_Loader "" +dynamic PortableGroup_Loader Service_Object * TAO_PortableGroup:_make_TAO_PortableGroup_Loader() "" diff --git a/TAO/orbsvcs/tests/Miop/McastLocal/svc_server1.conf b/TAO/orbsvcs/tests/Miop/McastLocal/svc_server1.conf new file mode 100644 index 00000000000..db74ea90e3f --- /dev/null +++ b/TAO/orbsvcs/tests/Miop/McastLocal/svc_server1.conf @@ -0,0 +1,6 @@ +# $Id$ + +dynamic UIPMC_Factory Service_Object * TAO_PortableGroup:_make_TAO_UIPMC_Protocol_Factory() "-ORBListenerInterfaces *=127.0.0.1" +static Resource_Factory "-ORBProtocolFactory IIOP_Factory -ORBProtocolFactory UIPMC_Factory" +#static PortableGroup_Loader "" +dynamic PortableGroup_Loader Service_Object * TAO_PortableGroup:_make_TAO_PortableGroup_Loader() "" diff --git a/TAO/orbsvcs/tests/Miop/McastLocal/svc_server2.conf b/TAO/orbsvcs/tests/Miop/McastLocal/svc_server2.conf new file mode 100644 index 00000000000..01848bc7c5f --- /dev/null +++ b/TAO/orbsvcs/tests/Miop/McastLocal/svc_server2.conf @@ -0,0 +1,6 @@ +# $Id$ + +dynamic UIPMC_Factory Service_Object * TAO_PortableGroup:_make_TAO_UIPMC_Protocol_Factory() "-ORBListenerInterfaces CopyPreferredInterfaces" +static Resource_Factory "-ORBProtocolFactory IIOP_Factory -ORBProtocolFactory UIPMC_Factory" +#static PortableGroup_Loader "" +dynamic PortableGroup_Loader Service_Object * TAO_PortableGroup:_make_TAO_PortableGroup_Loader() "" diff --git a/TAO/tao/params.cpp b/TAO/tao/params.cpp index bc286c1a0e5..4eaa9a473c9 100644 --- a/TAO/tao/params.cpp +++ b/TAO/tao/params.cpp @@ -217,30 +217,28 @@ TAO_ORB_Parameters::parse_and_add_endpoints (const ACE_CString &endpoints, } bool -TAO_ORB_Parameters::preferred_interfaces (const char *s) +TAO_ORB_Parameters::check_preferred_interfaces_string (const char *s) { // 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) + + for (const char *p = s; *p; ++p) switch (*p) { #if !defined (ACE_HAS_IPV6) - // Can't use this as assignment operator when IPv6 decimal - // addresses may be involved. + // Can't use this as assignment operator when IPv6 decimal + // addresses may be involved. case ':': #endif /* ACE_HAS_IPV6 */ case '=': - if (! expect_assign) + if (!expect_assign) return false; found_remote = true; expect_assign = false; @@ -248,8 +246,9 @@ TAO_ORB_Parameters::preferred_interfaces (const char *s) expect_comma = false; expect_wild = true; break; + case ',': - if (! expect_comma) + if (!expect_comma) return false; found_remote = false; expect_assign = false; @@ -257,32 +256,45 @@ TAO_ORB_Parameters::preferred_interfaces (const char *s) expect_comma = false; expect_wild = true; break; + case '*': case '?': - if (! expect_wild) + if (!expect_wild) return false; - expect_assign = ! found_remote; + expect_assign = !found_remote; expect_char = true; expect_comma = found_remote; expect_wild = false; break; + default: - if (! expect_char) + if (!expect_char) return false; - expect_assign = ! found_remote; + expect_assign = !found_remote; expect_char = true; expect_comma = found_remote; expect_wild = true; break; } - ++p; - } - if (!expect_comma || expect_assign) - return false; - this->pref_network_ = s; + return expect_comma && !expect_assign; +} + +bool +TAO_ORB_Parameters::preferred_interfaces (const char *s) +{ + const bool valid= check_preferred_interfaces_string (s); + if (valid) + { + // Append any valid string to those already specified + // (by other -ORBPreferredInterfaces options that have been + // seen previously) + if (this->pref_network_.length ()) + this->pref_network_+= ','; + this->pref_network_+= s; + } - return true; + return valid; } const char * diff --git a/TAO/tao/params.h b/TAO/tao/params.h index b9c91ebaaa1..ffb2e0fa690 100644 --- a/TAO/tao/params.h +++ b/TAO/tao/params.h @@ -211,10 +211,13 @@ public: void disable_rt_collocation_resolver (bool); /// Accepts the list of preferred interfaces and does a simple - /// semantic check on the string + /// semantic check on the string before setting. Also the getter. bool preferred_interfaces (const char *s); const char *preferred_interfaces (void) const; + /// Utility function called by the preferred interfaces setter + static bool check_preferred_interfaces_string (const char *); + void enforce_pref_interfaces (bool p); bool enforce_pref_interfaces (void) const; -- cgit v1.2.1