TAO_IIOP_Profile Class Reference

This class defines the protocol specific attributes required for locating ORBs over a TCP/IP network. More...

#include <IIOP_Profile.h>

Inheritance diagram for TAO_IIOP_Profile:

Inheritance graph
[legend]
Collaboration diagram for TAO_IIOP_Profile:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 TAO_IIOP_Profile (const ACE_INET_Addr &addr, const TAO::ObjectKey &object_key, const TAO_GIOP_Message_Version &version, TAO_ORB_Core *orb_core)
 TAO_IIOP_Profile (const char *host, CORBA::UShort port, const TAO::ObjectKey &object_key, const ACE_INET_Addr &addr, const TAO_GIOP_Message_Version &version, TAO_ORB_Core *orb_core)
 TAO_IIOP_Profile (TAO_ORB_Core *orb_core)
 Profile constructor, default.

void add_endpoint (TAO_IIOP_Endpoint *endp)
void remove_endpoint (TAO_IIOP_Endpoint *endp)
virtual void remove_generic_endpoint (TAO_Endpoint *ep)
virtual void add_generic_endpoint (TAO_Endpoint *ep)
 Add an endpoint when the specific endpoint type is unknown.

virtual char object_key_delimiter (void) const
 The object key delimiter that IIOP uses or expects.

virtual char * to_string ()
 Template methods. Please see Profile.h for documentation.

virtual int encode_endpoints (void)
virtual int encode_alternate_endpoints (void)
virtual TAO_Endpointendpoint (void)
virtual CORBA::ULong endpoint_count (void) const
 Return how many endpoints this profile contains.

virtual CORBA::ULong hash (CORBA::ULong max)
 Return a hash value for this object.


Static Public Member Functions

const char * prefix (void)
 Return the char string prefix.


Static Public Attributes

const char object_key_delimiter_ = '/'

Protected Member Functions

 ~TAO_IIOP_Profile (void)
 Destructor is to be called only through .

int encode_endpoints_for_rt (void)
virtual int decode_profile (TAO_InputCDR &cdr)
 Template methods. Please see Profile.h for the documentation.

virtual int decode_endpoints (void)
virtual void parse_string_i (const char *string)
 Protocol specific implementation of parse_string ().

virtual void create_profile_body (TAO_OutputCDR &cdr) const
 Creates an encapsulation of the ProfileBody struct in the cdr.

virtual CORBA::Boolean do_is_equivalent (const TAO_Profile *other_profile)
 Profile equivalence template method invoked on subclasses.


Protected Attributes

TAO_IIOP_Endpoint endpoint_
CORBA::ULong count_
 Number of endpoints in the list headed by .


Detailed Description

This class defines the protocol specific attributes required for locating ORBs over a TCP/IP network.

This class defines the IIOP profile as specified in the CORBA specification.

Definition at line 44 of file IIOP_Profile.h.


Constructor & Destructor Documentation

TAO_IIOP_Profile::TAO_IIOP_Profile const ACE_INET_Addr addr,
const TAO::ObjectKey object_key,
const TAO_GIOP_Message_Version version,
TAO_ORB_Core orb_core
 

Profile constructor, same as above except the object_key has already been marshaled.

Definition at line 52 of file IIOP_Profile.cpp.

00056   : TAO_Profile (IOP::TAG_INTERNET_IOP,
00057                  orb_core,
00058                  object_key,
00059                  version),
00060     endpoint_ (addr,
00061                orb_core->orb_params ()->use_dotted_decimal_addresses ()),
00062     count_ (1)
00063 {
00064 }

TAO_IIOP_Profile::TAO_IIOP_Profile const char *  host,
CORBA::UShort  port,
const TAO::ObjectKey object_key,
const ACE_INET_Addr addr,
const TAO_GIOP_Message_Version version,
TAO_ORB_Core orb_core
 

Profile constructor, this is the most efficient since it doesn't require any address resolution processing.

Definition at line 66 of file IIOP_Profile.cpp.

00072   : TAO_Profile (IOP::TAG_INTERNET_IOP,
00073                  orb_core,
00074                  object_key,
00075                  version),
00076     endpoint_ (host, port, addr),
00077     count_ (1)
00078 {
00079 }

TAO_IIOP_Profile::TAO_IIOP_Profile TAO_ORB_Core orb_core  ) 
 

Profile constructor, default.

Definition at line 81 of file IIOP_Profile.cpp.

References TAO_DEF_GIOP_MAJOR, and TAO_DEF_GIOP_MINOR.

00082   : TAO_Profile (IOP::TAG_INTERNET_IOP,
00083                  orb_core,
00084                  TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR,
00085                                            TAO_DEF_GIOP_MINOR)),
00086     endpoint_ (),
00087     count_ (1)
00088 {
00089 }

TAO_BEGIN_VERSIONED_NAMESPACE_DECL TAO_IIOP_Profile::~TAO_IIOP_Profile void   )  [protected]
 

Destructor is to be called only through .

Definition at line 25 of file IIOP_Profile.cpp.

References endpoint(), and TAO_Endpoint::next().

00026 {
00027   // Clean up the list of endpoints since we own it.
00028   // Skip the head, since it is not dynamically allocated.
00029   TAO_Endpoint *tmp = 0;
00030 
00031   for (TAO_Endpoint *next = this->endpoint ()->next ();
00032        next != 0;
00033        next = tmp)
00034     {
00035       tmp = next->next ();
00036       delete next;
00037     }
00038 }


Member Function Documentation

void TAO_IIOP_Profile::add_endpoint TAO_IIOP_Endpoint endp  ) 
 

