TAO_IIOP_Acceptor Class Reference

TAO_IIOP_Acceptor. More...

#include <IIOP_Acceptor.h>

Inheritance diagram for TAO_IIOP_Acceptor:

Inheritance graph
[legend]
Collaboration diagram for TAO_IIOP_Acceptor:

Collaboration graph
[legend]
List of all members.

Public Types

typedef ACE_Strategy_Acceptor<
TAO_IIOP_Connection_Handler,
ACE_SOCK_ACCEPTOR
BASE_ACCEPTOR
typedef TAO_Creation_Strategy<
TAO_IIOP_Connection_Handler
CREATION_STRATEGY
typedef TAO_Concurrency_Strategy<
TAO_IIOP_Connection_Handler
CONCURRENCY_STRATEGY
typedef TAO_Accept_Strategy<
TAO_IIOP_Connection_Handler,
ACE_SOCK_ACCEPTOR
ACCEPT_STRATEGY

Public Member Functions

 TAO_IIOP_Acceptor (void)
 Constructor.

 ~TAO_IIOP_Acceptor (void)
 Destructor.

const ACE_INET_Addraddress (void) const
const ACE_INET_Addrendpoints (void)
 Returns the array of endpoints in this acceptor.

const ACE_INET_Addrdefault_address (void) const
 Returns address for default endpoint.

void set_default_address (const ACE_INET_Addr &addr)
 Set address for default endpoint.

virtual int open (TAO_ORB_Core *orb_core, ACE_Reactor *reactor, int version_major, int version_minor, const char *address, const char *options=0)
virtual int open_default (TAO_ORB_Core *orb_core, ACE_Reactor *reactor, int version_major, int version_minor, const char *options=0)
virtual int close (void)
 Closes the acceptor.

virtual int create_profile (const TAO::ObjectKey &object_key, TAO_MProfile &mprofile, CORBA::Short priority)
virtual int is_collocated (const TAO_Endpoint *endpoint)
 Return 1 if the endpoint has the same address as the acceptor.

virtual CORBA::ULong endpoint_count (void)
virtual int object_key (IOP::TaggedProfile &profile, TAO::ObjectKey &key)
virtual int hostname (TAO_ORB_Core *orb_core, ACE_INET_Addr &addr, char *&host, const char *specified_hostname=0)

Protected Member Functions

int parse_address (const char *address, ACE_INET_Addr &addr, ACE_CString &specified_hostname, int *def_type=0)
int dotted_decimal_address (ACE_INET_Addr &addr, char *&host)
virtual int open_i (const ACE_INET_Addr &addr, ACE_Reactor *reactor)
int probe_interfaces (TAO_ORB_Core *orb_core, int def_type=AF_UNSPEC)
int parse_options (const char *options)
virtual int parse_options_i (int &argc, ACE_CString **argv)
int create_new_profile (const TAO::ObjectKey &object_key, TAO_MProfile &mprofile, CORBA::Short priority)
int create_shared_profile (const TAO::ObjectKey &object_key, TAO_MProfile &mprofile, CORBA::Short priority)

Protected Attributes

ACE_INET_Addraddrs_
unsigned short port_span_
char ** hosts_
char * hostname_in_ior_
CORBA::ULong endpoint_count_
TAO_GIOP_Message_Version version_
TAO_ORB_Coreorb_core_
 ORB Core.

int reuse_addr_
 Enable socket option SO_REUSEADDR to be set.

ACE_INET_Addr default_address_
 Address for default endpoint.


Private Attributes

BASE_ACCEPTOR base_acceptor_
 The concrete acceptor, as a pointer to it's base class.

CREATION_STRATEGYcreation_strategy_
 Acceptor strategies.

CONCURRENCY_STRATEGYconcurrency_strategy_
ACCEPT_STRATEGYaccept_strategy_

Detailed Description

TAO_IIOP_Acceptor.

The IIOP-specific bridge class for the concrete acceptor.

Definition at line 48 of file IIOP_Acceptor.h.


Member Typedef Documentation

typedef TAO_Accept_Strategy<TAO_IIOP_Connection_Handler, ACE_SOCK_ACCEPTOR> TAO_IIOP_Acceptor::ACCEPT_STRATEGY
 

Definition at line 80 of file IIOP_Acceptor.h.

typedef ACE_Strategy_Acceptor<TAO_IIOP_Connection_Handler, ACE_SOCK_ACCEPTOR> TAO_IIOP_Acceptor::BASE_ACCEPTOR
 

Definition at line 77 of file IIOP_Acceptor.h.

typedef TAO_Concurrency_Strategy<TAO_IIOP_Connection_Handler> TAO_IIOP_Acceptor::CONCURRENCY_STRATEGY
 

Definition at line 79 of file IIOP_Acceptor.h.

typedef TAO_Creation_Strategy<TAO_IIOP_Connection_Handler> TAO_IIOP_Acceptor::CREATION_STRATEGY
 

Definition at line 78 of file IIOP_Acceptor.h.


Constructor & Destructor Documentation

TAO_BEGIN_VERSIONED_NAMESPACE_DECL TAO_IIOP_Acceptor::TAO_IIOP_Acceptor void   ) 
 

Constructor.

Definition at line 32 of file IIOP_Acceptor.cpp.

References INADDR_ANY, TAO_DEF_GIOP_MAJOR, and TAO_DEF_GIOP_MINOR.

00033   : TAO_Acceptor (IOP::TAG_INTERNET_IOP),
00034     addrs_ (0),
00035     port_span_ (1),
00036     hosts_ (0),
00037     hostname_in_ior_ (0),
00038     endpoint_count_ (0),
00039     version_ (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR),
00040     orb_core_ (0),
00041     reuse_addr_ (1),
00042 #if defined (ACE_HAS_IPV6)
00043     default_address_ (static_cast<unsigned short> (0), ACE_IPV6_ANY, AF_INET6),
00044 #else
00045     default_address_ (static_cast<unsigned short> (0), static_cast<ACE_UINT32> (INADDR_ANY)),
00046 #endif /* ACE_HAS_IPV6 */
00047     base_acceptor_ (),
00048     creation_strategy_ (0),
00049     concurrency_strategy_ (0),
00050     accept_strategy_ (0)
00051 {
00052 }

TAO_IIOP_Acceptor::~TAO_IIOP_Acceptor void   ) 
 

Destructor.

Definition at line 56 of file IIOP_Acceptor.cpp.

References addrs_, close(), endpoint_count_, hostname_in_ior_, hosts_, and CORBA::string_free().

00057 {
00058   // Make sure we are closed before we start destroying the
00059   // strategies.
00060   this->close ();
00061 
00062   delete this->creation_strategy_;
00063   delete this->concurrency_strategy_;
00064   delete this->accept_strategy_;
00065 
00066   delete [] this->addrs_;
00067 
00068   for (CORBA::ULong i = 0; i < this->endpoint_count_; ++i)
00069     CORBA::string_free (this->hosts_[i]);
00070 
00071   delete [] this->hosts_;
00072 
00073   delete [] this->hostname_in_ior_;
00074 }


Member Function Documentation

const ACE_INET_Addr& TAO_IIOP_Acceptor::address void   )  const
 

@ Helper method for the implementation repository, should go away

int TAO_IIOP_Acceptor::close void   )  [virtual]
 

Closes the acceptor.

Implements TAO_Acceptor.

Definition at line 260 of file IIOP_Acceptor.cpp.

References base_acceptor_, and ACE_Acceptor< SVC_HANDLER, ACE_PEER_ACCEPTOR_2 >::close().

Referenced by ~TAO_IIOP_Acceptor().

00261 {
00262   return this->base_acceptor_.close ();
00263 }

int TAO_IIOP_Acceptor::create_new_profile const TAO::ObjectKey object_key,
TAO_MProfile mprofile,
CORBA::Short  priority
[protected]
 

Helper method to add a new profile to the mprofile for each endpoint.

Definition at line 99 of file IIOP_Acceptor.cpp.

References TAO_Profile::_decr_refcnt(), ACE_NEW_RETURN, addrs_, TAO_ORB_Core::codeset_manager(), TAO_IIOP_Profile::endpoint(), endpoint_count_, ACE_INET_Addr::get_port_number(), TAO_MProfile::give_profile(), TAO_MProfile::grow(), TAO_ORB_Core::orb_params(), TAO_Endpoint::priority(), TAO_MProfile::profile_count(), TAO_Codeset_Manager::set_codeset(), TAO_Tagged_Components::set_orb_type(), TAO_MProfile::size(), TAO_ORB_Parameters::std_profile_components(), ACE_OS::strcmp(), TAO_Profile::tagged_components(), TAO_ORB_TYPE, and version_.

