DIOP_Endpoint.cpp

Go to the documentation of this file.
00001 // This may look like C, but it's really -*- C++ -*-
00002 // $Id: DIOP_Endpoint.cpp 78851 2007-07-12 12:06:21Z vridosh $
00003 
00004 
00005 #include "tao/Strategies/DIOP_Endpoint.h"
00006 
00007 #if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
00008 
00009 #include "tao/Strategies/DIOP_Connection_Handler.h"
00010 #include "tao/debug.h"
00011 #include "tao/ORB_Constants.h"
00012 
00013 #include "ace/OS_NS_stdio.h"
00014 #include "ace/OS_NS_string.h"
00015 
00016 
00017 ACE_RCSID (Strategies,
00018            DIOP_Endpoint,
00019            "$Id: DIOP_Endpoint.cpp 78851 2007-07-12 12:06:21Z vridosh $")
00020 
00021 
00022 #if !defined (__ACE_INLINE__)
00023 # include "tao/Strategies/DIOP_Endpoint.inl"
00024 #endif /* __ACE_INLINE__ */
00025 
00026 #include "ace/os_include/os_netdb.h"
00027 
00028 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00029 
00030 TAO_DIOP_Endpoint::TAO_DIOP_Endpoint (const ACE_INET_Addr &addr,
00031                                       int use_dotted_decimal_addresses)
00032 
00033   : TAO_Endpoint (TAO_TAG_DIOP_PROFILE)
00034     , host_ ()
00035     , port_ (0)
00036 #if defined (ACE_HAS_IPV6)
00037     , is_ipv6_decimal_ (false)
00038 #endif /* ACE_HAS_IPV6 */
00039     , object_addr_ (addr)
00040     , object_addr_set_ (false)
00041     , next_ (0)
00042 {
00043   this->set (addr, use_dotted_decimal_addresses);
00044 }
00045 
00046 TAO_DIOP_Endpoint::TAO_DIOP_Endpoint (const char *host,
00047                                       CORBA::UShort port,
00048                                       const ACE_INET_Addr &addr,
00049                                       CORBA::Short priority)
00050   : TAO_Endpoint (TAO_TAG_DIOP_PROFILE,
00051                   priority)
00052     , host_ ()
00053     , port_ (port)
00054 #if defined (ACE_HAS_IPV6)
00055     , is_ipv6_decimal_ (false)
00056 #endif /* ACE_HAS_IPV6 */
00057     , object_addr_ (addr)
00058     , object_addr_set_ (false)
00059     , next_ (0)
00060 {
00061   this->host (host); // With IPv6 performs check for decimal address
00062 }
00063 
00064 TAO_DIOP_Endpoint::TAO_DIOP_Endpoint (void)
00065   : TAO_Endpoint (TAO_TAG_DIOP_PROFILE),
00066     host_ (),
00067     port_ (0),
00068 #if defined (ACE_HAS_IPV6)
00069     is_ipv6_decimal_ (false),
00070 #endif /* ACE_HAS_IPV6 */
00071     object_addr_ (),
00072     object_addr_set_ (false),
00073     next_ (0)
00074 {
00075 }
00076 
00077 TAO_DIOP_Endpoint::TAO_DIOP_Endpoint (const char *host,
00078                                       CORBA::UShort port,
00079                                       CORBA::Short priority)
00080   : TAO_Endpoint (TAO_TAG_DIOP_PROFILE, priority),
00081     host_ (),
00082     port_ (port),
00083 #if defined (ACE_HAS_IPV6)
00084     is_ipv6_decimal_ (false),
00085 #endif /* ACE_HAS_IPV6 */
00086     object_addr_ (),
00087     object_addr_set_ (false),
00088     next_ (0)
00089 {
00090   this->host (host); // With IPv6 performs check for decimal address
00091 }
00092 
00093 TAO_DIOP_Endpoint::~TAO_DIOP_Endpoint (void)
00094 {
00095 }
00096 
00097 int
00098 TAO_DIOP_Endpoint::set (const ACE_INET_Addr &addr,
00099                         int use_dotted_decimal_addresses)
00100 {
00101   char tmp_host[MAXHOSTNAMELEN + 1];
00102 
00103 #if defined (ACE_HAS_IPV6)
00104   this->is_ipv6_decimal_ = false; // Reset
00105 #endif /* ACE_HAS_IPV6 */
00106 
00107   if (use_dotted_decimal_addresses
00108       || addr.get_host_name (tmp_host, sizeof (tmp_host)) != 0)
00109     {
00110       if (use_dotted_decimal_addresses == 0 && TAO_debug_level > 5)
00111         {
00112           ACE_DEBUG ((LM_DEBUG,
00113                       ACE_TEXT ("TAO (%P|%t) - DIOP_Endpoint::set, ")
00114                       ACE_TEXT ("%p\n"),
00115                       ACE_TEXT ("cannot determine hostname")));
00116         }
00117 
00118       const char *tmp = addr.get_host_addr ();
00119       if (tmp == 0)
00120         {
00121           if (TAO_debug_level > 0)
00122             ACE_DEBUG ((LM_DEBUG,
00123                         ACE_TEXT ("TAO (%P|%t) - ")
00124                         ACE_TEXT ("DIOP_Endpoint::set, ")
00125                         ACE_TEXT ("%p\n"),
00126                         ACE_TEXT ("cannot determine hostname\n")));
00127           return -1;
00128         }
00129       else
00130         {
00131           this->host_ = tmp;
00132 #if defined (ACE_HAS_IPV6)
00133           if (addr.get_type () == PF_INET6)
00134             this->is_ipv6_decimal_ = true;
00135 #endif /* ACE_HAS_IPV6 */
00136         }
00137     }
00138   else
00139     this->host_ = CORBA::string_dup (tmp_host);
00140 
00141   this->port_ = addr.get_port_number ();
00142 
00143   return 0;
00144 }
00145 
00146 int
00147 TAO_DIOP_Endpoint::addr_to_string (char *buffer, size_t length)
00148 {
00149   size_t actual_len =
00150     ACE_OS::strlen (this->host_.in ()) // chars in host name
00151     + sizeof (':')                     // delimiter
00152     + ACE_OS::strlen ("65536")         // max port
00153     + sizeof ('\0');
00154 
00155 #if defined (ACE_HAS_IPV6)
00156   if (this->is_ipv6_decimal_)
00157     actual_len += 2; // '[' + ']'
00158 #endif /* ACE_HAS_IPV6 */
00159 
00160   if (length < actual_len)
00161     return -1;
00162 
00163 #if defined (ACE_HAS_IPV6)
00164   if (this->is_ipv6_decimal_)
00165     ACE_OS::sprintf (buffer, "[%s]:%d",
00166                      this->host_.in (), this->port_);
00167   else
00168 #endif /* ACE_HAS_IPV6 */
00169   ACE_OS::sprintf (buffer, "%s:%d",
00170                    this->host_.in (), this->port_);
00171 
00172   return 0;
00173 }
00174 
00175 const char *
00176 TAO_DIOP_Endpoint::host (const char *h)
00177 {
00178   this->host_ = h;
00179 #if defined (ACE_HAS_IPV6)
00180   if (ACE_OS::strchr (h, ':') != 0)
00181     this->is_ipv6_decimal_ = true;
00182 #endif /* ACE_HAS_IPV6 */
00183 
00184   return this->host_.in ();
00185 }
00186 
00187 TAO_Endpoint *
00188 TAO_DIOP_Endpoint::next (void)
00189 {
00190   return this->next_;
00191 }
00192 
00193 TAO_Endpoint *
00194 TAO_DIOP_Endpoint::duplicate (void)
00195 {
00196   TAO_DIOP_Endpoint *endpoint = 0;
00197 
00198   ACE_NEW_RETURN (endpoint,
00199                   TAO_DIOP_Endpoint (this->host_.in (),
00200                                      this->port_,
00201                                      this->object_addr_,
00202                                      this->priority ()),
00203                   0);
00204 
00205   return endpoint;
00206 }
00207 
00208 CORBA::Boolean
00209 TAO_DIOP_Endpoint::is_equivalent (const TAO_Endpoint *other_endpoint)
00210 {
00211   TAO_Endpoint *endpt = const_cast<TAO_Endpoint *> (other_endpoint);
00212 
00213   TAO_DIOP_Endpoint *endpoint = dynamic_cast<TAO_DIOP_Endpoint *> (endpt);
00214   if (endpoint == 0)
00215     return 0;
00216 
00217   return (this->port () == endpoint->port ()
00218           && ACE_OS::strcmp (this->host (), endpoint->host ()) == 0);
00219 }
00220 
00221 CORBA::ULong
00222 TAO_DIOP_Endpoint::hash (void)
00223 {
00224   if (this->hash_val_ != 0)
00225     return this->hash_val_;
00226 
00227   {
00228     ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00229                       guard,
00230                       this->addr_lookup_lock_,
00231                       this->hash_val_);
00232     // .. DCL
00233     if (this->hash_val_ != 0)
00234       return this->hash_val_;
00235 
00236     this->hash_val_ =
00237       ACE::hash_pjw (this->host ()) + this->port ();
00238   }
00239 
00240   return this->hash_val_;
00241 }
00242 
00243 const ACE_INET_Addr &
00244 TAO_DIOP_Endpoint::object_addr (void) const
00245 {
00246   // The object_addr_ is initialized here, rather than at IOR decode
00247   // time for several reasons:
00248   //   1. A request on the object may never be invoked.
00249   //   2. The DNS setup may have changed dynamically.
00250   //   ...etc..
00251 
00252   // Double checked locking optimization.
00253   if (!this->object_addr_set_)
00254     {
00255       ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00256                         guard,
00257                         this->addr_lookup_lock_,
00258                         this->object_addr_ );
00259 
00260       if (!this->object_addr_set_)
00261         {
00262           (void) this->object_addr_i ();
00263         }
00264     }
00265   return this->object_addr_;
00266 }
00267 
00268 void
00269 TAO_DIOP_Endpoint::object_addr_i (void) const
00270 {
00271   // We should have already held the lock
00272 
00273 #if defined (ACE_HAS_IPV6)
00274   bool is_ipv4_decimal_ = false;
00275   if (!this->is_ipv6_decimal_)
00276     is_ipv4_decimal_ =
00277       ACE_OS::strspn (this->host_.in (), ".0123456789") ==
00278       ACE_OS::strlen (this->host_.in ());
00279 
00280   // If this is *not* an IPv4 decimal address at first try to
00281   // resolve the address as an IPv6 address; if that fails
00282   // (or it's an IPv4 address) and the address is *not* an IPv6
00283   // decimal address try to resolve it as an IPv4 address.
00284   if ((is_ipv4_decimal_ ||
00285         this->object_addr_.set (this->port_,
00286                                 this->host_.in (),
00287                                 1,
00288                                 AF_INET6) == -1) &&
00289       (this->is_ipv6_decimal_ ||
00290         this->object_addr_.set (this->port_,
00291                               this->host_.in (),
00292                               1,
00293                               AF_INET) == -1))
00294 #else
00295   if (this->object_addr_.set (this->port_,
00296                               this->host_.in ()) == -1)
00297 #endif /* ACE_HAS_IPV6 */
00298     {
00299       // If this call fails, it most likely due a hostname
00300       // lookup failure caused by a DNS misconfiguration.  If
00301       // a request is made to the object at the given host and
00302       // port, then a CORBA::TRANSIENT() exception should be
00303       // thrown.
00304 
00305       // Invalidate the ACE_INET_Addr.  This is used as a flag
00306       // to denote that ACE_INET_Addr initialization failed.
00307       this->object_addr_.set_type (-1);
00308     }
00309   else
00310     {
00311       this->object_addr_set_ = true;
00312     }
00313 }
00314 
00315 TAO_END_VERSIONED_NAMESPACE_DECL
00316 
00317 #endif /* TAO_HAS_DIOP && TAO_HAS_DIOP != 0 */

Generated on Sun Jan 27 15:59:47 2008 for TAO_Strategies by doxygen 1.3.6