Add endp to this profile's list of endpoints (it is inserted next to the head of the list). This profiles takes ownership of endp.

Definition at line 378 of file IIOP_Profile.cpp.

References endpoint_, and TAO_IIOP_Endpoint::next_.

Referenced by add_generic_endpoint(), TAO_IIOP_Acceptor::create_shared_profile(), and decode_endpoints().

00379 {
00380   endp->next_ = this->endpoint_.next_;
00381   this->endpoint_.next_ = endp;
00382 
00383   ++this->count_;
00384 }

void TAO_IIOP_Profile::add_generic_endpoint TAO_Endpoint ep  )  [virtual]
 

Add an endpoint when the specific endpoint type is unknown.

Reimplemented from TAO_Profile.

Definition at line 434 of file IIOP_Profile.cpp.

References ACE_NEW, add_endpoint(), and TAO_IIOP_Endpoint.

00435 {
00436   TAO_IIOP_Endpoint *iep = dynamic_cast<TAO_IIOP_Endpoint *>(endp);
00437   if (iep != 0)
00438     {
00439       TAO_IIOP_Endpoint *clone;
00440       ACE_NEW (clone, TAO_IIOP_Endpoint(*iep));
00441       this->add_endpoint(clone);
00442     }
00443 }

void TAO_IIOP_Profile::create_profile_body TAO_OutputCDR cdr  )  const [protected, virtual]
 

Creates an encapsulation of the ProfileBody struct in the cdr.

Implements TAO_Profile.

Definition at line 538 of file IIOP_Profile.cpp.

References ACE_CString, ACE_ERROR, TAO_Tagged_Components::encode(), endpoint_, TAO_IIOP_Endpoint::is_ipv6_decimal_, LM_ERROR, TAO_GIOP_Message_Version::major, TAO_GIOP_Message_Version::minor, TAO::Refcounted_ObjectKey::object_key(), ACE_OS::strchr(), TAO_Profile::tagged_components(), TAO_ENCAP_BYTE_ORDER, ACE_OutputCDR::write_octet(), ACE_OutputCDR::write_string(), and ACE_OutputCDR::write_ushort().

00539 {
00540   encap.write_octet (TAO_ENCAP_BYTE_ORDER);
00541 
00542   // The GIOP version
00543   encap.write_octet (this->version_.major);
00544   encap.write_octet (this->version_.minor);
00545 
00546   // STRING hostname from profile
00547 #if defined (ACE_HAS_IPV6)
00548   // For IPv6 decimal addresses make sure the possibly included scopeid
00549   // is not published as this has only local meaning.
00550   const char* host;
00551   const char* pos;
00552   if (this->endpoint_.is_ipv6_decimal_ &&
00553       (pos = ACE_OS::strchr (host = this->endpoint_.host (), '%')) != 0)
00554     {
00555       ACE_CString tmp;
00556       size_t len = pos - host;
00557       tmp.set (this->endpoint_.host (), len, 1);
00558       encap.write_string (tmp.c_str ());
00559     }
00560   else
00561 #endif /* ACE_HAS_IPV6 */
00562   encap.write_string (this->endpoint_.host ());
00563 
00564 
00565   // UNSIGNED SHORT port number
00566   encap.write_ushort (this->endpoint_.port ());
00567 
00568   // OCTET SEQUENCE for object key
00569   if (this->ref_object_key_)
00570     encap << this->ref_object_key_->object_key ();
00571   else
00572     {
00573       ACE_ERROR ((LM_ERROR,
00574                   "(%P|%t) TAO - IIOP_Profile::create_profile_body "
00575                   "no object key marshalled \n"));
00576     }
00577 
00578   if (this->version_.major > 1
00579       || this->version_.minor > 0)
00580     this->tagged_components ().encode (encap);
00581 }

int TAO_IIOP_Profile::decode_endpoints void   )  [protected, virtual]
 

Helper for decode(). Decodes endpoints from a tagged component. Decode only if RTCORBA is enabled. Furthermore, we may not find TAO_TAG_ENDPOINTS component, e.g., if we are talking to nonRT version of TAO or some other ORB. This is not an error, and we must proceed. Return 0 on success and -1 on failure.

Implements TAO_Profile.

Definition at line 730 of file IIOP_Profile.cpp.

References ACE_NEW_RETURN, add_endpoint(), IOP::TaggedComponent::component_data, TAO_Tagged_Components::components(), endpoint(), endpoint_, TAO::unbounded_value_sequence< TaggedComponent >::get_buffer(), TAO::unbounded_value_sequence< T >::get_buffer(), TAO_Tagged_Components::get_component(), TAO::String_var< charT >::in(), TAO::unbounded_value_sequence< TaggedComponent >::length(), TAO::unbounded_value_sequence< IIOP_Endpoint_Info >::length(), TAO::unbounded_value_sequence< T >::length(), TAO::String_var< charT >::out(), TAO_Endpoint::priority(), ACE_InputCDR::reset_byte_order(), CORBA::String_var, IOP::TaggedComponent::tag, and TAO_INVALID_PRIORITY.