Referenced by create_profile().

00102 {
00103   // Adding this->endpoint_count_ to the TAO_MProfile.
00104   int const count = mprofile.profile_count ();
00105   if ((mprofile.size () - count) < this->endpoint_count_
00106       && mprofile.grow (count + this->endpoint_count_) == -1)
00107     return -1;
00108 
00109   // Create a profile for each acceptor endpoint.
00110   for (CORBA::ULong i = 0; i < this->endpoint_count_; ++i)
00111     {
00112       // Skip if the host name
00113       if (i > 0
00114           && (this->addrs_[i].get_port_number() == this->addrs_[0].get_port_number())
00115           && ACE_OS::strcmp(this->hosts_[i], this->hosts_[0]) == 0)
00116         continue;
00117 
00118       TAO_IIOP_Profile *pfile = 0;
00119       ACE_NEW_RETURN (pfile,
00120                       TAO_IIOP_Profile (this->hosts_[i],
00121                                         this->addrs_[i].get_port_number (),
00122                                         object_key,
00123                                         this->addrs_[i],
00124                                         this->version_,
00125                                         this->orb_core_),
00126                       -1);
00127       pfile->endpoint ()->priority (priority);
00128 
00129       if (mprofile.give_profile (pfile) == -1)
00130         {
00131           pfile->_decr_refcnt ();
00132           pfile = 0;
00133           return -1;
00134         }
00135 
00136       // Do not add any tagged components to the profile if configured
00137       // by the user not to do so, or if an IIOP 1.0 endpoint is being
00138       // created (IIOP 1.0 did not support tagged components).
00139       if (this->orb_core_->orb_params ()->std_profile_components () == 0
00140           || (this->version_.major == 1 && this->version_.minor == 0))
00141         continue;
00142 
00143       pfile->tagged_components ().set_orb_type (TAO_ORB_TYPE);
00144 
00145       TAO_Codeset_Manager *csm = this->orb_core_->codeset_manager();
00146       if (csm)
00147         csm->set_codeset(pfile->tagged_components());
00148     }
00149 
00150   return 0;
00151 }

int TAO_IIOP_Acceptor::create_profile const TAO::ObjectKey object_key,
TAO_MProfile mprofile,
CORBA::Short  priority
[virtual]
 

Create the corresponding profile for this endpoint. If share_profile is set to true, the pluggable protocol implementation should try to add the endpoint to a profile in the mprofile that is of the same type. Currently, this is used when RT CORBA is enabled.

Implements TAO_Acceptor.

Definition at line 81 of file IIOP_Acceptor.cpp.

References create_new_profile(), create_shared_profile(), endpoint_count_, TAO_ORB_Core::orb_params(), TAO_ORB_Parameters::shared_profile(), and TAO_INVALID_PRIORITY.

00084 {
00085   // Sanity check.
00086   if (this->endpoint_count_ == 0)
00087     return -1;
00088 
00089   // Check if multiple endpoints should be put in one profile or
00090   // if they should be spread across multiple profiles.
00091   if (priority == TAO_INVALID_PRIORITY &&
00092       this->orb_core_->orb_params ()->shared_profile () == 0)
00093     return this->create_new_profile (object_key, mprofile, priority);
00094   else
00095     return this->create_shared_profile (object_key, mprofile, priority);
00096 }

int TAO_IIOP_Acceptor::create_shared_profile const TAO::ObjectKey object_key,
TAO_MProfile mprofile,
CORBA::Short  priority
[protected]
 

Helper method to create a profile that contains all of our endpoints.

Definition at line 154 of file IIOP_Acceptor.cpp.

References TAO_Profile::_decr_refcnt(), ACE_NEW_RETURN, TAO_IIOP_Profile::add_endpoint(), addrs_, TAO_ORB_Core::codeset_manager(), TAO_IIOP_Profile::endpoint(), endpoint_count_, ACE_INET_Addr::get_port_number(), TAO_MProfile::get_profile(), TAO_MProfile::give_profile(), TAO_ORB_Core::orb_params(), TAO_Endpoint::priority(), TAO_MProfile::profile_count(), TAO_Codeset_Manager::set_codeset(), TAO_Tagged_Components::set_orb_type(), TAO_ORB_Parameters::std_profile_components(), ACE_OS::strcmp(), TAO_Profile::tag(), TAO_Profile::tagged_components(), TAO_ORB_TYPE, TAO_PHandle, and version_.

Referenced by create_profile().

00157 {
00158   CORBA::ULong index = 0;
00159   TAO_Profile *pfile = 0;
00160   TAO_IIOP_Profile *iiop_profile = 0;
00161 
00162   // First see if <mprofile> already contains a IIOP profile.
00163   for (TAO_PHandle i = 0; i != mprofile.profile_count (); ++i)
00164     {
00165       pfile = mprofile.get_profile (i);
00166       if (pfile->tag () == IOP::TAG_INTERNET_IOP)
00167         {
00168           iiop_profile = dynamic_cast<TAO_IIOP_Profile *> (pfile);
00169           break;
00170         }
00171     }
00172 
00173   // If <mprofile> doesn't contain a IIOP_Profile, we need to create
00174   // one.
00175   if (iiop_profile == 0)
00176     {
00177       ACE_NEW_RETURN (iiop_profile,
00178                       TAO_IIOP_Profile (this->hosts_[0],
00179                                         this->addrs_[0].get_port_number (),
00180                                         object_key,
00181                                         this->addrs_[0],
00182                                         this->version_,
00183                                         this->orb_core_),
00184                       -1);
00185 
00186       iiop_profile->endpoint ()->priority (priority);
00187 
00188       if (mprofile.give_profile (iiop_profile) == -1)
00189         {
00190           iiop_profile->_decr_refcnt ();
00191           iiop_profile = 0;
00192           return -1;
00193         }
00194 
00195       // Do not add any tagged components to the profile if configured
00196       // by the user not to do so, or if an IIOP 1.0 endpoint is being
00197       // created (IIOP 1.0 did not support tagged components).
00198       if (this->orb_core_->orb_params ()->std_profile_components () != 0
00199           && (this->version_.major >= 1 && this->version_.minor >= 1))
00200         {
00201           iiop_profile->tagged_components ().set_orb_type (TAO_ORB_TYPE);
00202           TAO_Codeset_Manager *csm = this->orb_core_->codeset_manager();
00203           if (csm)
00204             csm->set_codeset(iiop_profile->tagged_components());
00205         }
00206 
00207       index = 1;
00208     }
00209 
00210   // Add any remaining acceptor endpoints to the IIOP_Profile.
00211   for (;
00212        index < this->endpoint_count_;
00213        ++index)
00214     {
00215       if (index > 0 &&
00216           this->addrs_[index].get_port_number() == this->addrs_[0].get_port_number() &&
00217           ACE_OS::strcmp(this->hosts_[index], this->hosts_[0]) == 0)
00218         continue;
00219 
00220       TAO_IIOP_Endpoint *endpoint = 0;
00221       ACE_NEW_RETURN (endpoint,
00222                       TAO_IIOP_Endpoint (this->hosts_[index],
00223                                          this->addrs_[index].get_port_number (),
00224                                          this->addrs_[index]),
00225                       -1);
00226       endpoint->priority (priority);
00227       iiop_profile->add_endpoint (endpoint);
00228     }
00229 
00230   return 0;
00231 }

const ACE_INET_Addr& TAO_IIOP_Acceptor::default_address void   )  const
 

Returns address for default endpoint.

Referenced by TAO_Acceptor_Registry::open_default(), and TAO_Acceptor_Registry::open_i().

int TAO_IIOP_Acceptor::dotted_decimal_address ACE_INET_Addr addr,
char *&  host
[protected]
 

Set the host name for the given address using the dotted decimal format.

Definition at line 787 of file IIOP_Acceptor.cpp.

References ACE_ERROR, ACE_TEXT, ACE_INET_Addr::get_host_addr(), ACE_INET_Addr::get_host_name(), ACE_INET_Addr::get_port_number(), ACE_Addr::get_type(), ACE_INET_Addr::is_any(), LM_ERROR, ACE_INET_Addr::set(), CORBA::string_dup(), and TAO_debug_level.

Referenced by hostname().

