#include <IIOP_Acceptor.h>
Inheritance diagram for TAO_IIOP_Acceptor:
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_Addr & | address (void) const |
const ACE_INET_Addr * | endpoints (void) |
Returns the array of endpoints in this acceptor. | |
const ACE_INET_Addr & | default_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_Addr * | addrs_ |
unsigned short | port_span_ |
char ** | hosts_ |
char * | hostname_in_ior_ |
CORBA::ULong | endpoint_count_ |
TAO_GIOP_Message_Version | version_ |
TAO_ORB_Core * | orb_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_STRATEGY * | creation_strategy_ |
Acceptor strategies. | |
CONCURRENCY_STRATEGY * | concurrency_strategy_ |
ACCEPT_STRATEGY * | accept_strategy_ |
The IIOP-specific bridge class for the concrete acceptor.
Definition at line 48 of file IIOP_Acceptor.h.
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.
Definition at line 78 of file IIOP_Acceptor.h.
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 }
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().
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.
The concrete acceptor, as a pointer to it's base class.
Definition at line 267 of file IIOP_Acceptor.h.
Referenced by close().
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] |
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] |
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().