#include <IIOP_Acceptor.h>
Inheritance diagram for TAO_IIOP_Acceptor:
Public Types | |
typedef ACE_Strategy_Acceptor< TAO_IIOP_Connection_Handler, ACE_SOCK_ACCEPTOR > | BASE_ACCEPTOR |
typedef TAO_Creation_Strategy< TAO_IIOP_Connection_Handler > | CREATION_STRATEGY |
typedef TAO_Concurrency_Strategy< TAO_IIOP_Connection_Handler > | CONCURRENCY_STRATEGY |
typedef TAO_Accept_Strategy< TAO_IIOP_Connection_Handler, ACE_SOCK_ACCEPTOR > | ACCEPT_STRATEGY |
Public Member Functions | |
TAO_IIOP_Acceptor (void) | |
Constructor. | |
~TAO_IIOP_Acceptor (void) | |
Destructor. | |
const ACE_INET_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.
|
Definition at line 80 of file IIOP_Acceptor.h. |
|
Definition at line 77 of file IIOP_Acceptor.h. |
|
Definition at line 79 of file IIOP_Acceptor.h. |
|
Definition at line 78 of file IIOP_Acceptor.h. |
|
Constructor.
Definition at line 32 of file IIOP_Acceptor.cpp. References INADDR_ANY, TAO_DEF_GIOP_MAJOR, and TAO_DEF_GIOP_MINOR.
00033 : TAO_Acceptor (IOP::TAG_INTERNET_IOP), 00034 addrs_ (0), 00035 port_span_ (1), 00036 hosts_ (0), 00037 hostname_in_ior_ (0), 00038 endpoint_count_ (0), 00039 version_ (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR), 00040 orb_core_ (0), 00041 reuse_addr_ (1), 00042 #if defined (ACE_HAS_IPV6) 00043 default_address_ (static_cast<unsigned short> (0), ACE_IPV6_ANY, AF_INET6), 00044 #else 00045 default_address_ (static_cast<unsigned short> (0), static_cast<ACE_UINT32> (INADDR_ANY)), 00046 #endif /* ACE_HAS_IPV6 */ 00047 base_acceptor_ (), 00048 creation_strategy_ (0), 00049 concurrency_strategy_ (0), 00050 accept_strategy_ (0) 00051 { 00052 } |
|
Destructor.
Definition at line 56 of file IIOP_Acceptor.cpp. References addrs_, close(), endpoint_count_, hostname_in_ior_, hosts_, and CORBA::string_free().
00057 { 00058 // Make sure we are closed before we start destroying the 00059 // strategies. 00060 this->close (); 00061 00062 delete this->creation_strategy_; 00063 delete this->concurrency_strategy_; 00064 delete this->accept_strategy_; 00065 00066 delete [] this->addrs_; 00067 00068 for (CORBA::ULong i = 0; i < this->endpoint_count_; ++i) 00069 CORBA::string_free (this->hosts_[i]); 00070 00071 delete [] this->hosts_; 00072 00073 delete [] this->hostname_in_ior_; 00074 } |
|
@ Helper method for the implementation repository, should go away |
|
Closes the acceptor.
Implements TAO_Acceptor. Definition at line 260 of file IIOP_Acceptor.cpp. References base_acceptor_, and ACE_Acceptor< SVC_HANDLER, ACE_PEER_ACCEPTOR_2 >::close(). Referenced by ~TAO_IIOP_Acceptor().
00261 { 00262 return this->base_acceptor_.close (); 00263 } |
|
Helper method to add a new profile to the mprofile for each endpoint. Definition at line 99 of file IIOP_Acceptor.cpp. References TAO_Profile::_decr_refcnt(), ACE_NEW_RETURN, addrs_, TAO_ORB_Core::codeset_manager(), TAO_IIOP_Profile::endpoint(), endpoint_count_, ACE_INET_Addr::get_port_number(), TAO_MProfile::give_profile(), TAO_MProfile::grow(), TAO_ORB_Core::orb_params(), TAO_Endpoint::priority(), TAO_MProfile::profile_count(), TAO_Codeset_Manager::set_codeset(), TAO_Tagged_Components::set_orb_type(), TAO_MProfile::size(), TAO_ORB_Parameters::std_profile_components(), ACE_OS::strcmp(), TAO_Profile::tagged_components(), TAO_ORB_TYPE, and version_. Referenced by create_profile().
00102 { 00103 // Adding this->endpoint_count_ to the TAO_MProfile. 00104 int const count = mprofile.profile_count (); 00105 if ((mprofile.size () - count) < this->endpoint_count_ 00106 && mprofile.grow (count + this->endpoint_count_) == -1) 00107 return -1; 00108 00109 // Create a profile for each acceptor endpoint. 00110 for (CORBA::ULong i = 0; i < this->endpoint_count_; ++i) 00111 { 00112 // Skip if the host name 00113 if (i > 0 00114 && (this->addrs_[i].get_port_number() == this->addrs_[0].get_port_number()) 00115 && ACE_OS::strcmp(this->hosts_[i], this->hosts_[0]) == 0) 00116 continue; 00117 00118 TAO_IIOP_Profile *pfile = 0; 00119 ACE_NEW_RETURN (pfile, 00120 TAO_IIOP_Profile (this->hosts_[i], 00121 this->addrs_[i].get_port_number (), 00122 object_key, 00123 this->addrs_[i], 00124 this->version_, 00125 this->orb_core_), 00126 -1); 00127 pfile->endpoint ()->priority (priority); 00128 00129 if (mprofile.give_profile (pfile) == -1) 00130 { 00131 pfile->_decr_refcnt (); 00132 pfile = 0; 00133 return -1; 00134 } 00135 00136 // Do not add any tagged components to the profile if configured 00137 // by the user not to do so, or if an IIOP 1.0 endpoint is being 00138 // created (IIOP 1.0 did not support tagged components). 00139 if (this->orb_core_->orb_params ()->std_profile_components () == 0 00140 || (this->version_.major == 1 && this->version_.minor == 0)) 00141 continue; 00142 00143 pfile->tagged_components ().set_orb_type (TAO_ORB_TYPE); 00144 00145 TAO_Codeset_Manager *csm = this->orb_core_->codeset_manager(); 00146 if (csm) 00147 csm->set_codeset(pfile->tagged_components()); 00148 } 00149 00150 return 0; 00151 } |
|
Create the corresponding profile for this endpoint. If share_profile is set to true, the pluggable protocol implementation should try to add the endpoint to a profile in the mprofile that is of the same type. Currently, this is used when RT CORBA is enabled. Implements TAO_Acceptor. Definition at line 81 of file IIOP_Acceptor.cpp. References create_new_profile(), create_shared_profile(), endpoint_count_, TAO_ORB_Core::orb_params(), TAO_ORB_Parameters::shared_profile(), and TAO_INVALID_PRIORITY.
00084 { 00085 // Sanity check. 00086 if (this->endpoint_count_ == 0) 00087 return -1; 00088 00089 // Check if multiple endpoints should be put in one profile or 00090 // if they should be spread across multiple profiles. 00091 if (priority == TAO_INVALID_PRIORITY && 00092 this->orb_core_->orb_params ()->shared_profile () == 0) 00093 return this->create_new_profile (object_key, mprofile, priority); 00094 else 00095 return this->create_shared_profile (object_key, mprofile, priority); 00096 } |
|
Helper method to create a profile that contains all of our endpoints. Definition at line 154 of file IIOP_Acceptor.cpp. References TAO_Profile::_decr_refcnt(), ACE_NEW_RETURN, TAO_IIOP_Profile::add_endpoint(), addrs_, TAO_ORB_Core::codeset_manager(), TAO_IIOP_Profile::endpoint(), endpoint_count_, ACE_INET_Addr::get_port_number(), TAO_MProfile::get_profile(), TAO_MProfile::give_profile(), TAO_ORB_Core::orb_params(), TAO_Endpoint::priority(), TAO_MProfile::profile_count(), TAO_Codeset_Manager::set_codeset(), TAO_Tagged_Components::set_orb_type(), TAO_ORB_Parameters::std_profile_components(), ACE_OS::strcmp(), TAO_Profile::tag(), TAO_Profile::tagged_components(), TAO_ORB_TYPE, TAO_PHandle, and version_. Referenced by create_profile().
00157 { 00158 CORBA::ULong index = 0; 00159 TAO_Profile *pfile = 0; 00160 TAO_IIOP_Profile *iiop_profile = 0; 00161 00162 // First see if <mprofile> already contains a IIOP profile. 00163 for (TAO_PHandle i = 0; i != mprofile.profile_count (); ++i) 00164 { 00165 pfile = mprofile.get_profile (i); 00166 if (pfile->tag () == IOP::TAG_INTERNET_IOP) 00167 { 00168 iiop_profile = dynamic_cast<TAO_IIOP_Profile *> (pfile); 00169 break; 00170 } 00171 } 00172 00173 // If <mprofile> doesn't contain a IIOP_Profile, we need to create 00174 // one. 00175 if (iiop_profile == 0) 00176 { 00177 ACE_NEW_RETURN (iiop_profile, 00178 TAO_IIOP_Profile (this->hosts_[0], 00179 this->addrs_[0].get_port_number (), 00180 object_key, 00181 this->addrs_[0], 00182 this->version_, 00183 this->orb_core_), 00184 -1); 00185 00186 iiop_profile->endpoint ()->priority (priority); 00187 00188 if (mprofile.give_profile (iiop_profile) == -1) 00189 { 00190 iiop_profile->_decr_refcnt (); 00191 iiop_profile = 0; 00192 return -1; 00193 } 00194 00195 // Do not add any tagged components to the profile if configured 00196 // by the user not to do so, or if an IIOP 1.0 endpoint is being 00197 // created (IIOP 1.0 did not support tagged components). 00198 if (this->orb_core_->orb_params ()->std_profile_components () != 0 00199 && (this->version_.major >= 1 && this->version_.minor >= 1)) 00200 { 00201 iiop_profile->tagged_components ().set_orb_type (TAO_ORB_TYPE); 00202 TAO_Codeset_Manager *csm = this->orb_core_->codeset_manager(); 00203 if (csm) 00204 csm->set_codeset(iiop_profile->tagged_components()); 00205 } 00206 00207 index = 1; 00208 } 00209 00210 // Add any remaining acceptor endpoints to the IIOP_Profile. 00211 for (; 00212 index < this->endpoint_count_; 00213 ++index) 00214 { 00215 if (index > 0 && 00216 this->addrs_[index].get_port_number() == this->addrs_[0].get_port_number() && 00217 ACE_OS::strcmp(this->hosts_[index], this->hosts_[0]) == 0) 00218 continue; 00219 00220 TAO_IIOP_Endpoint *endpoint = 0; 00221 ACE_NEW_RETURN (endpoint, 00222 TAO_IIOP_Endpoint (this->hosts_[index], 00223 this->addrs_[index].get_port_number (), 00224 this->addrs_[index]), 00225 -1); 00226 endpoint->priority (priority); 00227 iiop_profile->add_endpoint (endpoint); 00228 } 00229 00230 return 0; 00231 } |
|
Returns address for default endpoint.
Referenced by TAO_Acceptor_Registry::open_default(), and TAO_Acceptor_Registry::open_i(). |
|
Set the host name for the given address using the dotted decimal format. Definition at line 787 of file IIOP_Acceptor.cpp. References ACE_ERROR, ACE_TEXT, ACE_INET_Addr::get_host_addr(), ACE_INET_Addr::get_host_name(), ACE_INET_Addr::get_port_number(), ACE_Addr::get_type(), ACE_INET_Addr::is_any(), LM_ERROR, ACE_INET_Addr::set(), CORBA::string_dup(), and TAO_debug_level. Referenced by hostname().
00789 { 00790 int result = 0; 00791 const char *tmp = 0; 00792 00793 // If the IP address in the INET_Addr is the IN(6)ADDR_ANY address, 00794 // then force the actual IP address to be used by initializing a new 00795 // INET_Addr with the hostname from the original one. If that fails 00796 // then something is seriously wrong with the systems networking 00797 // setup. 00798 if (addr.is_any ()) 00799 { 00800 ACE_INET_Addr new_addr; 00801 #if defined (ACE_HAS_IPV6) 00802 result = new_addr.set (addr.get_port_number (), 00803 addr.get_host_name (), 00804 1, /* encode */ 00805 addr.get_type ()); 00806 #else /* ACE_HAS_IPV6 */ 00807 result = new_addr.set (addr.get_port_number (), 00808 addr.get_host_name ()); 00809 #endif /* !ACE_HAS_IPV6 */ 00810 tmp = new_addr.get_host_addr (); 00811 } 00812 else 00813 tmp = addr.get_host_addr (); 00814 00815 if (tmp == 0 || result != 0) 00816 { 00817 if (TAO_debug_level > 0) 00818 ACE_ERROR ((LM_ERROR, 00819 ACE_TEXT ("TAO (%P|%t) - ") 00820 ACE_TEXT ("IIOP_Acceptor::dotted_decimal_address, ") 00821 ACE_TEXT ("- %p, "), 00822 ACE_TEXT ("cannot determine hostname\n"))); 00823 return -1; 00824 } 00825 00826 host = CORBA::string_dup (tmp); 00827 return 0; 00828 } |
|
Returns the number of endpoints this acceptor is listening on. This is used for determining how many profiles will be generated for this acceptor. Implements TAO_Acceptor. Definition at line 1040 of file IIOP_Acceptor.cpp. References endpoint_count_. Referenced by TAO_IIOP_Transport::get_listen_point().
01041 { 01042 return this->endpoint_count_; 01043 } |
|
Returns the array of endpoints in this acceptor.
Referenced by TAO_IIOP_Transport::get_listen_point(). |
|
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 592 of file IIOP_Acceptor.cpp. References ACE_DEBUG, ACE_TEXT, dotted_decimal_address(), ACE_INET_Addr::get_host_name(), hostname_in_ior_, ACE_INET_Addr::is_ipv4_compat_ipv6(), LM_DEBUG, MAXHOSTNAMELEN, TAO_ORB_Core::orb_params(), CORBA::string_dup(), TAO_debug_level, and TAO_ORB_Parameters::use_dotted_decimal_addresses(). Referenced by TAO_IIOP_Transport::get_listen_point(), open(), and probe_interfaces().
00596 { 00597 if (this->hostname_in_ior_ != 0) 00598 { 00599 if (TAO_debug_level >= 5) 00600 ACE_DEBUG ((LM_DEBUG, 00601 ACE_TEXT ("TAO (%P|%t) IIOP_Acceptor - ") 00602 ACE_TEXT ("Overriding the hostname with <%s>\n"), 00603 this->hostname_in_ior_)); 00604 00605 host = CORBA::string_dup (this->hostname_in_ior_); 00606 } 00607 else if (orb_core->orb_params ()->use_dotted_decimal_addresses ()) 00608 { 00609 // If dotted decimal addresses are enabled, 00610 // just return ours. 00611 return this->dotted_decimal_address (addr, host); 00612 } 00613 else if (specified_hostname != 0) 00614 { 00615 // If the user specified a hostname, pass it back 00616 // blindly as it overrides our choice of hostname. 00617 host = CORBA::string_dup (specified_hostname); 00618 } 00619 else 00620 { 00621 char tmp_host[MAXHOSTNAMELEN + 1]; 00622 00623 // Get the hostname associated with our address 00624 #if defined (ACE_HAS_IPV6) 00625 // If we have a IPv4-compatible IPv6 address don't do hostname lookup 00626 // because that gets us into trouble. Most likely we get the same hostname 00627 // returned as for the actual IPv4 address but resolving that into an IPv6 00628 // address at the client will fail. 00629 if (addr.is_ipv4_compat_ipv6 () || 00630 addr.get_host_name (tmp_host, sizeof (tmp_host)) != 0) 00631 #else /* ACE_HAS_IPV6 */ 00632 if (addr.get_host_name (tmp_host, sizeof (tmp_host)) != 0) 00633 #endif /* !ACE_HAS_IPV6 */ 00634 { 00635 // On failure, just return the decimal address. 00636 return this->dotted_decimal_address (addr, host); 00637 } 00638 else 00639 { 00640 host = CORBA::string_dup (tmp_host); 00641 } 00642 } 00643 00644 return 0; 00645 } |
|
Return 1 if the endpoint has the same address as the acceptor.
Implements TAO_Acceptor. Definition at line 234 of file IIOP_Acceptor.cpp. References addrs_, endpoint_count_, ACE_INET_Addr::get_port_number(), TAO_IIOP_Endpoint::host(), hosts_, TAO_IIOP_Endpoint::port(), and ACE_OS::strcmp().
00235 { 00236 const TAO_IIOP_Endpoint *endp = 00237 dynamic_cast<const TAO_IIOP_Endpoint *> (endpoint); 00238 00239 // Make sure the dynamically cast pointer is valid. 00240 if (endp == 0) 00241 return 0; 00242 00243 for (CORBA::ULong i = 0; i < this->endpoint_count_; ++i) 00244 { 00245 // compare the port and host name. Please do *NOT* optimize 00246 // this code by comparing the IP address instead. That would 00247 // trigger the following bug: 00248 // 00249 // http://deuce.doc.wustl.edu/bugzilla/show_bug.cgi?id=1220 00250 // 00251 if (endp->port() == this->addrs_[i].get_port_number() 00252 && ACE_OS::strcmp(endp->host(), this->hosts_[i]) == 0) 00253 return 1; 00254 } 00255 00256 return 0; 00257 } |
|
This method fetches the key from the profile. Protocols that are pluggable can send data that are specific in the Implements TAO_Acceptor. Definition at line 1046 of file IIOP_Acceptor.cpp. References ACE_DEBUG, ACE_TEXT, LM_DEBUG, CORBA::Octet, TAO::String_var< charT >::out(), IOP::TaggedProfile::profile_data, ACE_InputCDR::read_octet(), ACE_InputCDR::read_string(), ACE_InputCDR::read_ushort(), CORBA::String_var, and TAO_debug_level.
01048 { 01049 // Create the decoding stream from the encapsulation in the buffer, 01050 #if (TAO_NO_COPY_OCTET_SEQUENCES == 1) 01051 TAO_InputCDR cdr (profile.profile_data.mb ()); 01052 #else 01053 TAO_InputCDR cdr (reinterpret_cast<char*> (profile.profile_data.get_buffer ()), 01054 profile.profile_data.length ()); 01055 #endif /* TAO_NO_COPY_OCTET_SEQUENCES == 1 */ 01056 01057 CORBA::Octet major; 01058 CORBA::Octet minor = CORBA::Octet(); 01059 01060 // Read the version. We just read it here. We don't*do any* 01061 // processing. 01062 if (!(cdr.read_octet (major) 01063 && cdr.read_octet (minor))) 01064 { 01065 if (TAO_debug_level > 0) 01066 { 01067 ACE_DEBUG ((LM_DEBUG, 01068 ACE_TEXT ("TAO (%P|%t) - TAO_IIOP_Acceptor::object_key, v%d.%d\n"), 01069 major, 01070 minor)); 01071 } 01072 return -1; 01073 } 01074 01075 CORBA::String_var host; 01076 CORBA::UShort port = 0; 01077 01078 // Get host and port. No processing here too.. 01079 if (cdr.read_string (host.out ()) == 0 01080 || cdr.read_ushort (port) == 0) 01081 { 01082 if (TAO_debug_level > 0) 01083 { 01084 ACE_DEBUG ((LM_DEBUG, 01085 ACE_TEXT ("TAO (%P|%t) - TAO_IIOP_Acceptor::object_key, ") 01086 ACE_TEXT ("error while decoding host/port\n"))); 01087 } 01088 return -1; 01089 } 01090 01091 // ... and object key. 01092 if ((cdr >> object_key) == 0) 01093 return -1; 01094 01095 // We are NOT bothered about the rest. 01096 01097 return 1; 01098 } |
|
The TAO_Acceptor methods, check the documentation in Transport_Acceptor.h for details. Implements TAO_Acceptor. Definition at line 266 of file IIOP_Acceptor.cpp. References ACE_CString, ACE_DEBUG, ACE_ERROR_RETURN, ACE_NEW_RETURN, ACE_TEXT, ACE_TEXT_CHAR_TO_TCHAR, addrs_, AF_UNSPEC, TAO_ORB_Parameters::connect_ipv6_only(), endpoint_count_, ACE_INET_Addr::get_port_number(), ACE_Addr::get_type(), hostname(), hostname_in_ior_, hosts_, ACE_INET_Addr::is_ipv4_mapped_ipv6(), LM_DEBUG, LM_ERROR, open_i(), TAO_ORB_Core::orb_params(), parse_address(), parse_options(), probe_interfaces(), ACE_INET_Addr::set(), TAO_GIOP_Message_Version::set_version(), TAO_debug_level, and version_.
00272 { 00273 if (TAO_debug_level > 2) 00274 { 00275 ACE_DEBUG ((LM_DEBUG, 00276 ACE_TEXT ("TAO (%P|%t) - ") 00277 ACE_TEXT ("IIOP_Acceptor::open, address==%s, options=%s\n"), 00278 address, options)); 00279 } 00280 00281 this->orb_core_ = orb_core; 00282 00283 if (this->hosts_ != 0) 00284 { 00285 // The hostname cache has already been set! 00286 // This is bad mojo, i.e. an internal TAO error. 00287 ACE_ERROR_RETURN ((LM_ERROR, 00288 ACE_TEXT ("TAO (%P|%t) - ") 00289 ACE_TEXT ("IIOP_Acceptor::open, ") 00290 ACE_TEXT ("hostname already set\n\n")), 00291 -1); 00292 } 00293 00294 if (address == 0) 00295 return -1; 00296 00297 if (major >=0 && minor >= 0) 00298 this->version_.set_version (static_cast<CORBA::Octet> (major), 00299 static_cast<CORBA::Octet> (minor)); 00300 // Parse options 00301 if (this->parse_options (options) == -1) 00302 return -1; 00303 00304 ACE_CString specified_hostname; 00305 ACE_INET_Addr addr; 00306 int def_type = AF_UNSPEC; 00307 00308 if (this->parse_address (address, 00309 addr, 00310 specified_hostname, 00311 &def_type) == -1) 00312 return -1; 00313 00314 if (specified_hostname.length() == 0) 00315 { 00316 // The address is a port number or port name. No hostname was 00317 // specified. The hostname for each network interface and the 00318 // fully qualified domain name must be obtained. 00319 00320 // Check for multiple network interfaces. 00321 if (this->probe_interfaces (orb_core, def_type) == -1) 00322 return -1; 00323 00324 // Probe interfaces has a side effect of potentially modifying 00325 // the default address, since that is where the address family 00326 // is considered. 00327 addr.set(this->default_address_); 00328 00329 return this->open_i (addr, reactor); 00330 } 00331 00332 #if defined (ACE_HAS_IPV6) 00333 // Check for violation of ORBConnectIPV6Only option 00334 if (this->orb_core_->orb_params ()->connect_ipv6_only () && 00335 (addr.get_type () != AF_INET6 || 00336 addr.is_ipv4_mapped_ipv6 ())) 00337 { 00338 ACE_ERROR_RETURN ((LM_ERROR, 00339 ACE_TEXT ("TAO (%P|%t) - ") 00340 ACE_TEXT ("IIOP_Acceptor::open, ") 00341 ACE_TEXT ("non-IPv6 endpoints not allowed when ") 00342 ACE_TEXT ("connect_ipv6_only is set\n\n")), 00343 -1); 00344 } 00345 #endif /* ACE_HAS_IPV6 */ 00346 00347 if (TAO_debug_level > 2) 00348 { 00349 ACE_DEBUG ((LM_DEBUG, 00350 ACE_TEXT ("TAO (%P|%t) - ") 00351 ACE_TEXT ("IIOP_Acceptor::open, specified host=%s:%d\n"), 00352 (specified_hostname.length() == 0 ? "<null>" : specified_hostname.c_str()), 00353 addr.get_port_number ())); 00354 } 00355 00356 this->endpoint_count_ = 1; // Only one hostname to store 00357 00358 ACE_NEW_RETURN (this->addrs_, 00359 ACE_INET_Addr[this->endpoint_count_], 00360 -1); 00361 00362 ACE_NEW_RETURN (this->hosts_, 00363 char *[this->endpoint_count_], 00364 -1); 00365 00366 this->hosts_[0] = 0; 00367 00368 if (this->hostname_in_ior_ != 0) 00369 { 00370 if (TAO_debug_level > 2) 00371 { 00372 ACE_DEBUG ((LM_DEBUG, 00373 ACE_TEXT ("TAO (%P|%t) - ") 00374 ACE_TEXT ("IIOP_Acceptor::open, ") 00375 ACE_TEXT ("Overriding address in IOR with %s\n"), 00376 ACE_TEXT_CHAR_TO_TCHAR (this->hostname_in_ior_))); 00377 } 00378 specified_hostname = this->hostname_in_ior_; 00379 } 00380 00381 if (this->hostname (orb_core, 00382 addr, 00383 this->hosts_[0], 00384 specified_hostname.c_str()) != 0) 00385 return -1; 00386 00387 // Copy the addr. The port is (re)set in 00388 // TAO_IIOP_Acceptor::open_i(). 00389 if (this->addrs_[0].set (addr) != 0) 00390 return -1; 00391 00392 return this->open_i (addr, 00393 reactor); 00394 } |
|
Open an acceptor with the given protocol version on a default endpoint Implements TAO_Acceptor. Definition at line 397 of file IIOP_Acceptor.cpp. References ACE_ERROR_RETURN, ACE_TEXT, hosts_, LM_ERROR, open_i(), parse_options(), probe_interfaces(), ACE_INET_Addr::set(), TAO_GIOP_Message_Version::set_version(), and version_.
00402 { 00403 this->orb_core_ = orb_core; 00404 00405 if (this->hosts_ != 0) 00406 { 00407 // The hostname cache has already been set! 00408 // This is bad mojo, i.e. an internal TAO error. 00409 ACE_ERROR_RETURN ((LM_ERROR, 00410 ACE_TEXT ("TAO (%P|%t) - ") 00411 ACE_TEXT ("IIOP_Acceptor::open_default, ") 00412 ACE_TEXT ("hostname already set\n\n")), 00413 -1); 00414 } 00415 00416 if (major >= 0 && minor >= 0) 00417 this->version_.set_version (static_cast<CORBA::Octet> (major), 00418 static_cast<CORBA::Octet> (minor)); 00419 00420 // Parse options 00421 if (this->parse_options (options) == -1) 00422 return -1; 00423 00424 // Check for multiple network interfaces. 00425 if (this->probe_interfaces (orb_core) == -1) 00426 return -1; 00427 00428 // Now that each network interface's hostname has been cached, open 00429 // an endpoint on each network interface using the INADDR_ANY 00430 // address. 00431 ACE_INET_Addr addr; 00432 00433 if (addr.set (this->default_address_) != 0) 00434 return -1; 00435 00436 return this->open_i (addr, reactor); 00437 } |
|
Implement the common part of the open*() methods. This method is virtual to allow a derived class implementation to be invoked instead. Definition at line 440 of file IIOP_Acceptor.cpp. References ACE_Strategy_Acceptor< SVC_HANDLER, >::acceptor(), ACE_CLOEXEC, ACE_DEBUG, ACE_ERROR, ACE_MAX_DEFAULT_PORT, ACE_NEW_RETURN, ACE_TEXT, ACE_TEXT_CHAR_TO_TCHAR, addrs_, base_acceptor_, TAO_ORB_Parameters::connect_ipv6_only(), default_address_, endpoint_count_, ACE_INET_Addr::get_port_number(), ACE_INET_Addr::is_any(), LM_DEBUG, LM_ERROR, ACE_Strategy_Acceptor< SVC_HANDLER, >::open(), TAO_ORB_Core::orb_params(), port_span_, ACE_INET_Addr::set_port_number(), and TAO_debug_level. Referenced by open(), and open_default().
00442 { 00443 ACE_NEW_RETURN (this->creation_strategy_, 00444 CREATION_STRATEGY (this->orb_core_), 00445 -1); 00446 00447 ACE_NEW_RETURN (this->concurrency_strategy_, 00448 CONCURRENCY_STRATEGY (this->orb_core_), 00449 -1); 00450 00451 ACE_NEW_RETURN (this->accept_strategy_, 00452 ACCEPT_STRATEGY (this->orb_core_), 00453 -1); 00454 00455 unsigned short requested_port = addr.get_port_number (); 00456 if (requested_port == 0) 00457 { 00458 // don't care, i.e., let the OS choose an ephemeral port 00459 if (this->base_acceptor_.open (addr, 00460 reactor, 00461 this->creation_strategy_, 00462 this->accept_strategy_, 00463 this->concurrency_strategy_, 00464 0, 0, 0, 1, 00465 this->reuse_addr_) == -1) 00466 { 00467 if (TAO_debug_level > 0) 00468 ACE_DEBUG ((LM_DEBUG, 00469 ACE_TEXT ("TAO (%P|%t) - IIOP_Acceptor::open_i, ") 00470 ACE_TEXT ("%p, "), 00471 ACE_TEXT ("cannot open acceptor\n"))); 00472 return -1; 00473 } 00474 } 00475 else 00476 { 00477 ACE_INET_Addr a(addr); 00478 00479 bool found_a_port = false; 00480 ACE_UINT32 last_port = requested_port + this->port_span_ - 1; 00481 if (last_port > ACE_MAX_DEFAULT_PORT) 00482 { 00483 last_port = ACE_MAX_DEFAULT_PORT; 00484 } 00485 00486 for (ACE_UINT32 p = requested_port; p <= last_port; p++) 00487 { 00488 if (TAO_debug_level > 5) 00489 ACE_DEBUG ((LM_DEBUG, 00490 ACE_TEXT ("TAO (%P|%t) - IIOP_Acceptor::open_i, ") 00491 ACE_TEXT ("trying to listen on port %d\n"), p)); 00492 00493 // Now try to actually open on that port 00494 a.set_port_number ((u_short)p); 00495 if (this->base_acceptor_.open (a, 00496 reactor, 00497 this->creation_strategy_, 00498 this->accept_strategy_, 00499 this->concurrency_strategy_, 00500 0, 0, 0, 1, 00501 this->reuse_addr_) != -1) 00502 { 00503 found_a_port = true; 00504 break; 00505 } 00506 } 00507 00508 // Now, if we couldn't locate a port, we punt 00509 if (! found_a_port) 00510 { 00511 if (TAO_debug_level > 0) 00512 ACE_DEBUG ((LM_DEBUG, 00513 ACE_TEXT ("TAO (%P|%t) - IIOP_Acceptor::open_i, ") 00514 ACE_TEXT ("cannot open acceptor in port range (%d,%d)") 00515 ACE_TEXT ("- %p\n"), 00516 requested_port, last_port, ACE_TEXT(""))); 00517 return -1; 00518 } 00519 } 00520 00521 #if defined (ACE_HAS_IPV6) && defined (ACE_HAS_IPV6_V6ONLY) 00522 // Check if need to prevent this acceptor from accepting connections 00523 // from IPv4 mapped IPv6 addresses 00524 if (this->orb_core_->orb_params ()->connect_ipv6_only () && 00525 addr.is_any ()) 00526 { 00527 if (TAO_debug_level > 5) 00528 ACE_DEBUG ((LM_DEBUG, 00529 ACE_TEXT("TAO (%P|%t) - IIOP_Acceptor::open_i, ") 00530 ACE_TEXT("setting IPV6_V6ONLY\n"))); 00531 00532 // Prevent server from accepting connections from IPv4-mapped addresses. 00533 int on = 1; 00534 if (this->base_acceptor_.acceptor ().set_option (IPPROTO_IPV6, 00535 IPV6_V6ONLY, 00536 (void *) &on, 00537 sizeof (on)) == -1) 00538 { 00539 ACE_ERROR ((LM_ERROR, 00540 ACE_TEXT ("TAO (%P|%t) - IIOP_Acceptor::open_i, ") 00541 ACE_TEXT ("%p\n"), 00542 ACE_TEXT ("cannot set IPV6_V6ONLY"))); 00543 } 00544 } 00545 #endif /* ACE_HAS_IPV6 && ACE_HAS_IPV6_V6ONLY */ 00546 00547 ACE_INET_Addr address; 00548 00549 // We do this make sure the port number the endpoint is listening on 00550 // gets set in the addr. 00551 if (this->base_acceptor_.acceptor ().get_local_addr (address) != 0) 00552 { 00553 if (TAO_debug_level > 0) 00554 ACE_ERROR ((LM_ERROR, 00555 ACE_TEXT ("TAO (%P|%t) - IIOP_Acceptor::open_i, ") 00556 ACE_TEXT ("%p"), 00557 ACE_TEXT ("cannot get local addr\n"))); 00558 return -1; 00559 } 00560 00561 // Set the port for each addr. If there is more than one network 00562 // interface then the endpoint created on each interface will be on 00563 // the same port. This is how a wildcard socket bind() is supposed 00564 // to work. 00565 unsigned short port = address.get_port_number (); 00566 for (CORBA::ULong j = 0; j < this->endpoint_count_; ++j) 00567 this->addrs_[j].set_port_number (port, 1); 00568 00569 this->default_address_.set_port_number (port); 00570 00571 (void) this->base_acceptor_.acceptor().enable (ACE_CLOEXEC); 00572 // This avoids having child processes acquire the listen socket thereby 00573 // denying the server the opportunity to restart on a well-known endpoint. 00574 // This does not affect the aberrent behavior on Win32 platforms. 00575 00576 if (TAO_debug_level > 5) 00577 { 00578 for (CORBA::ULong i = 0; i < this->endpoint_count_; ++i) 00579 { 00580 ACE_DEBUG ((LM_DEBUG, 00581 ACE_TEXT ("TAO (%P|%t) - IIOP_Acceptor::open_i, ") 00582 ACE_TEXT ("listening on: <%s:%u>\n"), 00583 ACE_TEXT_CHAR_TO_TCHAR(this->hosts_[i]), 00584 this->addrs_[i].get_port_number ())); 00585 } 00586 } 00587 00588 return 0; 00589 } |
|
Helper method Clear out 'addr' & 'specified_hostname' and initialize them based upon 'address'. If a non-zero pointer is passed in for def_type, this will be set to AF_INET6 if IPv6 support is enabled and supplied hostname is either [] or [::]. It will be set to AF_INET if the hostname is 0.0.0.0, otherwise it is set to AF_UNSPEC. This value is then passed to probe_interfaces by open. Definition at line 649 of file IIOP_Acceptor.cpp. References ACE_ERROR_RETURN, ACE_TEXT, AF_INET, AF_UNSPEC, ACE_OS::atoi(), default_address_, ACE_INET_Addr::is_any(), LM_ERROR, TAO_GIOP_Message_Version::major, MAXHOSTNAMELEN, ACE_OS::memcpy(), TAO_GIOP_Message_Version::minor, ACE_INET_Addr::set(), ACE_INET_Addr::set_port_number(), ACE_OS::strchr(), ACE_OS::strcpy(), TAO_MIN_IPV6_IIOP_MAJOR, TAO_MIN_IPV6_IIOP_MINOR, and version_. Referenced by open().
00653 { 00654 { 00655 ACE_INET_Addr tmp; 00656 addr.set (tmp); 00657 specified_hostname.clear(); 00658 } 00659 00660 const char *port_separator_loc = ACE_OS::strchr (address, ':'); 00661 char tmp_host[MAXHOSTNAMELEN + 1]; 00662 tmp_host[0] = '\0'; 00663 bool host_defaulted = port_separator_loc == address; 00664 bool ipv6_in_host = false; 00665 if (def_type) 00666 *def_type = AF_UNSPEC; 00667 00668 #if defined (ACE_HAS_IPV6) 00669 // Check if this is a (possibly) IPv6 supporting profile containing a 00670 // numeric IPv6 address representation. 00671 if ((this->version_.major > TAO_MIN_IPV6_IIOP_MAJOR || 00672 this->version_.minor >= TAO_MIN_IPV6_IIOP_MINOR) && 00673 address[0] == '[') 00674 { 00675 // In this case we have to find the end of the numeric address and 00676 // start looking for the port separator from there. 00677 char const * const cp_pos = ACE_OS::strchr (address, ']'); 00678 if (cp_pos == 0) 00679 { 00680 // No valid IPv6 address specified. 00681 ACE_ERROR_RETURN ((LM_ERROR, 00682 ACE_TEXT ("TAO (%P|%t) - ") 00683 ACE_TEXT ("IIOP_Acceptor::open, ") 00684 ACE_TEXT ("Invalid IPv6 decimal address specified\n\n")), 00685 -1); 00686 } 00687 else 00688 { 00689 // Extract out just the host part of the address. 00690 size_t const len = cp_pos - (address + 1); 00691 00692 if (len >= sizeof (tmp_host)) 00693 return -1; 00694 00695 ipv6_in_host = true; 00696 host_defaulted = (cp_pos == address+1) || 00697 (cp_pos == address+3 && address[1] == ':' && address[2] == ':'); 00698 if (cp_pos[1] == ':') // Look for a port 00699 port_separator_loc = cp_pos + 1; 00700 else 00701 port_separator_loc = 0; 00702 if (def_type) 00703 *def_type = AF_INET6; 00704 00705 ACE_OS::memcpy (tmp_host, address + 1, len); 00706 tmp_host[len] = '\0'; 00707 } 00708 } 00709 else 00710 #endif /* ACE_HAS_IPV6 */ 00711 if (!host_defaulted) 00712 { 00713 if (port_separator_loc != 0) 00714 { 00715 // Extract out just the host part of the address. 00716 size_t const len = port_separator_loc - address; 00717 00718 if (len >= sizeof (tmp_host)) 00719 return -1; 00720 00721 ACE_OS::memcpy (tmp_host, address, len); 00722 tmp_host[len] = '\0'; 00723 } 00724 else 00725 ACE_OS::strcpy (tmp_host, address); 00726 } 00727 00728 if (!ipv6_in_host && !host_defaulted) 00729 { 00730 if (addr.set((unsigned short)0,tmp_host) != 0) 00731 return -1; 00732 this->default_address_.set(addr); 00733 host_defaulted = addr.is_any(); 00734 if (def_type) 00735 *def_type = AF_INET; 00736 } 00737 00738 if (host_defaulted) 00739 { 00740 // First convert the port into a usable form. 00741 unsigned short portno = 0; 00742 if (port_separator_loc != 0) 00743 { 00744 portno = 00745 static_cast<u_short> (ACE_OS::atoi (port_separator_loc + 00746 sizeof (':'))); 00747 } 00748 this->default_address_.set_port_number (portno); 00749 00750 // Now reset the port and set the host. 00751 if (addr.set (this->default_address_) != 0) 00752 return -1; 00753 } 00754 else if (port_separator_loc == 0) 00755 { 00756 // The address is a hostname. No port was specified, so assume 00757 // port zero (port will be chosen for us). 00758 specified_hostname = tmp_host[0] == '\0' ? address : tmp_host; 00759 if (addr.set ((unsigned short) 0, 00760 specified_hostname.c_str()) != 0) 00761 return -1; 00762 } 00763 else 00764 { 00765 // Host and port were specified. 00766 if (addr.set (address) != 0) 00767 return -1; 00768 if (tmp_host[0] == '\0') 00769 { 00770 // Extract out just the host part of the address. 00771 size_t const len = port_separator_loc - address; 00772 00773 if (len >= sizeof (tmp_host)) 00774 return -1; 00775 00776 ACE_OS::memcpy (tmp_host, address, len); 00777 tmp_host[len] = '\0'; 00778 } 00779 specified_hostname = tmp_host; 00780 } 00781 00782 return 1; 00783 } |
|
Parse protocol specific options. Currently supported: portspan -- specifies the range of ports over which the acceptor should scan looking for a free port (this is convenient for situations where you might normally use an ephemeral port but can't because you're behind a firewall and don't want to permit passage on all ephemeral ports) Definition at line 1101 of file IIOP_Acceptor.cpp. References ACE_CString, ACE_ERROR, ACE_NEW_RETURN, ACE_TEXT, LM_ERROR, and parse_options_i(). Referenced by open(), and open_default().
01102 { 01103 if (str == 0) 01104 return 0; // No options to parse. Not a problem. 01105 01106 // Use an option format similar to the one used for CGI scripts in 01107 // HTTP URLs. 01108 // e.g.: option1=foo&option2=bar 01109 01110 const ACE_CString options (str); 01111 01112 const size_t len = options.length (); 01113 01114 static const char option_delimiter = '&'; 01115 01116 // Count the number of options. 01117 int argc = 1; 01118 01119 for (size_t i = 0; i < len; ++i) 01120 if (options[i] == option_delimiter) 01121 argc++; 01122 01123 // The idea behind the following loop is to split the options into 01124 // (option, name) pairs. 01125 // For example, 01126 // `option1=foo&option2=bar' 01127 // will be parsed into: 01128 // `option1=foo' 01129 // `option2=bar' 01130 01131 ACE_CString *argv_base = 0; 01132 ACE_NEW_RETURN (argv_base, ACE_CString[argc],-1); 01133 ACE_CString **argv = 0; 01134 ACE_NEW_RETURN (argv, ACE_CString*[argc],-1); 01135 01136 ACE_CString::size_type begin = 0; 01137 ACE_CString::size_type end = 0; 01138 int result = 0; 01139 for (int j = 0; j < argc; ++j) 01140 { 01141 if (j < argc - 1) 01142 end = options.find (option_delimiter, begin); 01143 else 01144 end = len; 01145 01146 if (end == begin) 01147 { 01148 ACE_ERROR ((LM_ERROR, 01149 ACE_TEXT ("TAO (%P|%t) - Zero length IIOP option.\n"))); 01150 result = -1; 01151 break; 01152 } 01153 else if (end != options.npos) 01154 { 01155 argv_base[j] = options.substring (begin, end - begin); 01156 argv[j] = &argv_base[j]; 01157 begin = end + 1; 01158 } 01159 else 01160 { 01161 break; // No other options. 01162 } 01163 } 01164 01165 if (result == 0) 01166 result = this->parse_options_i (argc,argv); 01167 01168 if (argc > 0) 01169 { 01170 ACE_ERROR ((LM_ERROR, 01171 ACE_TEXT ("TAO (%P|%t) - IIOP") 01172 ACE_TEXT (" endpoint has %d unknown options:\n"), 01173 argc)); 01174 for (int i = 0; i < argc; i++) 01175 ACE_ERROR ((LM_ERROR, 01176 ACE_TEXT("\t%s\n"), 01177 argv[i]->c_str())); 01178 result = -1; 01179 } 01180 delete [] argv; 01181 delete [] argv_base; 01182 return result; 01183 } |
|
Parse options splits the options list in to an argv array. This allows manipulation of the list in a manner similar to orb_init. By moving the consumed args to the tail of the list and reducing the argc count, the base parse_options_i can be called by derived parse_options_i. Method returns -1 if an ill-formed or otherwise bogus arg is encountered. The only strictly bogus arg was priority, which was a holdover from the early RT IIOP implementations. an ill-formed option is one which is missing an equal sign or something to the left of it. Definition at line 1186 of file IIOP_Acceptor.cpp. References ACE_CString, ACE_ERROR_RETURN, ACE_MAX_DEFAULT_PORT, ACE_TEXT, ACE_TEXT_CHAR_TO_TCHAR, ACE_OS::atoi(), hostname_in_ior_, LM_ERROR, and port_span_. Referenced by parse_options().
01188 { 01189 int i = 0; 01190 while (i < argc) 01191 { 01192 ACE_CString::size_type const len = argv[i]->length (); 01193 ACE_CString::size_type const slot = argv[i]->find ('='); 01194 01195 if (slot == len - 1 01196 || slot == ACE_CString::npos) 01197 ACE_ERROR_RETURN ((LM_ERROR, 01198 ACE_TEXT ("TAO (%P|%t) - IIOP option <%s> is ") 01199 ACE_TEXT ("missing a value.\n"), 01200 ACE_TEXT_CHAR_TO_TCHAR(argv[i]->c_str ())), 01201 -1); 01202 01203 ACE_CString name = argv[i]->substring (0, slot); 01204 ACE_CString value = argv[i]->substring (slot + 1); 01205 01206 if (name.length () == 0) 01207 ACE_ERROR_RETURN ((LM_ERROR, 01208 ACE_TEXT ("TAO (%P|%t) Zero length IIOP ") 01209 ACE_TEXT ("option name.\n")), 01210 -1); 01211 if (name == "portspan") 01212 { 01213 int range = static_cast <int> (ACE_OS::atoi (value.c_str ())); 01214 // @@ What's the lower bound on the range? zero, or one? 01215 if (range < 1 || range > ACE_MAX_DEFAULT_PORT) 01216 ACE_ERROR_RETURN ((LM_ERROR, 01217 ACE_TEXT ("TAO (%P|%t) Invalid IIOP endpoint ") 01218 ACE_TEXT ("portspan: <%s>\n") 01219 ACE_TEXT ("Valid range 1 -- %d\n"), 01220 value.c_str (), ACE_MAX_DEFAULT_PORT), 01221 -1); 01222 01223 this->port_span_ = static_cast <u_short> (range); 01224 } 01225 else if (name == "hostname_in_ior") 01226 { 01227 this->hostname_in_ior_ = value.rep (); 01228 } 01229 else if (name == "reuse_addr") 01230 { 01231 this->reuse_addr_ = ACE_OS::atoi (value.c_str ()); 01232 } 01233 else 01234 { 01235 // the name is not known, skip to the next option 01236 ++i; 01237 continue; 01238 } 01239 // at the end, we've consumed this argument. Shift the list and 01240 // put this one on the end. This technique has the effect of 01241 // putting them in reverse order, but that doesn't matter, since 01242 // these arguments are only whole strings. 01243 --argc; 01244 ACE_CString *temp = argv[i]; 01245 for (int j = i; j <= argc-1; ++j) 01246 argv[j] = argv[j+1]; 01247 argv[argc] = temp; 01248 } 01249 return 0; 01250 } |
|
Probe the system for available network interfaces, and initialize the array with an ACE_INET_Addr for each network interface. The port for each initialized ACE_INET_Addr will be set in the open_i() method. This method only gets invoked when no explicit hostname is provided in the specified endpoint. The optional argument def_type is used to constrain the resulting list of interfaces to be either only IPv6 or IPv4, or both, when ACE_HAS_IPV6 is enabled and the source endpoint was an explicitly declared wildcard. Definition at line 831 of file IIOP_Acceptor.cpp. References ACE_DEBUG, ACE_NEW_RETURN, ACE_TEXT, addrs_, AF_INET, TAO_ORB_Parameters::connect_ipv6_only(), default_address_, endpoint_count_, ENOTSUP, ACE::get_ip_interfaces(), ACE_Addr::get_type(), hostname(), ACE_INET_Addr::is_ipv4_mapped_ipv6(), ACE_INET_Addr::is_linklocal(), ACE_INET_Addr::is_loopback(), LM_DEBUG, LM_WARNING, ACE_OS::memset(), TAO_ORB_Core::orb_params(), ACE_INET_Addr::set(), TAO_debug_level, and TAO_ORB_Parameters::use_ipv6_link_local(). Referenced by open(), and open_default().
00832 { 00833 // Extract the hostname for each network interface, and then cache 00834 // it. The hostnames will then be used when creating a 00835 // TAO_IIOP_Profile for each endpoint setup on the probed 00836 // network interfaces. 00837 ACE_INET_Addr *if_addrs = 0; 00838 size_t if_cnt = 0; 00839 00840 if (ACE::get_ip_interfaces (if_cnt, if_addrs) != 0 00841 && errno != ENOTSUP) 00842 { 00843 // In the case where errno == ENOTSUP, if_cnt and if_addrs will 00844 // not be modified, and will each remain equal to zero. This 00845 // causes the default interface to be used. 00846 return -1; 00847 } 00848 00849 if (if_cnt == 0 || if_addrs == 0) 00850 { 00851 if (TAO_debug_level > 0) 00852 { 00853 ACE_DEBUG ((LM_WARNING, 00854 ACE_TEXT ("TAO (%P|%t) - Unable to probe network ") 00855 ACE_TEXT ("interfaces. Using default.\n"))); 00856 } 00857 00858 if_cnt = 1; // Force the network interface count to be one. 00859 delete [] if_addrs; 00860 ACE_NEW_RETURN (if_addrs, 00861 ACE_INET_Addr[if_cnt], 00862 -1); 00863 } 00864 00865 // Scan for the loopback interface since it shouldn't be included in 00866 // the list of cached hostnames unless it is the only interface. 00867 size_t lo_cnt = 0; // Loopback interface count 00868 for (size_t j = 0; j < if_cnt; ++j) 00869 if (if_addrs[j].is_loopback ()) 00870 ++lo_cnt; 00871 00872 #if defined (ACE_HAS_IPV6) 00873 size_t ipv4_cnt = 0; 00874 size_t ipv4_lo_cnt = 0; 00875 size_t ipv6_ll = 0; 00876 bool ipv6_non_ll = false; 00877 // Scan for IPv4 interfaces since these should not be included 00878 // when IPv6-only is selected. 00879 for (size_t j = 0; j < if_cnt; ++j) 00880 if (if_addrs[j].get_type () != AF_INET6 || 00881 if_addrs[j].is_ipv4_mapped_ipv6 ()) 00882 { 00883 ++ipv4_cnt; 00884 if (if_addrs[j].is_loopback ()) 00885 ++ipv4_lo_cnt; // keep track of IPv4 loopback ifs 00886 } 00887 else if (!if_addrs[j].is_linklocal () && 00888 !if_addrs[j].is_loopback()) 00889 { 00890 ipv6_non_ll = true; // we have at least 1 non-local IPv6 if 00891 } 00892 else if (!orb_core->orb_params ()->use_ipv6_link_local () && 00893 if_addrs[j].is_linklocal ()) 00894 { 00895 ++ipv6_ll; // count link local addrs to exclude them afterwards 00896 } 00897 #endif /* ACE_HAS_IPV6 */ 00898 00899 // The instantiation for this template is in 00900 // tao/IIOP_Connector.cpp. 00901 ACE_Auto_Basic_Array_Ptr<ACE_INET_Addr> safe_if_addrs (if_addrs); 00902 00903 #if defined (ACE_HAS_IPV6) 00904 bool ipv4_only = def_type == AF_INET; 00905 bool ipv6_only = (def_type == AF_INET6) || 00906 orb_core->orb_params ()->connect_ipv6_only (); 00907 #if defined (ACE_WIN32) 00908 if (this->default_address_.get_type () == AF_INET) 00909 ipv4_only = true; 00910 else 00911 ipv6_only = true; 00912 #endif /* ACE_WIN32 */ 00913 // If the loopback interface is the only interface then include it 00914 // in the list of interfaces to query for a hostname, otherwise 00915 // exclude it from the list. 00916 bool ignore_lo; 00917 if (ipv6_only) 00918 // only exclude loopback if non-local if exists 00919 ignore_lo = ipv6_non_ll; 00920 else if (ipv4_only) 00921 ignore_lo = ipv4_cnt != ipv4_lo_cnt; 00922 else 00923 ignore_lo = if_cnt != lo_cnt; 00924 00925 // Adjust counts for IPv6 only if required 00926 size_t if_ok_cnt = if_cnt; 00927 if (ipv6_only) 00928 { 00929 if_ok_cnt -= ipv4_cnt; 00930 lo_cnt -= ipv4_lo_cnt; 00931 ipv4_lo_cnt = 0; 00932 } 00933 else if (ipv4_only) 00934 { 00935 if_ok_cnt = ipv4_cnt; 00936 lo_cnt = ipv4_lo_cnt; 00937 ipv6_ll = 0; 00938 } 00939 00940 // In case there are no non-local IPv6 ifs in the list only exclude 00941 // IPv4 loopback. 00942 // IPv6 loopback will be needed to successfully connect IPv6 clients 00943 // in a localhost environment. 00944 if (!ipv4_only && !ipv6_non_ll) 00945 lo_cnt = ipv4_lo_cnt; 00946 00947 if (!ignore_lo) 00948 this->endpoint_count_ = static_cast<CORBA::ULong> (if_ok_cnt - ipv6_ll); 00949 else 00950 this->endpoint_count_ = static_cast<CORBA::ULong> (if_ok_cnt - ipv6_ll - lo_cnt); 00951 #else /* ACE_HAS_IPV6 */ 00952 // If the loopback interface is the only interface then include it 00953 // in the list of interfaces to query for a hostname, otherwise 00954 // exclude it from the list. 00955 bool ignore_lo; 00956 ignore_lo = if_cnt != lo_cnt; 00957 if (!ignore_lo) 00958 this->endpoint_count_ = static_cast<CORBA::ULong> (if_cnt); 00959 else 00960 this->endpoint_count_ = static_cast<CORBA::ULong> (if_cnt - lo_cnt); 00961 #endif /* !ACE_HAS_IPV6 */ 00962 00963 if (this->endpoint_count_ == 0) 00964 { 00965 if (TAO_debug_level > 0) 00966 ACE_DEBUG ((LM_DEBUG, 00967 ACE_TEXT("(%P|%t) TAO_IIOP_Acceptor::probe_interfaces ") 00968 ACE_TEXT("found no usable addresses, def_type = %d\n"), 00969 def_type)); 00970 return -1; 00971 } 00972 00973 ACE_NEW_RETURN (this->addrs_, 00974 ACE_INET_Addr[this->endpoint_count_], 00975 -1); 00976 00977 ACE_NEW_RETURN (this->hosts_, 00978 char *[this->endpoint_count_], 00979 -1); 00980 00981 ACE_OS::memset (this->hosts_, 0, sizeof (char*) * this->endpoint_count_); 00982 00983 // The number of hosts/interfaces we want to cache may not be the 00984 // same as the number of detected interfaces so keep a separate 00985 // count. 00986 size_t host_cnt = 0; 00987 00988 for (size_t i = 0; i < if_cnt; ++i) 00989 { 00990 #if defined (ACE_HAS_IPV6) 00991 // Ignore any loopback interface if there are other 00992 // non-loopback interfaces. 00993 if (ignore_lo && 00994 if_addrs[i].is_loopback () && 00995 (ipv4_only || 00996 ipv6_non_ll || 00997 if_addrs[i].get_type () != AF_INET6)) 00998 continue; 00999 01000 // Ignore any non-IPv4 interfaces when so required. 01001 if (ipv4_only && 01002 (if_addrs[i].get_type () != AF_INET)) 01003 continue; 01004 01005 // Ignore any non-IPv6 interfaces when so required. 01006 if (ipv6_only && 01007 (if_addrs[i].get_type () != AF_INET6 || 01008 if_addrs[i].is_ipv4_mapped_ipv6 ())) 01009 continue; 01010 01011 // Ignore all IPv6 link local interfaces when so required. 01012 if (!orb_core->orb_params ()->use_ipv6_link_local () && 01013 if_addrs[i].is_linklocal ()) 01014 continue; 01015 #else /* ACE_HAS_IPV6 */ 01016 // Ignore any loopback interface if there are other 01017 // non-loopback interfaces. 01018 if (ignore_lo && 01019 if_addrs[i].is_loopback ()) 01020 continue; 01021 #endif /* !ACE_HAS_IPV6 */ 01022 01023 if (this->hostname (orb_core, 01024 if_addrs[i], 01025 this->hosts_[host_cnt]) != 0) 01026 return -1; 01027 01028 // Copy the addr. The port is (re)set in 01029 // TAO_IIOP_Acceptor::open_i(). 01030 if (this->addrs_[host_cnt].set (if_addrs[i]) != 0) 01031 return -1; 01032 01033 ++host_cnt; 01034 } 01035 01036 return 0; 01037 } |
|
Set address for default endpoint.
Referenced by TAO_Acceptor_Registry::open_default(), and TAO_Acceptor_Registry::open_i(). |
|
Definition at line 272 of file IIOP_Acceptor.h. |
|
Array of ACE_INET_Addr instances, each one corresponding to a given network interface. Definition at line 221 of file IIOP_Acceptor.h. Referenced by create_new_profile(), create_shared_profile(), is_collocated(), open(), open_i(), probe_interfaces(), and ~TAO_IIOP_Acceptor(). |
|
The concrete acceptor, as a pointer to it's base class.
Definition at line 267 of file IIOP_Acceptor.h. |
|
Definition at line 271 of file IIOP_Acceptor.h. |
|
Acceptor strategies.
Definition at line 270 of file IIOP_Acceptor.h. |
|
Address for default endpoint.
Definition at line 262 of file IIOP_Acceptor.h. Referenced by open_i(), parse_address(), and probe_interfaces(). |
|
The number of host names cached in the hosts_ array (equivalent to the number of endpoints opened by this Acceptor). Definition at line 246 of file IIOP_Acceptor.h. Referenced by create_new_profile(), create_profile(), create_shared_profile(), endpoint_count(), is_collocated(), open(), open_i(), probe_interfaces(), and ~TAO_IIOP_Acceptor(). |
|
Override the hostname used in the ORBEndPoint. Definition at line 242 of file IIOP_Acceptor.h. Referenced by hostname(), open(), parse_options_i(), and ~TAO_IIOP_Acceptor(). |
|
Cache the information about the endpoints serviced by this acceptor. There may in fact be multiple hostnames for this endpoint. For example, if the IP address is INADDR_ANY (0.0.0.0) then there will be possibly a different hostname for each interface. Definition at line 237 of file IIOP_Acceptor.h. Referenced by is_collocated(), open(), open_default(), and ~TAO_IIOP_Acceptor(). |
|
ORB Core.
Definition at line 256 of file IIOP_Acceptor.h. |
|
The number of ports over which the acceptor should search (starting at the port specified in each element of addrs_) for an available port. This is specified via the "portspan=" option to the endpoint. Definition at line 228 of file IIOP_Acceptor.h. Referenced by open_i(), and parse_options_i(). |
|
Enable socket option SO_REUSEADDR to be set.
Definition at line 259 of file IIOP_Acceptor.h. |
|
The GIOP version for this endpoint @ Theoretically they shouldn't be here!! We need to look at a way to move this out Definition at line 253 of file IIOP_Acceptor.h. Referenced by create_new_profile(), create_shared_profile(), open(), open_default(), and parse_address(). |