00789 {
00790   int result = 0;
00791   const char *tmp = 0;
00792 
00793   // If the IP address in the INET_Addr is the IN(6)ADDR_ANY address,
00794   // then force the actual IP address to be used by initializing a new
00795   // INET_Addr with the hostname from the original one.  If that fails
00796   // then something is seriously wrong with the systems networking
00797   // setup.
00798   if (addr.is_any ())
00799     {
00800       ACE_INET_Addr new_addr;
00801 #if defined (ACE_HAS_IPV6)
00802       result = new_addr.set (addr.get_port_number (),
00803                              addr.get_host_name (),
00804                              1, /* encode */
00805                              addr.get_type ());
00806 #else /* ACE_HAS_IPV6 */
00807       result = new_addr.set (addr.get_port_number (),
00808                              addr.get_host_name ());
00809 #endif /* !ACE_HAS_IPV6 */
00810       tmp = new_addr.get_host_addr ();
00811     }
00812   else
00813     tmp = addr.get_host_addr ();
00814 
00815   if (tmp == 0 || result != 0)
00816     {
00817       if (TAO_debug_level > 0)
00818         ACE_ERROR ((LM_ERROR,
00819                     ACE_TEXT ("TAO (%P|%t) - ")
00820                     ACE_TEXT ("IIOP_Acceptor::dotted_decimal_address, ")
00821                     ACE_TEXT ("- %p, "),
00822                     ACE_TEXT ("cannot determine hostname\n")));
00823       return -1;
00824     }
00825 
00826   host = CORBA::string_dup (tmp);
00827   return 0;
00828 }

CORBA::ULong TAO_IIOP_Acceptor::endpoint_count void   )  [virtual]
 

Returns the number of endpoints this acceptor is listening on. This is used for determining how many profiles will be generated for this acceptor.

Implements TAO_Acceptor.

Definition at line 1040 of file IIOP_Acceptor.cpp.

References endpoint_count_.

Referenced by TAO_IIOP_Transport::get_listen_point().

01041 {
01042   return this->endpoint_count_;
01043 }

const ACE_INET_Addr* TAO_IIOP_Acceptor::endpoints void   ) 
 

Returns the array of endpoints in this acceptor.

Referenced by TAO_IIOP_Transport::get_listen_point().

int TAO_IIOP_Acceptor::hostname TAO_ORB_Core orb_core,
ACE_INET_Addr addr,
char *&  host,
const char *  specified_hostname = 0
[virtual]
 

Set the host name for the given addr. A hostname may be forced by using specified_hostname. This is useful if the given address corresponds to more than one hostname and the desired one cannot be determined in any other way. This method is used both when constructing IOR endpoints and LPL (listen point lists).

The algorithm used is:

  • If hostname_in_ior_ has been set, it is used "as is";
  • else if use_dotted_decimal_addresses_ is set, the text representaion of the IP is used;
  • else if specified_hostname is given, it used "as is";
  • else a reverse (address to name) lookup is used to obtain the hostname or the IP if no reverse mapping exists.

Definition at line 592 of file IIOP_Acceptor.cpp.

References ACE_DEBUG, ACE_TEXT, dotted_decimal_address(), ACE_INET_Addr::get_host_name(), hostname_in_ior_, ACE_INET_Addr::is_ipv4_compat_ipv6(), LM_DEBUG, MAXHOSTNAMELEN, TAO_ORB_Core::orb_params(), CORBA::string_dup(), TAO_debug_level, and TAO_ORB_Parameters::use_dotted_decimal_addresses().

Referenced by TAO_IIOP_Transport::get_listen_point(), open(), and probe_interfaces().

00596 {
00597   if (this->hostname_in_ior_ != 0)
00598     {
00599       if (TAO_debug_level >= 5)
00600           ACE_DEBUG ((LM_DEBUG,
00601                       ACE_TEXT ("TAO (%P|%t) IIOP_Acceptor - ")
00602                       ACE_TEXT ("Overriding the hostname with <%s>\n"),
00603                       this->hostname_in_ior_));
00604 
00605       host = CORBA::string_dup (this->hostname_in_ior_);
00606     }
00607   else if (orb_core->orb_params ()->use_dotted_decimal_addresses ())
00608     {
00609       // If dotted decimal addresses are enabled,
00610       // just return ours.
00611       return this->dotted_decimal_address (addr, host);
00612     }
00613   else if (specified_hostname != 0)
00614     {
00615       // If the user specified a hostname, pass it back
00616       // blindly as it overrides our choice of hostname.
00617       host = CORBA::string_dup (specified_hostname);
00618     }
00619   else
00620     {
00621       char tmp_host[MAXHOSTNAMELEN + 1];
00622 
00623       // Get the hostname associated with our address
00624 #if defined (ACE_HAS_IPV6)
00625       // If we have a IPv4-compatible IPv6 address don't do hostname lookup
00626       // because that gets us into trouble. Most likely we get the same hostname
00627       // returned as for the actual IPv4 address but resolving that into an IPv6
00628       // address at the client will fail.
00629       if (addr.is_ipv4_compat_ipv6 () ||
00630           addr.get_host_name (tmp_host, sizeof (tmp_host)) != 0)
00631 #else /* ACE_HAS_IPV6 */
00632       if (addr.get_host_name (tmp_host, sizeof (tmp_host)) != 0)
00633 #endif /* !ACE_HAS_IPV6 */
00634         {
00635           // On failure, just return the decimal address.
00636           return this->dotted_decimal_address (addr, host);
00637         }
00638       else
00639         {
00640           host = CORBA::string_dup (tmp_host);
00641         }
00642     }
00643 
00644   return 0;
00645 }

int TAO_IIOP_Acceptor::is_collocated const TAO_Endpoint endpoint  )  [virtual]
 

Return 1 if the endpoint has the same address as the acceptor.

Implements TAO_Acceptor.

Definition at line 234 of file IIOP_Acceptor.cpp.

References addrs_, endpoint_count_, ACE_INET_Addr::get_port_number(), TAO_IIOP_Endpoint::host(), hosts_, TAO_IIOP_Endpoint::port(), and ACE_OS::strcmp().

00235 {
00236   const TAO_IIOP_Endpoint *endp =
00237     dynamic_cast<const TAO_IIOP_Endpoint *> (endpoint);
00238 
00239   // Make sure the dynamically cast pointer is valid.
00240   if (endp == 0)
00241     return 0;
00242 
00243   for (CORBA::ULong i = 0; i < this->endpoint_count_; ++i)
00244     {
00245       // compare the port and host name.  Please do *NOT* optimize
00246       // this code by comparing the IP address instead.  That would
00247       // trigger the following bug:
00248       //
00249       // http://deuce.doc.wustl.edu/bugzilla/show_bug.cgi?id=1220
00250       //
00251       if (endp->port() == this->addrs_[i].get_port_number()
00252           && ACE_OS::strcmp(endp->host(), this->hosts_[i]) == 0)
00253         return 1;
00254     }
00255 
00256   return 0;
00257 }

int TAO_IIOP_Acceptor::object_key IOP::TaggedProfile profile,
TAO::ObjectKey key
[virtual]
 

This method fetches the key from the profile. Protocols that are pluggable can send data that are specific in the profile_data field encapsulated as a octet stream. This method allows those protocols to get the object key from the encapsulation.

Implements TAO_Acceptor.

Definition at line 1046 of file IIOP_Acceptor.cpp.

References ACE_DEBUG, ACE_TEXT, LM_DEBUG, CORBA::Octet, TAO::String_var< charT >::out(), IOP::TaggedProfile::profile_data, ACE_InputCDR::read_octet(), ACE_InputCDR::read_string(), ACE_InputCDR::read_ushort(), CORBA::String_var, and TAO_debug_level.

01048 {
01049   // Create the decoding stream from the encapsulation in the buffer,
01050 #if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
01051   TAO_InputCDR cdr (profile.profile_data.mb ());
01052 #else
01053   TAO_InputCDR cdr (reinterpret_cast<char*> (profile.profile_data.get_buffer ()),
01054                     profile.profile_data.length ());
01055 #endif /* TAO_NO_COPY_OCTET_SEQUENCES == 1 */
01056 
01057   CORBA::Octet major;
01058   CORBA::Octet minor = CORBA::Octet();
01059 
01060   // Read the version. We just read it here. We don't*do any*
01061   // processing.
01062   if (!(cdr.read_octet (major)
01063         && cdr.read_octet (minor)))
01064     {
01065       if (TAO_debug_level > 0)
01066         {
01067           ACE_DEBUG ((LM_DEBUG,
01068                       ACE_TEXT ("TAO (%P|%t) - TAO_IIOP_Acceptor::object_key, v%d.%d\n"),
01069                       major,
01070                       minor));
01071         }
01072       return -1;
01073     }
01074 
01075   CORBA::String_var host;
01076   CORBA::UShort port = 0;
01077 
01078   // Get host and port. No processing here too..
01079   if (cdr.read_string (host.out ()) == 0
01080       || cdr.read_ushort (port) == 0)
01081     {
01082       if (TAO_debug_level > 0)
01083         {
01084           ACE_DEBUG ((LM_DEBUG,
01085                       ACE_TEXT ("TAO (%P|%t) - TAO_IIOP_Acceptor::object_key, ")
01086                       ACE_TEXT ("error while decoding host/port\n")));
01087         }
01088       return -1;
01089     }
01090 
01091   // ... and object key.
01092   if ((cdr >> object_key) == 0)
01093     return -1;
01094 
01095   // We are NOT bothered about the rest.
01096 
01097   return 1;
01098 }