00731 {
00732   IOP::TaggedComponent tagged_component;
00733   tagged_component.tag = TAO_TAG_ENDPOINTS;
00734 
00735   if (this->tagged_components_.get_component (tagged_component))
00736     {
00737       const CORBA::Octet *buf =
00738         tagged_component.component_data.get_buffer ();
00739 
00740       TAO_InputCDR in_cdr (reinterpret_cast<const char *> (buf),
00741                            tagged_component.component_data.length ());
00742 
00743       // Extract the Byte Order.
00744       CORBA::Boolean byte_order;
00745       if ((in_cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00746         return -1;
00747       in_cdr.reset_byte_order (static_cast<int> (byte_order));
00748 
00749       // Extract endpoints sequence.
00750       TAO::IIOPEndpointSequence endpoints;
00751 
00752       if ((in_cdr >> endpoints) == 0)
00753         return -1;
00754 
00755       // Get the priority of the first endpoint (head of the list.
00756       // It's other data is extracted as part of the standard profile
00757       // decoding.
00758       this->endpoint_.priority (endpoints[0].priority);
00759 
00760       // Use information extracted from the tagged component to
00761       // populate the profile.  Skip the first endpoint, since it is
00762       // always extracted through standard profile body.  Also, begin
00763       // from the end of the sequence to preserve endpoint order,
00764       // since <add_endpoint> method reverses the order of endpoints
00765       // in the list.
00766       for (CORBA::ULong i = endpoints.length () - 1;
00767            i > 0;
00768            --i)
00769         {
00770           TAO_IIOP_Endpoint *endpoint = 0;
00771           ACE_NEW_RETURN (endpoint,
00772                           TAO_IIOP_Endpoint (endpoints[i].host,
00773                                              endpoints[i].port,
00774                                              endpoints[i].priority),
00775                           -1);
00776 
00777           this->add_endpoint (endpoint);
00778         }
00779     }
00780 
00781   // Now decode if there are any TAG_ALTERNATE_IIOP_ADDRESS
00782   // components.
00783 
00784   IOP::MultipleComponentProfile& tc = this->tagged_components_.components();
00785   for (CORBA::ULong index = 0; index < tc.length(); index++)
00786     {
00787       if (tc[index].tag != IOP::TAG_ALTERNATE_IIOP_ADDRESS)
00788         continue;
00789       const CORBA::Octet *buf =
00790         tc[index].component_data.get_buffer ();
00791 
00792       TAO_InputCDR in_cdr (reinterpret_cast<const char*>(buf),
00793                            tc[index].component_data.length ());
00794 
00795       // Extract the Byte Order.
00796       CORBA::Boolean byte_order;
00797       if ((in_cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00798         return -1;
00799 
00800       in_cdr.reset_byte_order (static_cast<int>(byte_order));
00801 
00802       CORBA::String_var host;
00803       CORBA::Short port;
00804 
00805       if ((in_cdr >> host.out()) == 0 ||
00806           (in_cdr >> port) == 0)
00807         return -1;
00808 
00809       TAO_IIOP_Endpoint *endpoint = 0;
00810       ACE_NEW_RETURN (endpoint,
00811                       TAO_IIOP_Endpoint (host.in(),
00812                                          port,
00813                                          TAO_INVALID_PRIORITY),
00814                       -1);
00815 
00816       this->add_endpoint (endpoint);
00817     }
00818 
00819   return 0;
00820 }

int TAO_IIOP_Profile::decode_profile TAO_InputCDR cdr  )  [protected, virtual]
 

Template methods. Please see Profile.h for the documentation.

Implements TAO_Profile.

Definition at line 93 of file IIOP_Profile.cpp.

References ACE_DEBUG, ACE_TEXT, endpoint_, TAO_ORB_Parameters::enforce_pref_interfaces(), ACE_InputCDR::good_bit(), LM_DEBUG, TAO_IIOP_Endpoint::object_addr_, TAO_Profile::orb_core(), TAO_ORB_Core::orb_params(), TAO_IIOP_Endpoint::preferred_interfaces(), TAO_ORB_Parameters::preferred_interfaces(), ACE_InputCDR::read_string(), ACE_InputCDR::read_ushort(), ACE_Addr::set_type(), and TAO_debug_level.

00094 {
00095   // Decode host and port into the <endpoint_>.
00096   if (cdr.read_string (this->endpoint_.host_.out ()) == 0
00097       || cdr.read_ushort (this->endpoint_.port_) == 0)
00098     {
00099       if (TAO_debug_level > 0)
00100         ACE_DEBUG ((LM_DEBUG,
00101                     ACE_TEXT ("TAO (%P|%t) IIOP_Profile::decode - ")
00102                     ACE_TEXT ("error while decoding host/port\n")));
00103       return -1;
00104     }
00105 
00106   if (cdr.good_bit ())
00107     {
00108       // Invalidate the object_addr_ until first access.
00109       this->endpoint_.object_addr_.set_type (-1);
00110 
00111       const char* csv = this->orb_core()->orb_params()->preferred_interfaces();
00112       bool const enforce =
00113         this->orb_core()->orb_params()->enforce_pref_interfaces();
00114       this->count_ += this->endpoint_.preferred_interfaces(csv, enforce);
00115 
00116       return 1;
00117     }
00118 
00119   return -1;
00120 }

CORBA::Boolean TAO_IIOP_Profile::do_is_equivalent const TAO_Profile other_profile  )  [protected, virtual]
 

Profile equivalence template method invoked on subclasses.

TAO_Profile subclasses must implement this template method so that they can apply their own definition of profile equivalence.

Implements TAO_Profile.

Definition at line 304 of file IIOP_Profile.cpp.

References count_, endpoint_, TAO_IIOP_Endpoint::is_equivalent(), and TAO_IIOP_Endpoint::next_.

00305 {
00306   if (other_profile == this)
00307     return 1;
00308 
00309   const TAO_IIOP_Profile *op =
00310     dynamic_cast<const TAO_IIOP_Profile *> (other_profile);
00311 
00312   // Make sure we have a TAO_IIOP_Profile.
00313   if (op == 0)
00314     return 0;
00315 
00316   if (this->count_ == 0 && op->count_ == 0)
00317     return 1;
00318   if (this->count_ != op->count_)
00319     return 0;
00320   // Check endpoints equivalence.
00321   const TAO_IIOP_Endpoint *other_endp = &op->endpoint_;
00322   for (TAO_IIOP_Endpoint *endp = &this->endpoint_;
00323        endp != 0;
00324        endp = endp->next_)
00325     {
00326       if (endp->is_equivalent (other_endp))
00327         other_endp = other_endp->next_;
00328       else
00329         return 0;
00330     }
00331 
00332   return 1;
00333 }

int TAO_IIOP_Profile::encode_alternate_endpoints void   )  [virtual]
 

Encode alternate endpoints for non-RT profiles, using multiple TAG_ALTERNATE_IIOP_ADDRESS components, one endpoint per component

Reimplemented from TAO_Profile.

Definition at line 584 of file IIOP_Profile.cpp.

References ACE_CString, ACE_OutputCDR::begin(), IOP::TaggedComponent::component_data, ACE_Message_Block::cont(), endpoint(), endpoint_, TAO::unbounded_value_sequence< T >::get_buffer(), TAO_IIOP_Endpoint::host(), TAO_IIOP_Endpoint::is_encodable_, TAO_IIOP_Endpoint::is_ipv6_decimal_, ACE_Message_Block::length(), TAO::unbounded_value_sequence< T >::length(), ACE_OS::memcpy(), TAO_IIOP_Endpoint::next_, TAO_IIOP_Endpoint::port(), ACE_Message_Block::rd_ptr(), TAO_Tagged_Components::set_component(), ACE_OS::strchr(), IOP::TaggedComponent::tag, TAO_ENCAP_BYTE_ORDER, ACE_OutputCDR::total_length(), and ACE_OutputCDR::write_string().

00585 {
00586   // encode IOP::TAG_ALTERNATE_IIOP_ADDRESS tags if there are more
00587   // than one endpoints to listen to.
00588   const TAO_IIOP_Endpoint *endpoint = &this->endpoint_;
00589   for (CORBA::ULong i = 1;
00590        i < this->count_;
00591        ++i)
00592     {
00593       // The first endpoint is the actual endpoint. The rest of the
00594       // endpoints are the alternate endpoints. So, neglect the first
00595       // endpoint for TAG_ALTERNATE_IIOP_ADDRESS
00596       endpoint = endpoint->next_;
00597 
00598       if (!endpoint->is_encodable_)
00599         continue;
00600 
00601       // Encode the data structure. - The CORBA specification does not
00602       // mandate a particular container for the endpoints, only that
00603       // it is encoded as host first, then port.
00604       TAO_OutputCDR out_cdr;
00605 
00606 #if defined (ACE_HAS_IPV6)
00607       // For IPv6 decimal addresses make sure the possibly included scopeid
00608       // is not published as this has only local meaning.
00609       const char* host;
00610       const char* pos;
00611       if (endpoint->is_ipv6_decimal_ &&
00612           (pos = ACE_OS::strchr (host = endpoint->host (), '%')) != 0)
00613         {
00614           ACE_CString tmp;
00615           size_t len = pos - host;
00616           tmp.set (endpoint->host (), len, 1);
00617           if ((out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER) == 0)
00618               || (out_cdr << tmp.c_str () == 0)
00619               || (out_cdr << endpoint->port () == 0))
00620             return -1;
00621           out_cdr.write_string (len, endpoint->host ());
00622         }
00623       else
00624 #endif /* ACE_HAS_IPV6 */
00625       if ((out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER) == 0)
00626                 || (out_cdr << endpoint->host () == 0)
00627           || (out_cdr << endpoint->port () == 0))
00628         return -1;
00629 
00630       IOP::TaggedComponent tagged_component;
00631       tagged_component.tag = IOP::TAG_ALTERNATE_IIOP_ADDRESS;
00632 
00633       size_t length = out_cdr.total_length ();
00634       tagged_component.component_data.length
00635         (static_cast<CORBA::ULong>(length));
00636       CORBA::Octet *buf =
00637         tagged_component.component_data.get_buffer ();
00638 
00639       for (const ACE_Message_Block *iterator = out_cdr.begin ();
00640                  iterator != 0;
00641            iterator = iterator->cont ())
00642         {
00643           size_t i_length = iterator->length ();
00644           ACE_OS::memcpy (buf, iterator->rd_ptr (), i_length);
00645 
00646           buf += i_length;
00647         }
00648 
00649       // Add component with encoded endpoint data to this profile's
00650       // TaggedComponents.
00651       tagged_components_.set_component (tagged_component);
00652     }
00653   return  0;
00654 }

