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            "$Id: SCIOP_Endpoint.cpp 76932 2007-02-06 16:34:57Z johnnyw $")
00019 
00020 
00021 #if !defined (__ACE_INLINE__)
00022 # include "tao/Strategies/SCIOP_Endpoint.inl"
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_, this->host_.in ()) == -1)
00253     {
00254       // If this call fails, it most likely due a hostname
00255       // lookup failure caused by a DNS misconfiguration.  If
00256       // a request is made to the object at the given host and
00257       // port, then a CORBA::TRANSIENT() exception should be
00258       // thrown.
00259 
00260       // Invalidate the ACE_INET_Addr.  This is used as a flag
00261       // to denote that ACE_INET_Addr initialization failed.
00262       this->object_addr_.set_type (-1);
00263     }
00264   else
00265     {
00266       this->object_addr_set_ = true;
00267     }
00268 }
00269 
00270 CORBA::ULong
00271 TAO_SCIOP_Endpoint::preferred_interfaces (TAO_ORB_Core *oc)
00272 {
00273   ACE_CString tmp (
00274     oc->orb_params ()->preferred_interfaces ());
00275 
00276   ACE_CString::size_type pos = 0;
00277 
00278   pos = tmp.find (this->host_.in ());
00279 
00280   TAO_SCIOP_Endpoint *latest = this;
00281 
00282   CORBA::ULong count = 0;
00283 
00284   while (pos != ACE_CString::npos)
00285     {
00286       // Do we have a "," or an '\0'?
00287       ACE_CString::size_type new_pos = tmp.find (",", pos + 1);
00288 
00289       // Length of the preferred path
00290       ACE_CString::size_type length = 0;
00291 
00292       if (new_pos == ACE_CString::npos)
00293         length = tmp.length () - pos;
00294       else
00295         length = new_pos - pos;
00296 
00297       ACE_CString rem_tmp = tmp.substr (pos, length);
00298 
00299       // Search for the ":"
00300       ACE_CString::size_type col_pos = rem_tmp.find (":");
00301 
00302       if (col_pos == ACE_CString::npos)
00303         {
00304           pos = tmp.find (latest->host_.in (),
00305                           pos + length);
00306           continue;
00307         }
00308 
00309       ACE_CString path = rem_tmp.substr (col_pos + 1);
00310 
00311       latest->preferred_path_.host =
00312         CORBA::string_dup (path.c_str ());
00313 
00314       if (TAO_debug_level > 3)
00315         ACE_DEBUG ((LM_DEBUG,
00316                     "(%P|%t) Adding path [%s] "
00317                     " as preferred path for [%s] \n",
00318                     path.c_str (), this->host_.in ()));
00319 
00320       pos = tmp.find (latest->host_.in (),
00321                       pos + length);
00322 
00323       if (pos != ACE_CString::npos)
00324         {
00325           TAO_Endpoint *tmp_ep =
00326             latest->duplicate ();
00327 
00328           latest->next_ = dynamic_cast<TAO_SCIOP_Endpoint *> (tmp_ep);
00329 
00330           if (latest->next_ == 0) return count;
00331 
00332           latest = latest->next_;
00333           ++count;
00334         }
00335     }
00336 
00337   if (tmp.length () != 0 &&
00338       !oc->orb_params ()->enforce_pref_interfaces ())
00339     {
00340       TAO_Endpoint *tmp_ep = latest->duplicate ();
00341 
00342       latest->next_ =
00343         dynamic_cast<TAO_SCIOP_Endpoint *> (tmp_ep);
00344 
00345       if (latest->next_ == 0) return count;
00346 
00347       latest->next_->preferred_path_.host = (const char *) 0;
00348       ++count;
00349     }
00350 
00351   return count;
00352 }
00353 
00354 bool
00355 TAO_SCIOP_Endpoint::is_preferred_network (void) const
00356 {
00357   return (this->preferred_path_.host.in () != 0);
00358 }
00359 
00360 const char *
00361 TAO_SCIOP_Endpoint::preferred_network (void) const
00362 {
00363   return this->preferred_path_.host.in ();
00364 }
00365 
00366 TAO_END_VERSIONED_NAMESPACE_DECL
00367 
00368 #endif /* TAO_HAS_SCIOP == 1 */

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