int TAO_IIOP_Acceptor::open TAO_ORB_Core orb_core,
ACE_Reactor reactor,
int  version_major,
int  version_minor,
const char *  address,
const char *  options = 0
[virtual]
 

The TAO_Acceptor methods, check the documentation in Transport_Acceptor.h for details.

Implements TAO_Acceptor.

Definition at line 266 of file IIOP_Acceptor.cpp.

References ACE_CString, ACE_DEBUG, ACE_ERROR_RETURN, ACE_NEW_RETURN, ACE_TEXT, ACE_TEXT_CHAR_TO_TCHAR, addrs_, AF_UNSPEC, TAO_ORB_Parameters::connect_ipv6_only(), endpoint_count_, ACE_INET_Addr::get_port_number(), ACE_Addr::get_type(), hostname(), hostname_in_ior_, hosts_, ACE_INET_Addr::is_ipv4_mapped_ipv6(), LM_DEBUG, LM_ERROR, open_i(), TAO_ORB_Core::orb_params(), parse_address(), parse_options(), probe_interfaces(), ACE_INET_Addr::set(), TAO_GIOP_Message_Version::set_version(), TAO_debug_level, and version_.

00272 {
00273   if (TAO_debug_level > 2)
00274     {
00275       ACE_DEBUG ((LM_DEBUG,
00276                   ACE_TEXT ("TAO (%P|%t) - ")
00277                   ACE_TEXT ("IIOP_Acceptor::open, address==%s, options=%s\n"),
00278                   address, options));
00279     }
00280 
00281   this->orb_core_ = orb_core;
00282 
00283   if (this->hosts_ != 0)
00284     {
00285       // The hostname cache has already been set!
00286       // This is bad mojo, i.e. an internal TAO error.
00287       ACE_ERROR_RETURN ((LM_ERROR,
00288                          ACE_TEXT ("TAO (%P|%t) - ")
00289                          ACE_TEXT ("IIOP_Acceptor::open, ")
00290                          ACE_TEXT ("hostname already set\n\n")),
00291                         -1);
00292     }
00293 
00294   if (address == 0)
00295     return -1;
00296 
00297   if (major >=0 && minor >= 0)
00298     this->version_.set_version (static_cast<CORBA::Octet> (major),
00299                                 static_cast<CORBA::Octet> (minor));
00300   // Parse options
00301   if (this->parse_options (options) == -1)
00302     return -1;
00303 
00304   ACE_CString specified_hostname;
00305   ACE_INET_Addr addr;
00306   int def_type = AF_UNSPEC;
00307 
00308   if (this->parse_address (address,
00309                            addr,
00310                            specified_hostname,
00311                            &def_type) == -1)
00312     return -1;
00313 
00314   if (specified_hostname.length() == 0)
00315     {
00316       // The address is a port number or port name.  No hostname was
00317       // specified.  The hostname for each network interface and the
00318       // fully qualified domain name must be obtained.
00319 
00320       // Check for multiple network interfaces.
00321       if (this->probe_interfaces (orb_core, def_type) == -1)
00322         return -1;
00323 
00324       // Probe interfaces has a side effect of potentially modifying
00325       // the default address, since that is where the address family
00326       // is considered.
00327       addr.set(this->default_address_);
00328 
00329       return this->open_i (addr, reactor);
00330     }
00331 
00332 #if defined (ACE_HAS_IPV6)
00333   // Check for violation of ORBConnectIPV6Only option
00334   if (this->orb_core_->orb_params ()->connect_ipv6_only () &&
00335       (addr.get_type () != AF_INET6 ||
00336        addr.is_ipv4_mapped_ipv6 ()))
00337     {
00338       ACE_ERROR_RETURN ((LM_ERROR,
00339                          ACE_TEXT ("TAO (%P|%t) - ")
00340                          ACE_TEXT ("IIOP_Acceptor::open, ")
00341                          ACE_TEXT ("non-IPv6 endpoints not allowed when ")
00342                          ACE_TEXT ("connect_ipv6_only is set\n\n")),
00343                         -1);
00344     }
00345 #endif /* ACE_HAS_IPV6 */
00346 
00347   if (TAO_debug_level > 2)
00348     {
00349       ACE_DEBUG ((LM_DEBUG,
00350                   ACE_TEXT ("TAO (%P|%t) - ")
00351                   ACE_TEXT ("IIOP_Acceptor::open, specified host=%s:%d\n"),
00352                   (specified_hostname.length() == 0 ? "<null>" : specified_hostname.c_str()),
00353                   addr.get_port_number ()));
00354     }
00355 
00356   this->endpoint_count_ = 1;  // Only one hostname to store
00357 
00358   ACE_NEW_RETURN (this->addrs_,
00359                   ACE_INET_Addr[this->endpoint_count_],
00360                   -1);
00361 
00362   ACE_NEW_RETURN (this->hosts_,
00363                   char *[this->endpoint_count_],
00364                   -1);
00365 
00366   this->hosts_[0] = 0;
00367 
00368   if (this->hostname_in_ior_ != 0)
00369     {
00370       if (TAO_debug_level > 2)
00371         {
00372           ACE_DEBUG ((LM_DEBUG,
00373                       ACE_TEXT ("TAO (%P|%t) - ")
00374                       ACE_TEXT ("IIOP_Acceptor::open, ")
00375                       ACE_TEXT ("Overriding address in IOR with %s\n"),
00376                       ACE_TEXT_CHAR_TO_TCHAR (this->hostname_in_ior_)));
00377         }
00378       specified_hostname = this->hostname_in_ior_;
00379     }
00380 
00381   if (this->hostname (orb_core,
00382                       addr,
00383                       this->hosts_[0],
00384                       specified_hostname.c_str()) != 0)
00385     return -1;
00386 
00387   // Copy the addr.  The port is (re)set in
00388   // TAO_IIOP_Acceptor::open_i().
00389   if (this->addrs_[0].set (addr) != 0)
00390     return -1;
00391 
00392   return this->open_i (addr,
00393                        reactor);
00394 }

int TAO_IIOP_Acceptor::open_default TAO_ORB_Core orb_core,
ACE_Reactor reactor,
int  version_major,
int  version_minor,
const char *  options = 0
[virtual]
 

Open an acceptor with the given protocol version on a default endpoint

Implements TAO_Acceptor.

Definition at line 397 of file IIOP_Acceptor.cpp.

References ACE_ERROR_RETURN, ACE_TEXT, hosts_, LM_ERROR, open_i(), parse_options(), probe_interfaces(), ACE_INET_Addr::set(), TAO_GIOP_Message_Version::set_version(), and version_.

00402 {
00403   this->orb_core_ = orb_core;
00404 
00405   if (this->hosts_ != 0)
00406     {
00407       // The hostname cache has already been set!
00408       // This is bad mojo, i.e. an internal TAO error.
00409       ACE_ERROR_RETURN ((LM_ERROR,
00410                          ACE_TEXT ("TAO (%P|%t) - ")
00411                          ACE_TEXT ("IIOP_Acceptor::open_default, ")
00412                          ACE_TEXT ("hostname already set\n\n")),
00413                         -1);
00414     }
00415 
00416   if (major >= 0 && minor >= 0)
00417     this->version_.set_version (static_cast<CORBA::Octet> (major),
00418                                 static_cast<CORBA::Octet> (minor));
00419 
00420   // Parse options
00421   if (this->parse_options (options) == -1)
00422     return -1;
00423 
00424   // Check for multiple network interfaces.
00425   if (this->probe_interfaces (orb_core) == -1)
00426     return -1;
00427 
00428   // Now that each network interface's hostname has been cached, open
00429   // an endpoint on each network interface using the INADDR_ANY
00430   // address.
00431   ACE_INET_Addr addr;
00432 
00433   if (addr.set (this->default_address_) != 0)
00434     return -1;
00435 
00436   return this->open_i (addr, reactor);
00437 }

int TAO_IIOP_Acceptor::open_i const ACE_INET_Addr addr,
ACE_Reactor reactor
[protected, virtual]
 