int TAO_IIOP_Profile::encode_endpoints void   )  [virtual]
 

Encode endpoints for RT profiles, using a single TAO_TAG_ENDPOINT component.

Implements TAO_Profile.

Definition at line 657 of file IIOP_Profile.cpp.

References ACE_CString, endpoint(), endpoint_, TAO_IIOP_Endpoint::host(), TAO_IIOP_Endpoint::is_encodable_, TAO_IIOP_Endpoint::is_ipv6_decimal_, TAO::unbounded_value_sequence< IIOP_Endpoint_Info >::length(), TAO_IIOP_Endpoint::next_, TAO_IIOP_Endpoint::port(), TAO_Endpoint::priority(), TAO_Profile::set_tagged_components(), ssize_t, and TAO_ENCAP_BYTE_ORDER.

00658 {
00659   CORBA::ULong actual_count = 0;
00660 
00661   const TAO_IIOP_Endpoint *endpoint = &this->endpoint_;
00662 
00663   // Count the number of endpoints that needs to be encoded
00664   for (CORBA::ULong c = 0;
00665        c != this->count_;
00666        ++c)
00667     {
00668       if (endpoint->is_encodable_)
00669         ++actual_count;
00670 
00671       endpoint = endpoint->next_;
00672     }
00673 
00674   // Create a data structure and fill it with endpoint info for wire
00675   // transfer.
00676   // We include information for the head of the list
00677   // together with other endpoints because even though its addressing
00678   // info is transmitted using standard ProfileBody components, its
00679   // priority is not!
00680 
00681   TAO::IIOPEndpointSequence endpoints;
00682   endpoints.length (actual_count);
00683 
00684   endpoint = &this->endpoint_;
00685 
00686   for (CORBA::ULong i = 0;
00687        i < actual_count;
00688        ++i)
00689     {
00690       if (endpoint->is_encodable_)
00691         {
00692 #if defined (ACE_HAS_IPV6)
00693           if (endpoint->is_ipv6_decimal_)
00694             {
00695               // Don't publish scopeid if included.
00696               ACE_CString tmp(endpoint->host ());
00697               ssize_t pos = tmp.find('%');
00698               if (pos != ACE_CString::npos)
00699                 {
00700                   tmp = tmp.substr (0, pos + 1);
00701                   tmp[pos] = '\0';
00702                   endpoints[i].host = tmp.c_str();
00703                 }
00704               else
00705                 endpoints[i].host = tmp.c_str();
00706             }
00707           else
00708 #endif /* ACE_HAS_IPV6 */
00709           endpoints[i].host = endpoint->host ();
00710           endpoints[i].port = endpoint->port ();
00711           endpoints[i].priority = endpoint->priority ();
00712         }
00713       endpoint = endpoint->next_;
00714     }
00715 
00716   // Encode the data structure.
00717   TAO_OutputCDR out_cdr;
00718   if ((out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)
00719        == 0)
00720       || (out_cdr << endpoints) == 0)
00721     return -1;
00722 
00723   this->set_tagged_components (out_cdr);
00724 
00725   return  0;
00726 }

