summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Mcast_Connection_Handler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Mcast_Connection_Handler.cpp')
-rw-r--r--TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Mcast_Connection_Handler.cpp186
1 files changed, 132 insertions, 54 deletions
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<ACE_CString> 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<TAO_MIOP_Resource_Factory>::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