Implement the common part of the open*() methods. This method is virtual to allow a derived class implementation to be invoked instead.

Definition at line 440 of file IIOP_Acceptor.cpp.

References ACE_Strategy_Acceptor< SVC_HANDLER, >::acceptor(), ACE_CLOEXEC, ACE_DEBUG, ACE_ERROR, ACE_MAX_DEFAULT_PORT, ACE_NEW_RETURN, ACE_TEXT, ACE_TEXT_CHAR_TO_TCHAR, addrs_, base_acceptor_, TAO_ORB_Parameters::connect_ipv6_only(), default_address_, endpoint_count_, ACE_INET_Addr::get_port_number(), ACE_INET_Addr::is_any(), LM_DEBUG, LM_ERROR, ACE_Strategy_Acceptor< SVC_HANDLER, >::open(), TAO_ORB_Core::orb_params(), port_span_, ACE_INET_Addr::set_port_number(), and TAO_debug_level.

Referenced by open(), and open_default().

00442 {
00443   ACE_NEW_RETURN (this->creation_strategy_,
00444                   CREATION_STRATEGY (this->orb_core_),
00445                   -1);
00446 
00447   ACE_NEW_RETURN (this->concurrency_strategy_,
00448                   CONCURRENCY_STRATEGY (this->orb_core_),
00449                   -1);
00450 
00451   ACE_NEW_RETURN (this->accept_strategy_,
00452                   ACCEPT_STRATEGY (this->orb_core_),
00453                   -1);
00454 
00455   unsigned short requested_port = addr.get_port_number ();
00456   if (requested_port == 0)
00457     {
00458       // don't care, i.e., let the OS choose an ephemeral port
00459       if (this->base_acceptor_.open (addr,
00460                                      reactor,
00461                                      this->creation_strategy_,
00462                                      this->accept_strategy_,
00463                                      this->concurrency_strategy_,
00464                                      0, 0, 0, 1,
00465                                      this->reuse_addr_) == -1)
00466         {
00467           if (TAO_debug_level > 0)
00468             ACE_DEBUG ((LM_DEBUG,
00469                         ACE_TEXT ("TAO (%P|%t) - IIOP_Acceptor::open_i, ")
00470                         ACE_TEXT ("%p, "),
00471                         ACE_TEXT ("cannot open acceptor\n")));
00472           return -1;
00473         }
00474     }
00475   else
00476     {
00477       ACE_INET_Addr a(addr);
00478 
00479       bool found_a_port = false;
00480       ACE_UINT32 last_port = requested_port + this->port_span_ - 1;
00481       if (last_port > ACE_MAX_DEFAULT_PORT)
00482         {
00483           last_port = ACE_MAX_DEFAULT_PORT;
00484         }
00485 
00486       for (ACE_UINT32 p = requested_port; p <= last_port; p++)
00487         {
00488           if (TAO_debug_level > 5)
00489             ACE_DEBUG ((LM_DEBUG,
00490                         ACE_TEXT ("TAO (%P|%t) - IIOP_Acceptor::open_i, ")
00491                         ACE_TEXT ("trying to listen on port %d\n"), p));
00492 
00493           // Now try to actually open on that port
00494           a.set_port_number ((u_short)p);
00495           if (this->base_acceptor_.open (a,
00496                                          reactor,
00497                                          this->creation_strategy_,
00498                                          this->accept_strategy_,
00499                                          this->concurrency_strategy_,
00500                                          0, 0, 0, 1,
00501                                          this->reuse_addr_) != -1)
00502             {
00503               found_a_port = true;
00504               break;
00505             }
00506         }
00507 
00508       // Now, if we couldn't locate a port, we punt
00509       if (! found_a_port)
00510         {
00511           if (TAO_debug_level > 0)
00512             ACE_DEBUG ((LM_DEBUG,
00513                         ACE_TEXT ("TAO (%P|%t) - IIOP_Acceptor::open_i, ")
00514                         ACE_TEXT ("cannot open acceptor in port range (%d,%d)")
00515                         ACE_TEXT ("- %p\n"),
00516                         requested_port, last_port, ACE_TEXT("")));
00517           return -1;
00518         }
00519     }
00520 
00521 #if defined (ACE_HAS_IPV6) && defined (ACE_HAS_IPV6_V6ONLY)
00522   // Check if need to prevent this acceptor from accepting connections
00523   // from IPv4 mapped IPv6 addresses
00524   if (this->orb_core_->orb_params ()->connect_ipv6_only () &&
00525       addr.is_any ())
00526   {
00527     if (TAO_debug_level > 5)
00528       ACE_DEBUG ((LM_DEBUG,
00529                   ACE_TEXT("TAO (%P|%t) - IIOP_Acceptor::open_i, ")
00530                   ACE_TEXT("setting IPV6_V6ONLY\n")));
00531 
00532     // Prevent server from accepting connections from IPv4-mapped addresses.
00533     int on = 1;
00534     if (this->base_acceptor_.acceptor ().set_option (IPPROTO_IPV6,
00535                                                      IPV6_V6ONLY,
00536                                                      (void *) &on,
00537                                                      sizeof (on)) == -1)
00538       {
00539         ACE_ERROR ((LM_ERROR,
00540                     ACE_TEXT ("TAO (%P|%t) - IIOP_Acceptor::open_i, ")
00541                     ACE_TEXT ("%p\n"),
00542                     ACE_TEXT ("cannot set IPV6_V6ONLY")));
00543       }
00544   }
00545 #endif /* ACE_HAS_IPV6 && ACE_HAS_IPV6_V6ONLY */
00546 
00547   ACE_INET_Addr address;
00548 
00549   // We do this make sure the port number the endpoint is listening on
00550   // gets set in the addr.
00551   if (this->base_acceptor_.acceptor ().get_local_addr (address) != 0)
00552     {
00553       if (TAO_debug_level > 0)
00554         ACE_ERROR ((LM_ERROR,
00555                     ACE_TEXT ("TAO (%P|%t) - IIOP_Acceptor::open_i, ")
00556                     ACE_TEXT ("%p"),
00557                     ACE_TEXT ("cannot get local addr\n")));
00558       return -1;
00559     }
00560 
00561   // Set the port for each addr.  If there is more than one network
00562   // interface then the endpoint created on each interface will be on
00563   // the same port.  This is how a wildcard socket bind() is supposed
00564   // to work.
00565   unsigned short port = address.get_port_number ();
00566   for (CORBA::ULong j = 0; j < this->endpoint_count_; ++j)
00567     this->addrs_[j].set_port_number (port, 1);
00568 
00569   this->default_address_.set_port_number (port);
00570 
00571   (void) this->base_acceptor_.acceptor().enable (ACE_CLOEXEC);
00572   // This avoids having child processes acquire the listen socket thereby
00573   // denying the server the opportunity to restart on a well-known endpoint.
00574   // This does not affect the aberrent behavior on Win32 platforms.
00575 
00576   if (TAO_debug_level > 5)
00577     {
00578       for (CORBA::ULong i = 0; i < this->endpoint_count_; ++i)
00579         {
00580           ACE_DEBUG ((LM_DEBUG,
00581                       ACE_TEXT ("TAO (%P|%t) - IIOP_Acceptor::open_i, ")
00582                       ACE_TEXT ("listening on: <%s:%u>\n"),
00583                       ACE_TEXT_CHAR_TO_TCHAR(this->hosts_[i]),
00584                       this->addrs_[i].get_port_number ()));
00585         }
00586     }
00587 
00588   return 0;
00589 }

int TAO_IIOP_Acceptor::parse_address const char *  address,
ACE_INET_Addr addr,
ACE_CString specified_hostname,
int *  def_type = 0
[protected]
 

Helper method Clear out 'addr' & 'specified_hostname' and initialize them based upon 'address'. If a non-zero pointer is passed in for def_type, this will be set to AF_INET6 if IPv6 support is enabled and supplied hostname is either [] or [::]. It will be set to AF_INET if the hostname is 0.0.0.0, otherwise it is set to AF_UNSPEC. This value is then passed to probe_interfaces by open.

Definition at line 649 of file IIOP_Acceptor.cpp.

References ACE_ERROR_RETURN, ACE_TEXT, AF_INET, AF_UNSPEC, ACE_OS::atoi(), default_address_, ACE_INET_Addr::is_any(), LM_ERROR, TAO_GIOP_Message_Version::major, MAXHOSTNAMELEN, ACE_OS::memcpy(), TAO_GIOP_Message_Version::minor, ACE_INET_Addr::set(), ACE_INET_Addr::set_port_number(), ACE_OS::strchr(), ACE_OS::strcpy(), TAO_MIN_IPV6_IIOP_MAJOR, TAO_MIN_IPV6_IIOP_MINOR, and version_.

