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 TAO_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 TAO_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.

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_ (this),
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 accept_strategy_, close(), concurrency_strategy_, creation_strategy_, 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

Referenced by open_i().

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, >::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, TAO_IIOP_Profile::endpoint(), TAO_MProfile::give_profile(), TAO_MProfile::grow(), TAO_Endpoint::priority(), TAO_MProfile::profile_count(), TAO_Codeset_Manager::set_codeset(), TAO_Tagged_Components::set_orb_type(), TAO_MProfile::size(), ACE_OS::strcmp(), TAO_Profile::tagged_components(), TAO_ORB_TYPE, and version_.

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_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(), TAO_IIOP_Profile::endpoint(), TAO_MProfile::get_profile(), TAO_MProfile::give_profile(), TAO_Endpoint::priority(), TAO_MProfile::profile_count(), TAO_Codeset_Manager::set_codeset(), TAO_Tagged_Components::set_orb_type(), ACE_OS::strcmp(), TAO_Profile::tag(), TAO_Profile::tagged_components(), TAO_ORB_TYPE, 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 793 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, CORBA::string_dup(), and TAO_debug_level.

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

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 1046 of file IIOP_Acceptor.cpp.

Referenced by TAO_IIOP_Transport::get_listen_point().

01047 {
01048   return this->endpoint_count_;
01049 }

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:

Definition at line 598 of file IIOP_Acceptor.cpp.

References ACE_DEBUG, ACE_TEXT, ACE_INET_Addr::get_host_name(), 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().

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

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 TAO_IIOP_Endpoint::host(), 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 1052 of file IIOP_Acceptor.cpp.

References ACE_DEBUG, ACE_TEXT, LM_DEBUG, and TAO_debug_level.

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

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_DEBUG, ACE_ERROR_RETURN, ACE_NEW_RETURN, ACE_TEXT, ACE_TEXT_CHAR_TO_TCHAR, AF_UNSPEC, ACE_String_Base< CHAR >::c_str(), ACE_INET_Addr::get_port_number(), ACE_Addr::get_type(), ACE_String_Base< CHAR >::length(), LM_DEBUG, LM_ERROR, open_i(), 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, reactor);
00393 }

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 396 of file IIOP_Acceptor.cpp.

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

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

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 439 of file IIOP_Acceptor.cpp.

References ACE_CLOEXEC, ACE_DEBUG, ACE_ERROR, ACE_MAX_DEFAULT_PORT, ACE_NEW_RETURN, ACE_TEXT, ACE_TEXT_CHAR_TO_TCHAR, address(), default_address_, ACE_INET_Addr::get_port_number(), ACE_INET_Addr::is_any(), LM_DEBUG, LM_ERROR, TAO_Acceptor::set_error_retry_delay(), ACE_INET_Addr::set_port_number(), and TAO_debug_level.

Referenced by open(), and open_default().

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

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 655 of file IIOP_Acceptor.cpp.

References ACE_ERROR_RETURN, ACE_TEXT, AF_INET, AF_UNSPEC, ACE_OS::atoi(), ACE_String_Base< CHAR >::c_str(), ACE_String_Base< CHAR >::clear(), default_address_, ACE_INET_Addr::is_any(), LM_ERROR, MAXHOSTNAMELEN, ACE_OS::memcpy(), ACE_INET_Addr::set(), ACE_INET_Addr::set_port_number(), ACE_OS::strchr(), and ACE_OS::strcpy().

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

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 1107 of file IIOP_Acceptor.cpp.

References ACE_ERROR, ACE_NEW_RETURN, ACE_TEXT, ACE_String_Base< CHAR >::find(), ACE_String_Base< CHAR >::length(), LM_ERROR, ACE_String_Base_Const::npos, parse_options_i(), and ACE_String_Base< CHAR >::substring().

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

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 1192 of file IIOP_Acceptor.cpp.

References ACE_ERROR_RETURN, ACE_MAX_DEFAULT_PORT, ACE_TEXT, ACE_TEXT_CHAR_TO_TCHAR, ACE_OS::atoi(), ACE_String_Base< CHAR >::c_str(), ACE_String_Base< CHAR >::find(), ACE_String_Base< CHAR >::length(), LM_ERROR, ACE_String_Base_Const::npos, ACE_String_Base< CHAR >::rep(), and ACE_String_Base< CHAR >::substring().

Referenced by parse_options().

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

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 <addrs_> 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 837 of file IIOP_Acceptor.cpp.

References ACE_DEBUG, ACE_NEW_RETURN, ACE_TEXT, AF_INET, ENOTSUP, ACE::get_ip_interfaces(), LM_DEBUG, LM_WARNING, ACE_OS::memset(), TAO_ORB_Core::orb_params(), and TAO_debug_level.

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

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.

Referenced by ~TAO_IIOP_Acceptor().

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.

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().

CONCURRENCY_STRATEGY* TAO_IIOP_Acceptor::concurrency_strategy_ [private]

Definition at line 271 of file IIOP_Acceptor.h.

Referenced by ~TAO_IIOP_Acceptor().

CREATION_STRATEGY* TAO_IIOP_Acceptor::creation_strategy_ [private]

Acceptor strategies.

Definition at line 270 of file IIOP_Acceptor.h.

Referenced by ~TAO_IIOP_Acceptor().

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(), and parse_address().

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.

char* TAO_IIOP_Acceptor::hostname_in_ior_ [protected]

Override the hostname used in the ORBEndPoint.

Definition at line 242 of file IIOP_Acceptor.h.

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.

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.

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(), and open_default().


The documentation for this class was generated from the following files:
Generated on Tue Feb 2 17:39:31 2010 for TAO by  doxygen 1.4.7