DIOP_Connector.cpp

Go to the documentation of this file.
00001 // This may look like C, but it's really -*- C++ -*-
00002 // $Id: DIOP_Connector.cpp 79033 2007-07-26 09:26:46Z vridosh $
00003 
00004 #include "tao/Strategies/DIOP_Connector.h"
00005 
00006 #if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
00007 
00008 #include "ace/Connector.h"
00009 
00010 #include "tao/debug.h"
00011 #include "tao/ORB_Core.h"
00012 #include "tao/SystemException.h"
00013 #include "tao/Base_Transport_Property.h"
00014 #include "tao/Protocols_Hooks.h"
00015 #include "ace/OS_NS_strings.h"
00016 #include "ace/OS_NS_string.h"
00017 #include "tao/Thread_Lane_Resources.h"
00018 #include "ace/os_include/os_netdb.h"
00019 
00020 #include "tao/Strategies/DIOP_Profile.h"
00021 
00022 
00023 ACE_RCSID (Strategies,
00024            DIOP_Connector,
00025            "$Id: DIOP_Connector.cpp 79033 2007-07-26 09:26:46Z vridosh $")
00026 
00027 
00028 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00029 
00030 TAO_DIOP_Connector::TAO_DIOP_Connector (void)
00031   : TAO_Connector (TAO_TAG_DIOP_PROFILE)
00032 {
00033 }
00034 
00035 TAO_DIOP_Connector::~TAO_DIOP_Connector (void)
00036 {
00037 }
00038 
00039 int
00040 TAO_DIOP_Connector::open (TAO_ORB_Core *orb_core)
00041 {
00042   this->orb_core (orb_core);
00043 
00044   // Create our connect strategy
00045   if (this->create_connect_strategy () == -1)
00046     return -1;
00047 
00048   return 0;
00049 }
00050 
00051 int
00052 TAO_DIOP_Connector::close (void)
00053 {
00054   return 0;
00055 }
00056 
00057 int
00058 TAO_DIOP_Connector::set_validate_endpoint (TAO_Endpoint *endpoint)
00059 {
00060   TAO_DIOP_Endpoint *diop_endpoint =
00061     this->remote_endpoint (endpoint);
00062 
00063   if (diop_endpoint == 0)
00064     return -1;
00065 
00066   const ACE_INET_Addr &remote_address =
00067     diop_endpoint->object_addr ();
00068 
00069   // Verify that the remote ACE_INET_Addr was initialized properly.
00070   // Failure can occur if hostname lookup failed when initializing the
00071   // remote ACE_INET_Addr.
00072 #if defined (ACE_HAS_IPV6)
00073    if (remote_address.get_type () != AF_INET &&
00074        remote_address.get_type () != AF_INET6)
00075 #else /* ACE_HAS_IPV6 */
00076   if (remote_address.get_type () != AF_INET)
00077 #endif /* !ACE_HAS_IPV6 */
00078     {
00079       if (TAO_debug_level > 0)
00080         {
00081           ACE_DEBUG ((LM_DEBUG,
00082                       ACE_TEXT ("TAO (%P|%t) - DIOP connection failed.\n")
00083                       ACE_TEXT ("TAO (%P|%t) This is most likely ")
00084                       ACE_TEXT ("due to a hostname lookup ")
00085                       ACE_TEXT ("failure.\n")));
00086         }
00087 
00088       return -1;
00089     }
00090 
00091   return 0;
00092 }
00093 
00094 TAO_Transport *
00095 TAO_DIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *,
00096                                      TAO_Transport_Descriptor_Interface &desc,
00097                                      ACE_Time_Value * /*max_wait_time*/)
00098 {
00099   TAO_DIOP_Endpoint *diop_endpoint =
00100     this->remote_endpoint (desc.endpoint ());
00101 
00102   if (diop_endpoint == 0)
00103     return 0;
00104 
00105   const ACE_INET_Addr &remote_address =
00106     diop_endpoint->object_addr ();
00107 
00108 #if defined (ACE_HAS_IPV6) && !defined (ACE_HAS_IPV6_V6ONLY)
00109   // Check if we need to invalidate accepted connections
00110   // from IPv4 mapped IPv6 addresses
00111   if (this->orb_core ()->orb_params ()->connect_ipv6_only () &&
00112       remote_address.is_ipv4_mapped_ipv6 ())
00113     {
00114       if (TAO_debug_level > 0)
00115         {
00116           ACE_TCHAR remote_as_string[MAXHOSTNAMELEN + 16];
00117 
00118           (void) remote_address.addr_to_string (remote_as_string,
00119                                                 sizeof remote_as_string);
00120 
00121           ACE_ERROR ((LM_ERROR,
00122                       ACE_TEXT ("TAO (%P|%t) - DIOP_Connection_Handler::open, ")
00123                       ACE_TEXT ("invalid connection to IPv4 mapped IPv6 interface <%s>!\n"),
00124                       remote_as_string));
00125         }
00126       return 0;
00127     }
00128 #endif /* ACE_HAS_IPV6 && ACE_HAS_IPV6_V6ONLY */
00129 
00130   TAO_DIOP_Connection_Handler *svc_handler = 0;
00131 
00132   ACE_NEW_RETURN (svc_handler,
00133                   TAO_DIOP_Connection_Handler (this->orb_core ()),
00134                   0);
00135 
00136   u_short port = 0;
00137   const ACE_UINT32 ia_any = INADDR_ANY;
00138   ACE_INET_Addr local_addr (port, ia_any);
00139 
00140 #if defined (ACE_HAS_IPV6)
00141   if (remote_address.get_type () == AF_INET6)
00142     local_addr.set (port,
00143                     ACE_IPV6_ANY);
00144 #endif /* ACE_HAS_IPV6 */
00145 
00146   svc_handler->local_addr (local_addr);
00147   svc_handler->addr (remote_address);
00148 
00149   int retval = svc_handler->open (0);
00150 
00151   // Failure to open a connection.
00152   if (retval != 0)
00153     {
00154       // Close the handler (this will also delete svc_handler).
00155       svc_handler->close ();
00156 
00157       if (TAO_debug_level > 0)
00158         {
00159           ACE_ERROR ((LM_ERROR,
00160                       ACE_TEXT ("TAO (%P|%t) - DIOP_Connector::make_connection, ")
00161                       ACE_TEXT ("could not make a new connection\n")));
00162         }
00163 
00164       return 0;
00165     }
00166 
00167   if (TAO_debug_level > 2)
00168     ACE_DEBUG ((LM_DEBUG,
00169                 ACE_TEXT ("TAO (%P|%t) - DIOP_Connector::connect, ")
00170                 ACE_TEXT ("new connection on HANDLE %d\n"),
00171                 svc_handler->peer ().get_handle ()));
00172 
00173   TAO_DIOP_Transport *transport =
00174     dynamic_cast <TAO_DIOP_Transport *> (svc_handler->transport ());
00175 
00176   // In case of errors transport is zero
00177   if (transport == 0)
00178     {
00179       // Close the handler (this will also delete svc_handler).
00180       svc_handler->close ();
00181 
00182       // Give users a clue to the problem.
00183       if (TAO_debug_level > 3)
00184         ACE_DEBUG ((LM_ERROR,
00185                     ACE_TEXT ("TAO (%P|%t) - DIOP_Connector::make_connection, ")
00186                     ACE_TEXT ("connection to <%s:%u> failed (%p)\n"),
00187                     ACE_TEXT_CHAR_TO_TCHAR (diop_endpoint->host ()),
00188                     diop_endpoint->port (),
00189                     ACE_TEXT ("errno")));
00190 
00191       return 0;
00192     }
00193 
00194   // Add the handler to Cache
00195   retval =
00196     this->orb_core ()->lane_resources ().transport_cache ().cache_transport (&desc,
00197                                                                              transport);
00198 
00199   // Failure in adding to cache.
00200   if (retval != 0)
00201     {
00202       // Close the handler (this will also delete svc_handler).
00203       svc_handler->close ();
00204 
00205       if (TAO_debug_level > 0)
00206         {
00207           ACE_ERROR ((LM_ERROR,
00208                       ACE_TEXT ("TAO (%P|%t) - DIOP_Connector::make_connection, ")
00209                       ACE_TEXT ("could not add the new connection to cache\n")));
00210         }
00211 
00212       return 0;
00213     }
00214 
00215   return transport;
00216 }
00217 
00218 TAO_Profile *
00219 TAO_DIOP_Connector::create_profile (TAO_InputCDR& cdr)
00220 {
00221   TAO_Profile *pfile = 0;
00222   ACE_NEW_RETURN (pfile,
00223                   TAO_DIOP_Profile (this->orb_core ()),
00224                   0);
00225 
00226   if (pfile->decode (cdr) == -1)
00227     {
00228       pfile->_decr_refcnt ();
00229       pfile = 0;
00230     }
00231 
00232   return pfile;
00233 }
00234 
00235 TAO_Profile *
00236 TAO_DIOP_Connector::make_profile (void)
00237 {
00238   // The endpoint should be of the form:
00239   //    N.n@host:port/object_key
00240   // or:
00241   //    host:port/object_key
00242 
00243   TAO_Profile *profile = 0;
00244   ACE_NEW_THROW_EX (profile,
00245                     TAO_DIOP_Profile (this->orb_core ()),
00246                     CORBA::NO_MEMORY (
00247                       CORBA::SystemException::_tao_minor_code (
00248                         TAO::VMCID,
00249                         ENOMEM),
00250                       CORBA::COMPLETED_NO));
00251 
00252   return profile;
00253 }
00254 
00255 int
00256 TAO_DIOP_Connector::check_prefix (const char *endpoint)
00257 {
00258   // Check for a valid string
00259   if (!endpoint || !*endpoint)
00260     return -1;  // Failure
00261 
00262   const char *protocol[] = { "diop", "dioploc" };
00263 
00264   size_t const slot = ACE_OS::strchr (endpoint, ':') - endpoint;
00265 
00266   size_t const len0 = ACE_OS::strlen (protocol[0]);
00267   size_t const len1 = ACE_OS::strlen (protocol[1]);
00268 
00269   // Check for the proper prefix in the IOR.  If the proper prefix
00270   // isn't in the IOR then it is not an IOR we can use.
00271   if (slot == len0
00272       && ACE_OS::strncasecmp (endpoint, protocol[0], len0) == 0)
00273     return 0;
00274   else if (slot == len1
00275            && ACE_OS::strncasecmp (endpoint, protocol[1], len1) == 0)
00276     return 0;
00277 
00278   return -1;
00279   // Failure: not an DIOP IOR
00280   // DO NOT throw an exception here.
00281 }
00282 
00283 char
00284 TAO_DIOP_Connector::object_key_delimiter (void) const
00285 {
00286   return TAO_DIOP_Profile::object_key_delimiter_;
00287 }
00288 
00289 TAO_DIOP_Endpoint *
00290 TAO_DIOP_Connector::remote_endpoint (TAO_Endpoint *endpoint)
00291 {
00292   if (endpoint->tag () != TAO_TAG_DIOP_PROFILE)
00293     return 0;
00294 
00295   return dynamic_cast<TAO_DIOP_Endpoint *> (endpoint);
00296 }
00297 
00298 int
00299 TAO_DIOP_Connector::cancel_svc_handler (
00300   TAO_Connection_Handler * /* svc_handler */)
00301 {
00302   return 0;
00303 }
00304 
00305 TAO_END_VERSIONED_NAMESPACE_DECL
00306 
00307 #endif /* TAO_HAS_DIOP && TAO_HAS_DIOP != 0 */

Generated on Tue Feb 2 17:47:18 2010 for TAO_Strategies by  doxygen 1.4.7