Referenced by open().

00653 {
00654   {
00655     ACE_INET_Addr tmp;
00656     addr.set (tmp);
00657     specified_hostname.clear();
00658   }
00659 
00660   const char *port_separator_loc = ACE_OS::strchr (address, ':');
00661   char tmp_host[MAXHOSTNAMELEN + 1];
00662   tmp_host[0] = '\0';
00663   bool host_defaulted = port_separator_loc == address;
00664   bool ipv6_in_host = false;
00665   if (def_type)
00666     *def_type = AF_UNSPEC;
00667 
00668 #if defined (ACE_HAS_IPV6)
00669   // Check if this is a (possibly) IPv6 supporting profile containing a
00670   // numeric IPv6 address representation.
00671   if ((this->version_.major > TAO_MIN_IPV6_IIOP_MAJOR ||
00672         this->version_.minor >= TAO_MIN_IPV6_IIOP_MINOR) &&
00673       address[0] == '[')
00674     {
00675       // In this case we have to find the end of the numeric address and
00676       // start looking for the port separator from there.
00677       char const * const cp_pos = ACE_OS::strchr (address, ']');
00678       if (cp_pos == 0)
00679         {
00680           // No valid IPv6 address specified.
00681           ACE_ERROR_RETURN ((LM_ERROR,
00682                              ACE_TEXT ("TAO (%P|%t) - ")
00683                              ACE_TEXT ("IIOP_Acceptor::open, ")
00684                              ACE_TEXT ("Invalid IPv6 decimal address specified\n\n")),
00685                             -1);
00686         }
00687       else
00688         {
00689           // Extract out just the host part of the address.
00690           size_t const len = cp_pos - (address + 1);
00691 
00692           if (len >= sizeof (tmp_host))
00693             return -1;
00694 
00695           ipv6_in_host = true;
00696           host_defaulted = (cp_pos == address+1) ||
00697             (cp_pos == address+3 && address[1] == ':' && address[2] == ':');
00698           if (cp_pos[1] == ':')    // Look for a port
00699             port_separator_loc = cp_pos + 1;
00700           else
00701             port_separator_loc = 0;
00702           if (def_type)
00703             *def_type = AF_INET6;
00704 
00705           ACE_OS::memcpy (tmp_host, address + 1, len);
00706           tmp_host[len] = '\0';
00707         }
00708     }
00709   else
00710 #endif /* ACE_HAS_IPV6 */
00711     if (!host_defaulted)
00712       {
00713         if (port_separator_loc != 0)
00714           {
00715             // Extract out just the host part of the address.
00716             size_t const len = port_separator_loc - address;
00717 
00718             if (len >= sizeof (tmp_host))
00719               return -1;
00720 
00721             ACE_OS::memcpy (tmp_host, address, len);
00722             tmp_host[len] = '\0';
00723           }
00724         else
00725           ACE_OS::strcpy (tmp_host, address);
00726       }
00727 
00728   if (!ipv6_in_host && !host_defaulted)
00729     {
00730       if (addr.set((unsigned short)0,tmp_host) != 0)
00731         return -1;
00732       this->default_address_.set(addr);
00733       host_defaulted = addr.is_any();
00734       if (def_type)
00735         *def_type = AF_INET;
00736     }
00737 
00738   if (host_defaulted)
00739     {
00740       // First convert the port into a usable form.
00741       unsigned short portno = 0;
00742       if (port_separator_loc != 0)
00743         {
00744           portno =
00745             static_cast<u_short> (ACE_OS::atoi (port_separator_loc +
00746                                                 sizeof (':')));
00747         }
00748       this->default_address_.set_port_number (portno);
00749 
00750       // Now reset the port and set the host.
00751       if (addr.set (this->default_address_) != 0)
00752         return -1;
00753     }
00754   else if (port_separator_loc == 0)
00755     {
00756       // The address is a hostname.  No port was specified, so assume
00757       // port zero (port will be chosen for us).
00758       specified_hostname = tmp_host[0] == '\0' ? address : tmp_host;
00759       if (addr.set ((unsigned short) 0,
00760                     specified_hostname.c_str()) != 0)
00761         return -1;
00762     }
00763   else
00764     {
00765       // Host and port were specified.
00766       if (addr.set (address) != 0)
00767         return -1;
00768       if (tmp_host[0] == '\0')
00769         {
00770           // Extract out just the host part of the address.
00771           size_t const len = port_separator_loc - address;
00772 
00773           if (len >= sizeof (tmp_host))
00774             return -1;
00775 
00776           ACE_OS::memcpy (tmp_host, address, len);
00777           tmp_host[len] = '\0';
00778         }
00779       specified_hostname = tmp_host;
00780     }
00781 
00782   return 1;
00783 }

int TAO_IIOP_Acceptor::parse_options const char *  options  )  [protected]
 

Parse protocol specific options.