int TAO_IIOP_Profile::encode_endpoints_for_rt void   )  [protected]
 

Helper method for encode_endpoints to deal with RT requests.

Encodes this profile's endpoints into a tagged component. This is done only if RTCORBA is enabled, since currently this is the only case when we have more than one endpoint per profile. Returns 0 on success and -1 on failure.

Endpoints are transmitted using TAO-proprietory tagged component. Component tag is TAO_TAG_ENDPOINTS and component data is an encapsulation of a sequence of structs, each representing a single endpoint. Data format is specified in iiop_endpoins.pidl.

TAO_Endpoint * TAO_IIOP_Profile::endpoint void   )  [virtual]
 

Return a pointer to this profile's endpoint. If the profile contains more than one endpoint, i.e., a list, the method returns the head of the list.

Implements TAO_Profile.

Definition at line 366 of file IIOP_Profile.cpp.

References endpoint_.

Referenced by TAO_IIOP_Acceptor::create_new_profile(), TAO_IIOP_Acceptor::create_shared_profile(), decode_endpoints(), encode_alternate_endpoints(), encode_endpoints(), and ~TAO_IIOP_Profile().

00367 {
00368   return &this->endpoint_;
00369 }

CORBA::ULong TAO_IIOP_Profile::endpoint_count void   )  const [virtual]
 

Return how many endpoints this profile contains.

Implements TAO_Profile.

Definition at line 372 of file IIOP_Profile.cpp.

00373 {
00374   return this->count_;
00375 }

CORBA::ULong TAO_IIOP_Profile::hash CORBA::ULong  max  )  [virtual]
 

Return a hash value for this object.

Implements TAO_Profile.

Definition at line 336 of file IIOP_Profile.cpp.

References endpoint_, TAO_IIOP_Endpoint::hash(), TAO_Profile::hash_service_i(), TAO::unbounded_value_sequence< T >::length(), TAO_GIOP_Message_Version::minor, TAO_IIOP_Endpoint::next_, TAO::Refcounted_ObjectKey::object_key(), and TAO_Profile::tag().

00338 {
00339   // Get the hash value for all endpoints.
00340   CORBA::ULong hashval = 0;
00341   for (TAO_IIOP_Endpoint *endp = &this->endpoint_;
00342        endp != 0;
00343        endp = endp->next_)
00344     {
00345       hashval += endp->hash ();
00346     }
00347 
00348   hashval += this->version_.minor;
00349   hashval += this->tag ();
00350 
00351   const TAO::ObjectKey &ok =
00352     this->ref_object_key_->object_key ();
00353 
00354   if (ok.length () >= 4)
00355     {
00356       hashval += ok[1];
00357       hashval += ok[3];
00358     }
00359 
00360   hashval += TAO_Profile::hash_service_i (max);
00361 
00362   return hashval % max;
00363 }

char TAO_IIOP_Profile::object_key_delimiter void   )  const [virtual]
 

The object key delimiter that IIOP uses or expects.

Implements TAO_Profile.

Definition at line 45 of file IIOP_Profile.cpp.

References object_key_delimiter_.

00046 {
00047   return TAO_IIOP_Profile::object_key_delimiter_;
00048 }

void TAO_IIOP_Profile::parse_string_i const char *  string  )  [protected, virtual]
 

Protocol specific implementation of parse_string ().

Implements TAO_Profile.

Definition at line 123 of file IIOP_Profile.cpp.

