SCIOP_Endpoint.cpp

Go to the documentation of this file.
00001 #include "tao/Strategies/SCIOP_Endpoint.h"
00002 
00003 #if TAO_HAS_SCIOP == 1
00004 
00005 #include "tao/ORB_Constants.h"
00006 #include "tao/debug.h"
00007 
00008 #include "ace/Synch_Traits.h"
00009 #include "ace/Thread_Mutex.h"
00010 #include "ace/OS_NS_string.h"
00011 #include "ace/Log_Msg.h"
00012 #include "ace/Synch.h"
00013 #include "ace/OS_NS_stdio.h"
00014 #include "tao/ORB_Core.h"
00015 
00016 ACE_RCSID (Strategies,
00017            SCIOP_Endpoint,
00018            "SCIOP_Endpoint.cpp,v 1.19 2006/03/10 07:19:18 jtc Exp")
00019 
00020 
00021 #if !defined (__ACE_INLINE__)
00022 # include "tao/Strategies/SCIOP_Endpoint.i"
00023 #endif /* __ACE_INLINE__ */
00024 
00025 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00026 
00027 TAO_SCIOP_Endpoint::TAO_SCIOP_Endpoint (const ACE_INET_Addr &addr,
00028                                       int use_dotted_decimal_addresses)
00029   : TAO_Endpoint (TAO_TAG_SCIOP_PROFILE)
00030   , host_ ()
00031   , port_ (683)  // default port (IANA assigned)
00032   , object_addr_ (addr)
00033   , object_addr_set_ (0)
00034   , preferred_path_ ()
00035   , is_encodable_ (true)
00036   , next_ (0)
00037 {
00038   this->set (addr, use_dotted_decimal_addresses);
00039 }
00040 
00041 TAO_SCIOP_Endpoint::TAO_SCIOP_Endpoint (const char *host,
00042                                         CORBA::UShort port,
00043                                         const ACE_INET_Addr &addr,
00044                                         CORBA::Short priority)
00045   : TAO_Endpoint (TAO_TAG_SCIOP_PROFILE,
00046                   priority)
00047   , host_ (host)
00048   , port_ (port)
00049   , object_addr_ (addr)
00050   , object_addr_set_ (0)
00051   , preferred_path_ ()
00052   , is_encodable_ (true)
00053   , next_ (0)
00054 {
00055 }
00056 
00057 TAO_SCIOP_Endpoint::TAO_SCIOP_Endpoint (void)
00058   : TAO_Endpoint (TAO_TAG_SCIOP_PROFILE)
00059   , host_ ()
00060   , port_ (683)  // default port (IANA assigned)
00061   , object_addr_ ()
00062   , object_addr_set_ (0)
00063   , preferred_path_ ()
00064   , is_encodable_ (true)
00065   , next_ (0)
00066 {
00067 }
00068 
00069 TAO_SCIOP_Endpoint::TAO_SCIOP_Endpoint (const char *host,
00070                                         CORBA::UShort port,
00071                                         CORBA::Short priority)
00072   : TAO_Endpoint (TAO_TAG_SCIOP_PROFILE)
00073   , host_ (host)
00074   , port_ (port)
00075   , object_addr_ ()
00076   , object_addr_set_ (0)
00077   , preferred_path_ ()
00078   , is_encodable_ (true)
00079   , next_ (0)
00080 {
00081   this->priority (priority);
00082 }
00083 
00084 TAO_SCIOP_Endpoint::~TAO_SCIOP_Endpoint (void)
00085 {
00086 }
00087 
00088 TAO_SCIOP_Endpoint::TAO_SCIOP_Endpoint (const TAO_SCIOP_Endpoint &rhs)
00089   : TAO_Endpoint (rhs.tag_,
00090                   rhs.priority_)
00091   , host_ (rhs.host_)
00092   , port_ (rhs.port_)
00093   , object_addr_ (rhs.object_addr_)
00094   , object_addr_set_ (rhs.object_addr_set_)
00095   , preferred_path_  (rhs.preferred_path_)
00096   , is_encodable_ (rhs.is_encodable_)
00097   , next_ (0)
00098 {
00099 }
00100 
00101 int
00102 TAO_SCIOP_Endpoint::set (const ACE_INET_Addr &addr,
00103                         int use_dotted_decimal_addresses)
00104 {
00105   char tmp_host[MAXHOSTNAMELEN + 1];
00106 
00107   if (use_dotted_decimal_addresses
00108       || addr.get_host_name (tmp_host, sizeof (tmp_host)) != 0)
00109     {
00110       const char *tmp = addr.get_host_addr ();
00111       if (tmp == 0)
00112         {
00113           if (TAO_debug_level > 0)
00114             ACE_DEBUG ((LM_DEBUG,
00115                         ACE_TEXT ("\n\nTAO (%P|%t) ")
00116                         ACE_TEXT ("SCIOP_Endpoint::set ")
00117                         ACE_TEXT ("- %p\n\n"),
00118                         ACE_TEXT ("cannot determine hostname")));
00119           return -1;
00120         }
00121       else
00122         this->host_ = tmp;
00123     }
00124   else
00125     this->host_ = CORBA::string_dup (tmp_host);
00126 
00127   this->port_ = addr.get_port_number();
00128 
00129   return 0;
00130 }
00131 
00132 int
00133 TAO_SCIOP_Endpoint::addr_to_string (char *buffer, size_t length)
00134 {
00135   size_t actual_len =
00136     ACE_OS::strlen (this->host_.in ()) // chars in host name
00137     + sizeof (':')                     // delimiter
00138     + ACE_OS::strlen ("65536")         // max port
00139     + sizeof ('\0');
00140 
00141   if (length < actual_len)
00142     return -1;
00143 
00144   ACE_OS::sprintf (buffer, "%s:%d",
00145                    this->host_.in (), this->port_);
00146 
00147   return 0;
00148 }
00149 
00150 const char *
00151 TAO_SCIOP_Endpoint::host (const char *h)
00152 {
00153   this->host_ = h;
00154 
00155   return this->host_.in ();
00156 }
00157 
00158 TAO_Endpoint *
00159 TAO_SCIOP_Endpoint::next (void)
00160 {
00161   return this->next_;
00162 }
00163 
00164 TAO_Endpoint *
00165 TAO_SCIOP_Endpoint::duplicate (void)
00166 {
00167   TAO_SCIOP_Endpoint *endpoint = 0;
00168 
00169   // @@NOTE: Not at all exception safe
00170   ACE_NEW_RETURN (endpoint,
00171                   TAO_SCIOP_Endpoint (*this),
00172                   0);
00173 
00174   return endpoint;
00175 }
00176 
00177 CORBA::Boolean
00178 TAO_SCIOP_Endpoint::is_equivalent (const TAO_Endpoint *other_endpoint)
00179 {
00180   TAO_Endpoint *endpt =
00181     const_cast<TAO_Endpoint *> (other_endpoint);
00182 
00183   TAO_SCIOP_Endpoint *endpoint =
00184     dynamic_cast<TAO_SCIOP_Endpoint *> (endpt);
00185   if (endpoint == 0)
00186     return 0;
00187 
00188   return (this->port_ == endpoint->port_
00189           && (ACE_OS::strcmp(this->host(), endpoint->host()) == 0));
00190 }
00191 
00192 CORBA::ULong
00193 TAO_SCIOP_Endpoint::hash (void)
00194 {
00195   if (this->hash_val_ != 0)
00196     return this->hash_val_;
00197 
00198   {
00199     ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00200                       guard,
00201                       this->addr_lookup_lock_,
00202                       this->hash_val_);
00203     // .. DCL
00204     if (this->hash_val_ != 0)
00205       return this->hash_val_;
00206 
00207     // A few comments about this optimization. The call below will
00208     // deadlock if the object_addr_set is false. If you don't belive
00209 
00210     if (!this->object_addr_set_)
00211       {
00212         // Set the object_addr first
00213         (void) this->object_addr_i ();
00214       }
00215 
00216     this->hash_val_ =
00217       this->object_addr_.get_ip_address () + this->port ();
00218   }
00219 
00220   return this->hash_val_;
00221 }
00222 
00223 const ACE_INET_Addr &
00224 TAO_SCIOP_Endpoint::object_addr (void) const
00225 {
00226   // The object_addr_ is initialized here, rather than at IOR decode
00227   // time for several reasons:
00228   //   1. A request on the object may never be invoked.
00229   //   2. The DNS setup may have changed dynamically.
00230   //   ...etc..
00231 
00232   // Double checked locking optimization.
00233   if (!this->object_addr_set_)
00234     {
00235       ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00236                         guard,
00237                         this->addr_lookup_lock_,
00238                         this->object_addr_);
00239 
00240       if (!this->object_addr_set_)
00241         {
00242           (void) this->object_addr_i ();
00243         }
00244     }
00245 
00246   return this->object_addr_;
00247 }
00248 
00249 void
00250 TAO_SCIOP_Endpoint::object_addr_i (void) const
00251 {
00252   if (this->object_addr_.set (this->port_,
00253                               this->host_.in ()) == -1)
00254     {
00255       // If this call fails, it most likely due a hostname
00256       // lookup failure caused by a DNS misconfiguration.  If
00257       // a request is made to the object at the given host and
00258       // port, then a CORBA::TRANSIENT() exception should be
00259       // thrown.
00260 
00261       // Invalidate the ACE_INET_Addr.  This is used as a flag
00262       // to denote that ACE_INET_Addr initialization failed.
00263       this->object_addr_.set_type (-1);
00264     }
00265   else
00266     {
00267       this->object_addr_set_ = true;
00268     }
00269 }
00270 
00271 CORBA::ULong
00272 TAO_SCIOP_Endpoint::preferred_interfaces (TAO_ORB_Core *oc)
00273 {
00274   ACE_CString tmp (
00275     oc->orb_params ()->preferred_interfaces ());
00276 
00277   ssize_t pos = 0;
00278 
00279   pos = tmp.find (this->host_.in ());
00280 
00281   TAO_SCIOP_Endpoint *latest = this;
00282 
00283   CORBA::ULong count = 0;
00284 
00285   while (pos != ACE_CString::npos)
00286     {
00287       // Do we have a "," or an '\0'?
00288       ssize_t new_pos = tmp.find (",",
00289                                   pos + 1);
00290 
00291       // Length of the preferred path
00292       int length = 0;
00293 
00294       if (new_pos == ACE_CString::npos)
00295         length = tmp.length () - pos;
00296       else
00297         length = new_pos - pos;
00298 
00299       ACE_CString rem_tmp = tmp.substr (pos, length);
00300 
00301       // Search for the ":"
00302       ssize_t col_pos = rem_tmp.find (":");
00303 
00304       if (col_pos == ACE_CString::npos)
00305         {
00306           pos = tmp.find (latest->host_.in (),
00307                           pos + length);
00308           continue;
00309         }
00310 
00311       ACE_CString path = rem_tmp.substr (col_pos + 1);
00312 
00313       latest->preferred_path_.host =
00314         CORBA::string_dup (path.c_str ());
00315 
00316       if (TAO_debug_level > 3)
00317         ACE_DEBUG ((LM_DEBUG,
00318                     "(%P|%t) Adding path [%s] "
00319                     " as preferred path for [%s] \n",
00320                     path.c_str (), this->host_.in ()));
00321 
00322       pos = tmp.find (latest->host_.in (),
00323                       pos + length);
00324 
00325       if (pos != ACE_CString::npos)
00326         {
00327           TAO_Endpoint *tmp_ep =
00328             latest->duplicate ();
00329 
00330           latest->next_ = dynamic_cast<TAO_SCIOP_Endpoint *> (tmp_ep);
00331 
00332           if (latest->next_ == 0) return count;
00333 
00334           latest = latest->next_;
00335           ++count;
00336         }
00337     }
00338 
00339   if (tmp.length () != 0 &&
00340       !oc->orb_params ()->enforce_pref_interfaces ())
00341     {
00342       TAO_Endpoint *tmp_ep = latest->duplicate ();
00343 
00344       latest->next_ =
00345         dynamic_cast<TAO_SCIOP_Endpoint *> (tmp_ep);
00346 
00347       if (latest->next_ == 0) return count;
00348 
00349       latest->next_->preferred_path_.host = (const char *) 0;
00350       ++count;
00351     }
00352 
00353   return count;
00354 }
00355 
00356 bool
00357 TAO_SCIOP_Endpoint::is_preferred_network (void) const
00358 {
00359   return (this->preferred_path_.host.in () != 0);
00360 }
00361 
00362 const char *
00363 TAO_SCIOP_Endpoint::preferred_network (void) const
00364 {
00365   return this->preferred_path_.host.in ();
00366 }
00367 
00368 TAO_END_VERSIONED_NAMESPACE_DECL
00369 
00370 #endif /* TAO_HAS_SCIOP == 1 */

Generated on Thu Nov 9 13:39:29 2006 for TAO_Strategies by doxygen 1.3.6