Currently supported: portspan -- specifies the range of ports over which the acceptor should scan looking for a free port (this is convenient for situations where you might normally use an ephemeral port but can't because you're behind a firewall and don't want to permit passage on all ephemeral ports)

Definition at line 1101 of file IIOP_Acceptor.cpp.

References ACE_CString, ACE_ERROR, ACE_NEW_RETURN, ACE_TEXT, LM_ERROR, and parse_options_i().

Referenced by open(), and open_default().

01102 {
01103   if (str == 0)
01104     return 0;  // No options to parse.  Not a problem.
01105 
01106   // Use an option format similar to the one used for CGI scripts in
01107   // HTTP URLs.
01108   // e.g.:  option1=foo&option2=bar
01109 
01110   const ACE_CString options (str);
01111 
01112   const size_t len = options.length ();
01113 
01114   static const char option_delimiter = '&';
01115 
01116   // Count the number of options.
01117   int argc = 1;
01118 
01119   for (size_t i = 0; i < len; ++i)
01120     if (options[i] == option_delimiter)
01121       argc++;
01122 
01123   // The idea behind the following loop is to split the options into
01124   // (option, name) pairs.
01125   // For example,
01126   //    `option1=foo&option2=bar'
01127   // will be parsed into:
01128   //    `option1=foo'
01129   //    `option2=bar'
01130 
01131   ACE_CString *argv_base = 0;
01132   ACE_NEW_RETURN (argv_base, ACE_CString[argc],-1);
01133   ACE_CString **argv = 0;
01134   ACE_NEW_RETURN (argv, ACE_CString*[argc],-1);
01135 
01136   ACE_CString::size_type begin = 0;
01137   ACE_CString::size_type end = 0;
01138   int result = 0;
01139   for (int j = 0; j < argc; ++j)
01140     {
01141       if (j < argc - 1)
01142         end = options.find (option_delimiter, begin);
01143       else
01144         end = len;
01145 
01146       if (end == begin)
01147         {
01148           ACE_ERROR ((LM_ERROR,
01149                       ACE_TEXT ("TAO (%P|%t) - Zero length IIOP option.\n")));
01150           result = -1;
01151           break;
01152         }
01153       else if (end != options.npos)
01154         {
01155           argv_base[j] = options.substring (begin, end - begin);
01156           argv[j] = &argv_base[j];
01157           begin = end + 1;
01158         }
01159       else
01160         {
01161           break;  // No other options.
01162         }
01163     }
01164 
01165   if (result == 0)
01166     result = this->parse_options_i (argc,argv);
01167 
01168   if (argc > 0)
01169     {
01170       ACE_ERROR ((LM_ERROR,
01171                   ACE_TEXT ("TAO (%P|%t) - IIOP")
01172                   ACE_TEXT (" endpoint has %d unknown options:\n"),
01173                   argc));
01174       for (int i = 0; i < argc; i++)
01175         ACE_ERROR ((LM_ERROR,
01176                     ACE_TEXT("\t%s\n"),
01177                     argv[i]->c_str()));
01178       result = -1;
01179     }
01180   delete [] argv;
01181   delete [] argv_base;
01182   return result;
01183 }

int TAO_IIOP_Acceptor::parse_options_i int &  argc,
ACE_CString **  argv
[protected, virtual]
 

Parse options splits the options list in to an argv array. This allows manipulation of the list in a manner similar to orb_init. By moving the consumed args to the tail of the list and reducing the argc count, the base parse_options_i can be called by derived parse_options_i. Method returns -1 if an ill-formed or otherwise bogus arg is encountered. The only strictly bogus arg was priority, which was a holdover from the early RT IIOP implementations. an ill-formed option is one which is missing an equal sign or something to the left of it.

Definition at line 1186 of file IIOP_Acceptor.cpp.

References ACE_CString, ACE_ERROR_RETURN, ACE_MAX_DEFAULT_PORT, ACE_TEXT, ACE_TEXT_CHAR_TO_TCHAR, ACE_OS::atoi(), hostname_in_ior_, LM_ERROR, and port_span_.

Referenced by parse_options().

01188 {
01189   int i = 0;
01190   while (i < argc)
01191     {
01192       ACE_CString::size_type const len  = argv[i]->length ();
01193       ACE_CString::size_type const slot = argv[i]->find ('=');
01194 
01195       if (slot == len - 1
01196           || slot == ACE_CString::npos)
01197         ACE_ERROR_RETURN ((LM_ERROR,
01198                            ACE_TEXT ("TAO (%P|%t) - IIOP option <%s> is ")
01199                            ACE_TEXT ("missing a value.\n"),
01200                            ACE_TEXT_CHAR_TO_TCHAR(argv[i]->c_str ())),
01201                           -1);
01202 
01203       ACE_CString name = argv[i]->substring (0, slot);
01204       ACE_CString value = argv[i]->substring (slot + 1);
01205 
01206       if (name.length () == 0)
01207         ACE_ERROR_RETURN ((LM_ERROR,
01208                            ACE_TEXT ("TAO (%P|%t) Zero length IIOP ")
01209                            ACE_TEXT ("option name.\n")),
01210                           -1);
01211       if (name == "portspan")
01212         {
01213           int range = static_cast <int> (ACE_OS::atoi (value.c_str ()));
01214           // @@ What's the lower bound on the range?  zero, or one?
01215           if (range < 1 || range > ACE_MAX_DEFAULT_PORT)
01216             ACE_ERROR_RETURN ((LM_ERROR,
01217                                ACE_TEXT ("TAO (%P|%t) Invalid IIOP endpoint ")
01218                                ACE_TEXT ("portspan: <%s>\n")
01219                                ACE_TEXT ("Valid range 1 -- %d\n"),
01220                                value.c_str (), ACE_MAX_DEFAULT_PORT),
01221                               -1);
01222 
01223           this->port_span_ = static_cast <u_short> (range);
01224         }
01225       else if (name == "hostname_in_ior")
01226         {
01227           this->hostname_in_ior_ = value.rep ();
01228         }
01229       else if (name == "reuse_addr")
01230         {
01231           this->reuse_addr_ = ACE_OS::atoi (value.c_str ());
01232         }
01233       else
01234         {
01235           // the name is not known, skip to the next option
01236           ++i;
01237           continue;
01238         }
01239       // at the end, we've consumed this argument. Shift the list and
01240       // put this one on the end. This technique has the effect of
01241       // putting them in reverse order, but that doesn't matter, since
01242       // these arguments are only whole strings.
01243       --argc;
01244       ACE_CString *temp = argv[i];
01245       for (int j = i; j <= argc-1; ++j)
01246         argv[j] = argv[j+1];
01247       argv[argc] = temp;
01248     }
01249   return 0;
01250 }

int TAO_IIOP_Acceptor::probe_interfaces TAO_ORB_Core orb_core,
int  def_type = AF_UNSPEC
[protected]
 

Probe the system for available network interfaces, and initialize the array with an ACE_INET_Addr for each network interface. The port for each initialized ACE_INET_Addr will be set in the open_i() method. This method only gets invoked when no explicit hostname is provided in the specified endpoint.

The optional argument def_type is used to constrain the resulting list of interfaces to be either only IPv6 or IPv4, or both, when ACE_HAS_IPV6 is enabled and the source endpoint was an explicitly declared wildcard.

Definition at line 831 of file IIOP_Acceptor.cpp.

References ACE_DEBUG, ACE_NEW_RETURN, ACE_TEXT, addrs_, AF_INET, TAO_ORB_Parameters::connect_ipv6_only(), default_address_, endpoint_count_, ENOTSUP, ACE::get_ip_interfaces(), ACE_Addr::get_type(), hostname(), ACE_INET_Addr::is_ipv4_mapped_ipv6(), ACE_INET_Addr::is_linklocal(), ACE_INET_Addr::is_loopback(), LM_DEBUG, LM_WARNING, ACE_OS::memset(), TAO_ORB_Core::orb_params(), ACE_INET_Addr::set(), TAO_debug_level, and TAO_ORB_Parameters::use_ipv6_link_local().

Referenced by open(), and open_default().

00832 {
00833   // Extract the hostname for each network interface, and then cache
00834   // it.  The hostnames will then be used when creating a
00835   // TAO_IIOP_Profile for each endpoint setup on the probed
00836   // network interfaces.
00837   ACE_INET_Addr *if_addrs = 0;
00838   size_t if_cnt = 0;
00839 
00840   if (ACE::get_ip_interfaces (if_cnt, if_addrs) != 0
00841       && errno != ENOTSUP)
00842     {
00843       // In the case where errno == ENOTSUP, if_cnt and if_addrs will
00844       // not be modified, and will each remain equal to zero.  This
00845       // causes the default interface to be used.
00846       return -1;
00847     }
00848 
00849   if (if_cnt == 0 || if_addrs == 0)
00850     {
00851       if (TAO_debug_level > 0)
00852         {
00853           ACE_DEBUG ((LM_WARNING,
00854                       ACE_TEXT ("TAO (%P|%t) - Unable to probe network ")
00855                       ACE_TEXT ("interfaces. Using default.\n")));
00856         }
00857 
00858       if_cnt = 1; // Force the network interface count to be one.
00859       delete [] if_addrs;
00860       ACE_NEW_RETURN (if_addrs,
00861                       ACE_INET_Addr[if_cnt],
00862                       -1);
00863     }
00864 
00865   // Scan for the loopback interface since it shouldn't be included in
00866   // the list of cached hostnames unless it is the only interface.
00867   size_t lo_cnt = 0;  // Loopback interface count
00868   for (size_t j = 0; j < if_cnt; ++j)
00869     if (if_addrs[j].is_loopback ())
00870       ++lo_cnt;
00871 
00872 #if defined (ACE_HAS_IPV6)
00873   size_t ipv4_cnt = 0;
00874   size_t ipv4_lo_cnt = 0;
00875   size_t ipv6_ll = 0;
00876   bool ipv6_non_ll = false;
00877   // Scan for IPv4 interfaces since these should not be included
00878   // when IPv6-only is selected.
00879   for (size_t j = 0; j < if_cnt; ++j)
00880     if (if_addrs[j].get_type () != AF_INET6 ||
00881         if_addrs[j].is_ipv4_mapped_ipv6 ())
00882       {
00883         ++ipv4_cnt;
00884         if (if_addrs[j].is_loopback ())
00885           ++ipv4_lo_cnt;  // keep track of IPv4 loopback ifs
00886       }
00887     else if (!if_addrs[j].is_linklocal () &&
00888              !if_addrs[j].is_loopback())
00889       {
00890         ipv6_non_ll = true; // we have at least 1 non-local IPv6 if
00891       }
00892     else if (!orb_core->orb_params ()->use_ipv6_link_local () &&
00893              if_addrs[j].is_linklocal ())
00894       {
00895         ++ipv6_ll;  // count link local addrs to exclude them afterwards
00896       }
00897 #endif /* ACE_HAS_IPV6 */
00898 
00899   // The instantiation for this template is in
00900   // tao/IIOP_Connector.cpp.
00901   ACE_Auto_Basic_Array_Ptr<ACE_INET_Addr> safe_if_addrs (if_addrs);
00902 
00903 #if defined (ACE_HAS_IPV6)
00904   bool ipv4_only = def_type == AF_INET;
00905   bool ipv6_only = (def_type == AF_INET6) ||
00906     orb_core->orb_params ()->connect_ipv6_only ();
00907 #if defined (ACE_WIN32)
00908   if (this->default_address_.get_type () == AF_INET)
00909     ipv4_only = true;
00910   else
00911     ipv6_only = true;
00912 #endif /* ACE_WIN32 */
00913   // If the loopback interface is the only interface then include it
00914   // in the list of interfaces to query for a hostname, otherwise
00915   // exclude it from the list.
00916   bool ignore_lo;
00917   if (ipv6_only)
00918     // only exclude loopback if non-local if exists
00919     ignore_lo = ipv6_non_ll;
00920   else if (ipv4_only)
00921     ignore_lo = ipv4_cnt != ipv4_lo_cnt;
00922   else
00923     ignore_lo = if_cnt != lo_cnt;
00924 
00925   // Adjust counts for IPv6 only if required
00926   size_t if_ok_cnt = if_cnt;
00927   if (ipv6_only)
00928     {
00929       if_ok_cnt -= ipv4_cnt;
00930       lo_cnt -= ipv4_lo_cnt;
00931       ipv4_lo_cnt = 0;
00932     }
00933   else if (ipv4_only)
00934     {
00935       if_ok_cnt = ipv4_cnt;
00936       lo_cnt = ipv4_lo_cnt;
00937       ipv6_ll = 0;
00938     }
00939 
00940   // In case there are no non-local IPv6 ifs in the list only exclude
00941   // IPv4 loopback.
00942   // IPv6 loopback will be needed to successfully connect IPv6 clients
00943   // in a localhost environment.
00944   if (!ipv4_only && !ipv6_non_ll)
00945     lo_cnt = ipv4_lo_cnt;
00946 
00947   if (!ignore_lo)
00948     this->endpoint_count_ = static_cast<CORBA::ULong> (if_ok_cnt - ipv6_ll);
00949   else
00950     this->endpoint_count_ = static_cast<CORBA::ULong> (if_ok_cnt - ipv6_ll - lo_cnt);
00951 #else /* ACE_HAS_IPV6 */
00952   // If the loopback interface is the only interface then include it
00953   // in the list of interfaces to query for a hostname, otherwise
00954   // exclude it from the list.
00955   bool ignore_lo;
00956   ignore_lo = if_cnt != lo_cnt;
00957   if (!ignore_lo)
00958     this->endpoint_count_ = static_cast<CORBA::ULong> (if_cnt);
00959   else
00960     this->endpoint_count_ = static_cast<CORBA::ULong> (if_cnt - lo_cnt);
00961 #endif /* !ACE_HAS_IPV6 */
00962 
00963   if (this->endpoint_count_ == 0)
00964     {
00965       if (TAO_debug_level > 0)
00966         ACE_DEBUG ((LM_DEBUG,
00967                     ACE_TEXT("(%P|%t) TAO_IIOP_Acceptor::probe_interfaces ")
00968                     ACE_TEXT("found no usable addresses, def_type = %d\n"),
00969                     def_type));
00970       return -1;
00971     }
00972 
00973   ACE_NEW_RETURN (this->addrs_,
00974                   ACE_INET_Addr[this->endpoint_count_],
00975                   -1);
00976 
00977   ACE_NEW_RETURN (this->hosts_,
00978                   char *[this->endpoint_count_],
00979                   -1);
00980 
00981   ACE_OS::memset (this->hosts_, 0, sizeof (char*) * this->endpoint_count_);
00982 
00983   // The number of hosts/interfaces we want to cache may not be the
00984   // same as the number of detected interfaces so keep a separate
00985   // count.
00986   size_t host_cnt = 0;
00987 
00988   for (size_t i = 0; i < if_cnt; ++i)
00989     {
00990 #if defined (ACE_HAS_IPV6)
00991       // Ignore any loopback interface if there are other
00992       // non-loopback interfaces.
00993       if (ignore_lo &&
00994           if_addrs[i].is_loopback () &&
00995           (ipv4_only ||
00996            ipv6_non_ll ||
00997            if_addrs[i].get_type () != AF_INET6))
00998         continue;
00999 
01000       // Ignore any non-IPv4 interfaces when so required.
01001       if (ipv4_only &&
01002           (if_addrs[i].get_type () != AF_INET))
01003         continue;
01004 
01005       // Ignore any non-IPv6 interfaces when so required.
01006       if (ipv6_only &&
01007           (if_addrs[i].get_type () != AF_INET6 ||
01008            if_addrs[i].is_ipv4_mapped_ipv6 ()))
01009         continue;
01010 
01011       // Ignore all IPv6 link local interfaces when so required.
01012       if (!orb_core->orb_params ()->use_ipv6_link_local () &&
01013           if_addrs[i].is_linklocal ())
01014         continue;
01015 #else /* ACE_HAS_IPV6 */
01016       // Ignore any loopback interface if there are other
01017       // non-loopback interfaces.
01018       if (ignore_lo &&
01019           if_addrs[i].is_loopback ())
01020         continue;
01021 #endif /* !ACE_HAS_IPV6 */
01022 
01023       if (this->hostname (orb_core,
01024                           if_addrs[i],
01025                           this->hosts_[host_cnt]) != 0)
01026         return -1;
01027 
01028       // Copy the addr.  The port is (re)set in
01029       // TAO_IIOP_Acceptor::open_i().
01030       if (this->addrs_[host_cnt].set (if_addrs[i]) != 0)
01031         return -1;
01032 
01033       ++host_cnt;
01034     }
01035 
01036   return 0;
01037 }

void TAO_IIOP_Acceptor::set_default_address const ACE_INET_Addr addr  ) 
 