References TAO::String_var< charT >::_retn(), ACE_DEBUG, ACE_TEXT, ACE_THROW, ACE_OS::atoi(), TAO::ObjectKey_Table::bind(), TAO::ObjectKey::decode_string_to_sequence(), endpoint_, ACE_INET_Addr::get_host_name(), ACE_INET_Addr::get_port_number(), TAO_IIOP_Endpoint::host_, TAO::String_var< charT >::in(), TAO::String_var< charT >::inout(), TAO_IIOP_Endpoint::is_ipv6_decimal_, LM_DEBUG, LM_ERROR, TAO_GIOP_Message_Version::major, MAXHOSTNAMELEN, TAO_GIOP_Message_Version::minor, TAO_ORB_Core::object_key_table(), TAO_Profile::orb_core(), TAO_IIOP_Endpoint::port_, ACE_OS::strchr(), ACE_OS::strcmp(), CORBA::string_alloc(), CORBA::string_dup(), ACE_INET_Addr::string_to_addr(), CORBA::String_var, ACE_OS::strncpy(), ACE_OS::strspn(), TAO_debug_level, TAO_MIN_IPV6_IIOP_MAJOR, TAO_MIN_IPV6_IIOP_MINOR, and TAO_Profile::version().

00125 {
00126   // Pull off the "hostname:port/" part of the objref
00127   // Copy the string because we are going to modify it...
00128 
00129   const char *okd = ACE_OS::strchr (ior, this->object_key_delimiter_);
00130 
00131   if (okd == 0 || okd == ior)
00132     {
00133       // No object key delimiter or no hostname specified.
00134       ACE_THROW (CORBA::INV_OBJREF (
00135                    CORBA::SystemException::_tao_minor_code (
00136                      0,
00137                      EINVAL),
00138                    CORBA::COMPLETED_NO));
00139     }
00140 
00141   // Length of host string.
00142   CORBA::ULong length_host = 0;
00143 
00144   const char *cp_pos = ACE_OS::strchr (ior, ':');  // Look for a port
00145 #if defined (ACE_HAS_IPV6)
00146   // IPv6 numeric address in host string?
00147   bool ipv6_in_host = false;
00148 
00149   // Check if this is a (possibly) IPv6 supporting profile containing a
00150   // decimal IPv6 address representation.
00151   if ((this->version().major > TAO_MIN_IPV6_IIOP_MAJOR ||
00152         this->version().minor >= TAO_MIN_IPV6_IIOP_MINOR) &&
00153       ior[0] == '[')
00154     {
00155       // In this case we have to find the end of the numeric address and
00156       // start looking for the port separator from there.
00157       const char *cp_pos_a = ACE_OS::strchr(ior, ']');
00158       if (cp_pos_a == 0)
00159         {
00160           // No valid IPv6 address specified.
00161           if (TAO_debug_level > 0)
00162             {
00163               ACE_DEBUG ((LM_ERROR,
00164                        ACE_TEXT ("\nTAO (%P|%t) IIOP_Profile: ")
00165                        ACE_TEXT ("Invalid IPv6 decimal address specified.\n")));
00166             }
00167 
00168           ACE_THROW (CORBA::INV_OBJREF (
00169                        CORBA::SystemException::_tao_minor_code (
00170                          0,
00171                          EINVAL),
00172                        CORBA::COMPLETED_NO));
00173         }
00174       else
00175         {
00176           if (cp_pos_a[1] == ':')    // Look for a port
00177             cp_pos = cp_pos_a + 1;
00178           else
00179             cp_pos = 0;
00180           ipv6_in_host = true; // host string contains full IPv6 numeric address
00181         }
00182     }
00183 #endif /* ACE_HAS_IPV6 */
00184 
00185   if (cp_pos == ior)
00186     {
00187       // No hostname, however one is required by the spec when specifying a port.
00188       // See formal-04-03-01, section 13.6.10.3
00189       if (TAO_debug_level > 0)
00190         {
00191           ACE_DEBUG ((LM_ERROR,
00192                    ACE_TEXT ("\nTAO (%P|%t) IIOP_Profile: ")
00193                    ACE_TEXT ("Host address may be omited only when no port has been specified.\n")));
00194         }
00195 
00196       ACE_THROW (CORBA::INV_OBJREF (
00197                    CORBA::SystemException::_tao_minor_code (
00198                      0,
00199                      EINVAL),
00200                    CORBA::COMPLETED_NO));
00201     }
00202   else if (cp_pos != 0)
00203     {
00204       // A port number or port name was specified.
00205       CORBA::ULong length_port = okd - cp_pos - 1;
00206       CORBA::String_var tmp = CORBA::string_alloc (length_port);
00207 
00208       ACE_OS::strncpy (tmp.inout (), cp_pos + 1, length_port);
00209       tmp[length_port] = '\0';
00210       if (length_port == 0)
00211         {
00212           this->endpoint_.port_ = 2809; // default IIOP port for
00213           // parsing corbaloc strings
00214         }
00215       else if (ACE_OS::strspn (tmp.in (), "1234567890") == length_port)
00216         {
00217           this->endpoint_.port_ =
00218             static_cast<CORBA::UShort> (ACE_OS::atoi (tmp.in ()));
00219         }
00220       else
00221         {
00222           ACE_INET_Addr ia;
00223           if (ia.string_to_addr (tmp.in ()) == -1)
00224             {
00225               ACE_THROW (CORBA::INV_OBJREF (
00226                              CORBA::SystemException::_tao_minor_code (
00227                                0,
00228                                EINVAL),
00229                              CORBA::COMPLETED_NO));
00230             }
00231           else
00232             {
00233               this->endpoint_.port_ = ia.get_port_number ();
00234             }
00235         }
00236       length_host = cp_pos - ior;
00237     }
00238   else
00239     length_host = okd - ior;
00240 
00241 #if defined (ACE_HAS_IPV6)
00242   if (ipv6_in_host)
00243     length_host -= 2; // don't store '[' and ']'
00244 #endif /* ACE_HAS_IPV6 */
00245 
00246   CORBA::String_var tmp = CORBA::string_alloc (length_host);
00247 
00248 #if defined (ACE_HAS_IPV6)
00249   if (ipv6_in_host)
00250     ACE_OS::strncpy (tmp.inout (), ior + 1, length_host);
00251   else
00252 #endif /* ACE_HAS_IPV6 */
00253   // Skip the trailing '/'
00254   ACE_OS::strncpy (tmp.inout (), ior, length_host);
00255   tmp[length_host] = '\0';
00256 
00257   this->endpoint_.host_ = tmp._retn ();
00258 #if defined (ACE_HAS_IPV6)
00259   this->endpoint_.is_ipv6_decimal_ = ipv6_in_host;
00260 #endif /* ACE_HAS_IPV6 */
00261 
00262   if (ACE_OS::strcmp (this->endpoint_.host_.in (), "") == 0)
00263     {
00264       ACE_INET_Addr host_addr;
00265 
00266       char tmp_host [MAXHOSTNAMELEN + 1];
00267 
00268       // If no host is specified: assign the default host, i.e. the
00269       // local host.
00270       if (host_addr.get_host_name (tmp_host,
00271                                    sizeof (tmp_host)) != 0)
00272         {
00273           // Can't get the IP address since the INET_Addr wasn't
00274           // initialized.  Just throw an exception.
00275 
00276           if (TAO_debug_level > 0)
00277             ACE_DEBUG ((LM_DEBUG,
00278                         ACE_TEXT ("\n\nTAO (%P|%t) ")
00279                         ACE_TEXT ("IIOP_Profile::parse_string ")
00280                         ACE_TEXT ("- %p\n\n"),
00281                         ACE_TEXT ("cannot determine hostname")));
00282 
00283           // @@ What's the right exception to throw here?
00284           ACE_THROW (CORBA::INV_OBJREF (
00285                        CORBA::SystemException::_tao_minor_code (
00286                          0,
00287                          EINVAL),
00288                        CORBA::COMPLETED_NO));
00289         }
00290       else
00291         this->endpoint_.host_ = CORBA::string_dup (tmp_host);
00292     }
00293 
00294   TAO::ObjectKey ok;
00295 
00296   TAO::ObjectKey::decode_string_to_sequence (ok,
00297                                              okd + 1);
00298 
00299   (void) this->orb_core ()->object_key_table ().bind (ok,
00300                                                       this->ref_object_key_);
00301 }

const char * TAO_IIOP_Profile::prefix void   )  [static]
 

Return the char string prefix.

Definition at line 532 of file IIOP_Profile.cpp.

00533 {
00534   return ::the_prefix;
00535 }

void TAO_IIOP_Profile::remove_endpoint TAO_IIOP_Endpoint endp  ) 
 

Remove endp from this profile's list of endpoints and free the endp memory. This method assumes endp is in this profile's endpoint list.

Definition at line 387 of file IIOP_Profile.cpp.

References endpoint_, and TAO_IIOP_Endpoint::next_.

Referenced by remove_generic_endpoint().

00388 {
00389   if (endp == 0)
00390     return;
00391 
00392   // special handling for the target matching the base endpoint
00393   if (endp == &this->endpoint_)
00394     {
00395       if (--this->count_ > 0)
00396         {
00397           TAO_IIOP_Endpoint* n = this->endpoint_.next_;
00398           this->endpoint_ = *n;
00399           // since the assignment operator does not copy the next_
00400           // pointer, we must do it by hand
00401           this->endpoint_.next_ = n->next_;
00402           delete n;
00403         }
00404       return;
00405     }
00406 
00407   TAO_IIOP_Endpoint* last = &this->endpoint_;
00408   TAO_IIOP_Endpoint* cur = this->endpoint_.next_;
00409 
00410   while (cur != 0)
00411   {
00412     if (cur == endp)
00413       break;
00414     last = cur;
00415     cur = cur->next_;
00416   }
00417 
00418   if (cur != 0)
00419   {
00420     last->next_ = cur->next_;
00421     cur->next_ = 0;
00422     --this->count_;
00423     delete cur;
00424   }
00425 }

void TAO_IIOP_Profile::remove_generic_endpoint TAO_Endpoint ep  )  [virtual]
 

Remove the provided endpoint from the profile. Some subclasses of TAO_Profile already have a protocol-specific version of remove_endpoint, but this generic interface is required. The default implementation is a no-op. Protocol maintainers wishing to add support for the EndpointPolicy must implement remove_generic_endpoint to call their protocol-specific version of remove_endpoint

Reimplemented from TAO_Profile.

Definition at line 428 of file IIOP_Profile.cpp.

References remove_endpoint().

00429 {
00430   this->remove_endpoint(dynamic_cast<TAO_IIOP_Endpoint *>(ep));
00431 }

char * TAO_IIOP_Profile::to_string  )  [virtual]
 

Template methods. Please see Profile.h for documentation.

Implements TAO_Profile.

Definition at line 446 of file IIOP_Profile.cpp.

References ACE_CString, TAO::ObjectKey::encode_sequence_to_string(), endpoint_, TAO_IIOP_Endpoint::host(), TAO::String_var< charT >::in(), TAO::String_var< charT >::inout(), TAO_IIOP_Endpoint::is_ipv6_decimal_, TAO_IIOP_Endpoint::next_, TAO::Refcounted_ObjectKey::object_key(), TAO_IIOP_Endpoint::port(), ACE_OS::sprintf(), ssize_t, ACE_OS::strcat(), ACE_OS::strcpy(), CORBA::string_alloc(), CORBA::String_var, ACE_OS::strlen(), and the_prefix.