Set address for default endpoint.

Referenced by TAO_Acceptor_Registry::open_default(), and TAO_Acceptor_Registry::open_i().


Member Data Documentation

ACCEPT_STRATEGY* TAO_IIOP_Acceptor::accept_strategy_ [private]
 

Definition at line 272 of file IIOP_Acceptor.h.

ACE_INET_Addr* TAO_IIOP_Acceptor::addrs_ [protected]
 

Array of ACE_INET_Addr instances, each one corresponding to a given network interface.

Definition at line 221 of file IIOP_Acceptor.h.

Referenced by create_new_profile(), create_shared_profile(), is_collocated(), open(), open_i(), probe_interfaces(), and ~TAO_IIOP_Acceptor().

BASE_ACCEPTOR TAO_IIOP_Acceptor::base_acceptor_ [private]
 

The concrete acceptor, as a pointer to it's base class.

Definition at line 267 of file IIOP_Acceptor.h.

Referenced by close(), and open_i().

CONCURRENCY_STRATEGY* TAO_IIOP_Acceptor::concurrency_strategy_ [private]
 

Definition at line 271 of file IIOP_Acceptor.h.

CREATION_STRATEGY* TAO_IIOP_Acceptor::creation_strategy_ [private]
 

Acceptor strategies.

Definition at line 270 of file IIOP_Acceptor.h.

ACE_INET_Addr TAO_IIOP_Acceptor::default_address_ [protected]
 

Address for default endpoint.

Definition at line 262 of file IIOP_Acceptor.h.

Referenced by open_i(), parse_address(), and probe_interfaces().

CORBA::ULong TAO_IIOP_Acceptor::endpoint_count_ [protected]
 

The number of host names cached in the hosts_ array (equivalent to the number of endpoints opened by this Acceptor).

Definition at line 246 of file IIOP_Acceptor.h.

Referenced by create_new_profile(), create_profile(), create_shared_profile(), endpoint_count(), is_collocated(), open(), open_i(), probe_interfaces(), and ~TAO_IIOP_Acceptor().

char* TAO_IIOP_Acceptor::hostname_in_ior_ [protected]
 

Override the hostname used in the ORBEndPoint.

Definition at line 242 of file IIOP_Acceptor.h.

Referenced by hostname(), open(), parse_options_i(), and ~TAO_IIOP_Acceptor().

char** TAO_IIOP_Acceptor::hosts_ [protected]
 

Cache the information about the endpoints serviced by this acceptor. There may in fact be multiple hostnames for this endpoint. For example, if the IP address is INADDR_ANY (0.0.0.0) then there will be possibly a different hostname for each interface.

Definition at line 237 of file IIOP_Acceptor.h.

Referenced by is_collocated(), open(), open_default(), and ~TAO_IIOP_Acceptor().

TAO_ORB_Core* TAO_IIOP_Acceptor::orb_core_ [protected]
 

ORB Core.

Definition at line 256 of file IIOP_Acceptor.h.

unsigned short TAO_IIOP_Acceptor::port_span_ [protected]
 

The number of ports over which the acceptor should search (starting at the port specified in each element of addrs_) for an available port. This is specified via the "portspan=" option to the endpoint.

Definition at line 228 of file IIOP_Acceptor.h.

Referenced by open_i(), and parse_options_i().

int TAO_IIOP_Acceptor::reuse_addr_ [protected]
 

Enable socket option SO_REUSEADDR to be set.

Definition at line 259 of file IIOP_Acceptor.h.

TAO_GIOP_Message_Version TAO_IIOP_Acceptor::version_ [protected]
 

The GIOP version for this endpoint @ Theoretically they shouldn't be here!! We need to look at a way to move this out

Definition at line 253 of file IIOP_Acceptor.h.

Referenced by create_new_profile(), create_shared_profile(), open(), open_default(), and parse_address().


The documentation for this class was generated from the following files:
Generated on Sun Jan 27 13:14:49 2008 for TAO by doxygen 1.3.6