00447 {
00448   // corbaloc:iiop:1.2@host:port,iiop:1.2@host:port,.../key
00449 
00450   CORBA::String_var key;
00451   TAO::ObjectKey::encode_sequence_to_string (key.inout(),
00452                                              this->ref_object_key_->object_key ());
00453 
00454   size_t buflen = (
00455        8 /* "corbaloc" */ +
00456        1 /* colon separator */ +
00457        1 /* object key separator */ +
00458        ACE_OS::strlen (key.in ()));
00459   size_t pfx_len = (
00460        ACE_OS::strlen (::the_prefix) /* "iiop" */ +
00461        1 /* colon separator */);
00462 
00463  const TAO_IIOP_Endpoint *endp = 0;
00464  for (endp = &this->endpoint_; endp != 0; endp = endp->next_)
00465    {
00466       buflen += (
00467           pfx_len +
00468           1 /* major version */ +
00469           1 /* decimal point */ +
00470           1 /* minor version */ +
00471           1 /* `@' character */ +
00472           ACE_OS::strlen (endp->host ()) +
00473           1 /* colon separator */ +
00474           5 /* port number */ +
00475           1 /* comma */);
00476 #if defined (ACE_HAS_IPV6)
00477       if (endp->is_ipv6_decimal_)
00478         buflen += 2; // room for '[' and ']'
00479 #endif /* ACE_HAS_IPV6 */
00480    }
00481 
00482   static const char digits [] = "0123456789";
00483 
00484   char * buf = CORBA::string_alloc (static_cast<CORBA::ULong> (buflen));
00485 
00486   ACE_OS::strcpy(buf, "corbaloc:");
00487 
00488   for (endp = &this->endpoint_; endp != 0; endp = endp->next_)
00489     {
00490       if(&this->endpoint_ != endp)
00491       ACE_OS::strcat(buf, ",");
00492 
00493 #if defined (ACE_HAS_IPV6)
00494       if (endp->is_ipv6_decimal_)
00495         {
00496           // Don't publish scopeid if included.
00497           ACE_CString tmp(endp->host ());
00498           ssize_t pos = tmp.find('%');
00499           if (pos != ACE_CString::npos)
00500             {
00501               tmp = tmp.substr(0, pos + 1);
00502               tmp[pos] = '\0';
00503             }
00504           ACE_OS::sprintf (buf + ACE_OS::strlen(buf),
00505                   "%s:%c.%c@[%s]:%d",
00506                   ::the_prefix,
00507                   digits [this->version_.major],
00508                   digits [this->version_.minor],
00509                   tmp.c_str (),
00510                   endp->port () );
00511         }
00512       else
00513 #endif
00514       ACE_OS::sprintf (buf + ACE_OS::strlen(buf),
00515               "%s:%c.%c@%s:%d",
00516               ::the_prefix,
00517               digits [this->version_.major],
00518               digits [this->version_.minor],
00519               endp->host (),
00520               endp->port () );
00521 
00522   }
00523   ACE_OS::sprintf (buf + ACE_OS::strlen(buf),
00524           "%c%s",
00525           this->object_key_delimiter_,
00526           key.in ());
00527 
00528   return buf;
00529 }


Member Data Documentation

CORBA::ULong TAO_IIOP_Profile::count_ [protected]
 

Number of endpoints in the list headed by .

Definition at line 182 of file IIOP_Profile.h.

Referenced by do_is_equivalent().

TAO_IIOP_Endpoint TAO_IIOP_Profile::endpoint_ [protected]
 

Head of this profile's list of endpoints. This endpoint is not dynamically allocated because a profile always contains at least one endpoint.

Currently, a profile contains more than one endpoint, i.e., list contains more than just the head, only for two cases (1) when RTCORBA is enabled and (2) the ORB is initialized with -ORBPreferredInterfaces option. However, in the near future, this will be used in for mode as well, e.g., to support TAG_ALTERNATE_IIOP_ADDRESS feature.

This is probably as good a place to discuss how the list of endpoints is used for #2. If the ORB is configured to use preferred interfaces for invocation, TAO creates an endpoint per preferred interface. To be clear, every tuple <destination:target> will have an endpoint. What TAO essentially does is that creates it multiple endpoints so that the invocation code path can use existing iterating techniques to try one preferred interface after another (if the first did not work). If the ORB is configured with -ORBEnforcePreferredInterface set to false in addition to the ORBPreferredInterfaces option , TAO creates another endpoint with the preferred bit set to null, so that the invocation code can fall back to a TCP stack returned local address. Addressing info of the default endpoint, i.e., head of the list, is transmitted using standard IIOP ProfileBody components. See method documentation above for how the rest of the endpoint list is transmitted.

Definition at line 179 of file IIOP_Profile.h.

Referenced by add_endpoint(), create_profile_body(), decode_endpoints(), decode_profile(), do_is_equivalent(), encode_alternate_endpoints(), encode_endpoints(), endpoint(), hash(), parse_string_i(), remove_endpoint(), and to_string().

const char TAO_IIOP_Profile::object_key_delimiter_ = '/' [static]
 

Definition at line 42 of file IIOP_Profile.cpp.

Referenced by object_key_delimiter().


The documentation for this class was generated from the following files:
Generated on Thu Nov 9 12:14:43 2006 for TAO by doxygen 1.3.6