Acceptor_Registry.cpp

Go to the documentation of this file.
00001 // $Id: Acceptor_Registry.cpp 81444 2008-04-25 13:26:05Z johnnyw $
00002 
00003 #include "tao/Acceptor_Registry.h"
00004 #include "tao/Profile.h"
00005 #include "tao/Transport_Acceptor.h"
00006 #include "tao/Protocol_Factory.h"
00007 #include "tao/ORB_Core.h"
00008 #include "tao/params.h"
00009 #include "tao/MProfile.h"
00010 #include "tao/debug.h"
00011 #include "tao/Acceptor_Filter.h"
00012 #include "tao/Endpoint.h"
00013 #include "tao/ORB_Constants.h"
00014 #include "tao/SystemException.h"
00015 #if defined (ACE_WIN32) && defined (ACE_HAS_IPV6)
00016 # include "tao/IIOP_Acceptor.h"
00017 #endif /* ACE_WIN32 && ACE_HAS_IPV6 */
00018 
00019 #include "ace/Auto_Ptr.h"
00020 #include "ace/OS_NS_string.h"
00021 #include "ace/OS_NS_ctype.h"
00022 #include "ace/CORBA_macros.h"
00023 
00024 #if !defined(__ACE_INLINE__)
00025 #include "tao/Acceptor_Registry.inl"
00026 #endif /* __ACE_INLINE__ */
00027 
00028 ACE_RCSID (tao,
00029            Acceptor_Registry,
00030            "$Id: Acceptor_Registry.cpp 81444 2008-04-25 13:26:05Z johnnyw $")
00031 
00032 
00033 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00034 
00035 TAO_Acceptor_Registry::TAO_Acceptor_Registry (void)
00036   : acceptors_ (0),
00037     size_ (0)
00038 {
00039 }
00040 
00041 TAO_Acceptor_Registry::~TAO_Acceptor_Registry (void)
00042 {
00043   this->close_all ();
00044 
00045   delete [] this->acceptors_;
00046 }
00047 
00048 size_t
00049 TAO_Acceptor_Registry::endpoint_count (void)
00050 {
00051   int count = 0;
00052   const TAO_AcceptorSetIterator end = this->end ();
00053 
00054   for (TAO_AcceptorSetIterator i = this->begin (); i != end; ++i)
00055     {
00056       count += (*i)->endpoint_count ();
00057     }
00058 
00059   return count;
00060 }
00061 
00062 int
00063 TAO_Acceptor_Registry::is_collocated (const TAO_MProfile &mprofile)
00064 {
00065   const TAO_AcceptorSetIterator end = this->end ();
00066 
00067   const CORBA::ULong count = mprofile.profile_count ();
00068 
00069   // If at least one endpoint in one of the profiles matches one of
00070   // the acceptors, we are collocated.
00071   for (TAO_AcceptorSetIterator i = this->begin (); i != end; ++i)
00072     {
00073       for (TAO_PHandle j = 0; j != count; ++j)
00074         {
00075           const TAO_Profile *profile = mprofile.get_profile (j);
00076 
00077           // @@ We need to invoke a nonconst <endpoint> method on
00078           //    <profile>.  The content of profile/endpoint will not
00079           //    be modified.
00080           TAO_Profile *pf = const_cast<TAO_Profile *> (profile);
00081 
00082           // Check all endpoints for address equality.
00083           if ((*i)->tag () == pf->tag ())
00084             {
00085               // @note This can be a potentially expensive (O(n^2))
00086               //       operation if the below is_collocated() call
00087               //       also executes a loop.
00088               for (TAO_Endpoint *endp = pf->endpoint ();
00089                    endp != 0;
00090                    endp = endp->next ())
00091                 {
00092                   if ((*i)->is_collocated (endp))
00093                     {
00094                       return 1;
00095                     }
00096                 }
00097             }
00098         }
00099     }
00100 
00101   return 0;
00102 }
00103 
00104 TAO_Acceptor*
00105 TAO_Acceptor_Registry::get_acceptor (CORBA::ULong tag)
00106 {
00107   TAO_AcceptorSetIterator end = this->end ();
00108   TAO_AcceptorSetIterator acceptor = this->begin ();
00109 
00110   for (; acceptor != end; ++acceptor)
00111     {
00112       if ((*acceptor)->tag () == tag)
00113         {
00114           return *acceptor;
00115         }
00116     }
00117 
00118   return 0;
00119 }
00120 
00121 int
00122 TAO_Acceptor_Registry::open (TAO_ORB_Core *orb_core,
00123                              ACE_Reactor *reactor,
00124                              const TAO_EndpointSet &endpoint_set,
00125                              bool ignore_address)
00126 {
00127   if (endpoint_set.is_empty ()
00128       // No endpoints were specified, we let each protocol pick its
00129       // own default.
00130 
00131       // All TAO pluggable protocols are expected to have the ability
00132       // to create a default endpoint.
00133       && this->open_default (orb_core, reactor, 0) == -1)
00134     {
00135       throw ::CORBA::INTERNAL (
00136         CORBA::SystemException::_tao_minor_code (
00137           TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE,
00138           0),
00139         CORBA::COMPLETED_NO);
00140     }
00141 
00142   // Count the maximum number of endpoints in the set.  This will be
00143   // the maximum number of acceptors that need to be created.
00144   size_t acceptor_count = 0;
00145   TAO_EndpointSetIterator endpts (endpoint_set);
00146 
00147   for (ACE_CString *ep = 0;
00148        endpts.next (ep) != 0;
00149        endpts.advance ())
00150     {
00151       const ACE_CString &iop = (*ep);
00152 
00153       // IOP://address1,address2
00154       //    ^ slot
00155       ACE_CString::size_type const slot = iop.find ("://", 0);
00156 
00157       if (slot == iop.npos)
00158         {
00159           if (TAO_debug_level > 0)
00160             {
00161               ACE_ERROR ((LM_ERROR,
00162                           ACE_TEXT ("(%P|%t) Invalid endpoint ")
00163                           ACE_TEXT ("specification: <%s>.\n"),
00164                           ACE_TEXT_CHAR_TO_TCHAR (iop.c_str ())));
00165             }
00166 
00167           throw ::CORBA::BAD_PARAM (
00168             CORBA::SystemException::_tao_minor_code (
00169               TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE,
00170               EINVAL),
00171             CORBA::COMPLETED_NO);
00172         }
00173 
00174       ++acceptor_count;  // We've got at least one acceptor so far.
00175 #if defined (ACE_WIN32) && defined (ACE_HAS_IPV6)
00176       // Since Win32 has single-stack IPv4/IPv6 we need an additional
00177       // acceptor if an iiop protocol without endpoints is specified
00178       // to open explicitly on IPv6 ANY *and* IPv4 ANY.
00179 
00180       // Now get the list of available protocol factories.
00181       const TAO_ProtocolFactorySetItor end =
00182         orb_core->protocol_factories ()->end ();
00183 
00184       // extract the protocol prefix
00185       const ACE_CString prefix (iop.substring (0, slot));
00186 
00187       for (TAO_ProtocolFactorySetItor factory =
00188              orb_core->protocol_factories ()->begin ();
00189            factory != end;
00190            ++factory)
00191         {
00192           if ((*factory)->factory ()->match_prefix (prefix))
00193             {
00194               if ((*factory)->factory ()->tag () == IOP::TAG_INTERNET_IOP)
00195                 {
00196                   // just add additional space to cover for possibility
00197                   ++acceptor_count;
00198                 }
00199               break; // we found the protocol, no need to go on
00200             }
00201         }
00202 #endif /* ACE_WIN32 && ACE_HAS_IPV6 */
00203 
00204       // Now count the number of commas.  That number will be the
00205       // remaining number of endpoints in the current endpoint
00206       // specification.
00207       const char *ep_end =
00208         ep->c_str () + ACE_OS::strlen (ep->c_str ());
00209 
00210       for (const char *e = ACE_OS::strchr (ep->c_str (), ',');
00211            e != 0 && e != ep_end;
00212            e = ACE_OS::strchr (e, ','))
00213         {
00214           ++acceptor_count;
00215           ++e;
00216         }
00217     }
00218 
00219   // The array containing the TAO_Acceptors will never contain more
00220   // than the number of endpoints stored in TAO_ORB_Parameters.
00221   if (this->acceptors_ == 0)
00222     {
00223       ACE_NEW_THROW_EX (this->acceptors_,
00224                         TAO_Acceptor *[acceptor_count],
00225                         CORBA::NO_MEMORY (
00226                           CORBA::SystemException::_tao_minor_code (
00227                             TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE,
00228                             ENOMEM),
00229                           CORBA::COMPLETED_NO));
00230     }
00231 
00232   TAO_EndpointSetIterator endpoints (endpoint_set);
00233 
00234   for (ACE_CString *endpoint = 0;
00235        endpoints.next (endpoint) != 0;
00236        endpoints.advance ())
00237     {
00238       const ACE_CString &iop = (*endpoint);
00239 
00240       // IOP://address1,address2
00241       //    ^ slot
00242       ACE_CString::size_type const slot = iop.find ("://", 0);
00243 
00244       if (slot == iop.npos)
00245         {
00246           if (TAO_debug_level > 0)
00247             {
00248               ACE_ERROR ((LM_ERROR,
00249                           ACE_TEXT ("(%P|%t) Invalid endpoint ")
00250                           ACE_TEXT ("specification: <%s>.\n"),
00251                           ACE_TEXT_CHAR_TO_TCHAR (iop.c_str ())));
00252             }
00253 
00254           throw ::CORBA::BAD_PARAM (
00255             CORBA::SystemException::_tao_minor_code (
00256               TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE,
00257               EINVAL),
00258             CORBA::COMPLETED_NO);
00259         }
00260 
00261       const ACE_CString prefix (iop.substring (0, slot));
00262 
00263       // @@ We could move the protocol factory loop to the outermost
00264       //    level but for now we leave it inside the endpoint loop
00265       //    under the assumption that there will be more endpoints
00266       //    than protocols.
00267 
00268       // Now get the list of available protocol factories.
00269       const TAO_ProtocolFactorySetItor end =
00270         orb_core->protocol_factories ()->end ();
00271 
00272       bool found = false;
00273       // If usable protocol (factory) is found then this will be
00274       // set equal to true.
00275 
00276       for (TAO_ProtocolFactorySetItor factory =
00277              orb_core->protocol_factories ()->begin ();
00278            factory != end;
00279            ++factory)
00280         {
00281           if ((*factory)->factory ()->match_prefix (prefix))
00282             {
00283               // increment slot past the "://" (i.e. add 3)
00284               ACE_CString addrs = iop.substring (slot + 3);
00285 
00286               int const result = this->open_i (orb_core,
00287                                                reactor,
00288                                                addrs,
00289                                                factory,
00290                                                ignore_address);
00291 
00292               if (result != 0)
00293                 {
00294                   return -1;
00295                 }
00296 
00297               found = true;  // A usable protocol was found.
00298             }
00299           else
00300             {
00301               continue;
00302             }
00303         }
00304 
00305       if (found == false)
00306         {
00307           ACE_ERROR ((LM_ERROR,
00308                       ACE_TEXT ("TAO (%P|%t) ")
00309                       ACE_TEXT ("no usable transport protocol ")
00310                       ACE_TEXT ("was found.\n")));
00311 
00312           throw ::CORBA::BAD_PARAM (
00313             CORBA::SystemException::_tao_minor_code (
00314               TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE,
00315               EINVAL),
00316             CORBA::COMPLETED_NO);
00317         }
00318     }
00319 
00320   return 0;
00321 }
00322 
00323 // Iterate through the loaded transport protocols and create a default
00324 // server for each protocol.
00325 int TAO_Acceptor_Registry::open_default (TAO_ORB_Core *orb_core,
00326                                          ACE_Reactor *reactor,
00327                                          const char *options)
00328 {
00329   // Flag that indicates at least one endpoint was opened.  If one
00330   // wasn't opened then there is a problem.
00331   bool opened_endpoint = false;
00332 
00333 #if defined (ACE_WIN32) && defined (ACE_HAS_IPV6)
00334   if (!orb_core->orb_params ()->connect_ipv6_only () && this->acceptors_ == 0)
00335     {
00336       // Since Win32 has single-stack IPv4/IPv6 we need an additional
00337       // acceptor to open explicitly on IPv6 ANY *and* IPv4 ANY.
00338       // This code takes care of that.
00339 
00340       TAO_ProtocolFactorySet *pfs = orb_core->protocol_factories ();
00341 
00342       // Number of acceptors to set up
00343       size_t acceptor_count = 0;
00344 
00345       const TAO_ProtocolFactorySetItor end = pfs->end ();
00346 
00347       // Loop through all the loaded protocols...
00348       for (TAO_ProtocolFactorySetItor i = pfs->begin (); i != end; ++i)
00349         {
00350           if (!(*i)->factory ()->requires_explicit_endpoint ())
00351             {
00352               if ((*i)->factory ()->tag () == IOP::TAG_INTERNET_IOP)
00353                 acceptor_count += 2; // IPv4 AND IPv6 endpoints
00354               else
00355                 acceptor_count += 1;
00356             }
00357         }
00358 
00359       // Allocate TAO_Acceptor array
00360       ACE_NEW_RETURN (this->acceptors_,
00361                       TAO_Acceptor *[acceptor_count],
00362                       -1);
00363 
00364       // Loop through all the loaded protocols...
00365       for (TAO_ProtocolFactorySetItor i = pfs->begin (); i != end; ++i)
00366         {
00367           // If the protocol requires an explicit -ORBEndpoint option then
00368           // don't use it, otherwise open a default endpoint for that
00369           // protocol, this solves the problem with persistent endpoints
00370           // (such as UNIX domain rendesvouz points) that are not cleaned
00371           // up if the server crashes.
00372           if (!(*i)->factory ()->requires_explicit_endpoint ())
00373             {
00374               // Make an acceptor
00375               TAO_Acceptor *acceptor =
00376                 (*i)->factory ()->make_acceptor ();
00377 
00378               if (acceptor == 0)
00379                 {
00380                   if (TAO_debug_level > 0)
00381                     {
00382                       ACE_ERROR ((
00383                           LM_ERROR,
00384                           ACE_TEXT ("TAO (%P|%t) unable to create ")
00385                           ACE_TEXT ("an acceptor for <%s>\n"),
00386                           ACE_TEXT_CHAR_TO_TCHAR ((*i)->protocol_name ().c_str ())
00387                         ));
00388                     }
00389 
00390                   return -1;
00391                 }
00392 
00393               if ((*i)->factory ()->tag () == IOP::TAG_INTERNET_IOP)
00394                 {
00395                   // Open first acceptor on IPv4 ANY
00396                   ACE_INET_Addr addr(static_cast<unsigned short> (0)); // IPv4 ANY
00397 
00398                   TAO_IIOP_Acceptor* iiop_acceptor = dynamic_cast<TAO_IIOP_Acceptor*> (acceptor);
00399 
00400                   if (!iiop_acceptor)
00401                     return -1;
00402 
00403                   iiop_acceptor->set_default_address (addr);
00404 
00405                   if (this->open_default_i (orb_core,
00406                                             reactor,
00407                                             TAO_DEF_GIOP_MAJOR,  // default major
00408                                             TAO_DEF_GIOP_MINOR,  // default minor
00409                                             i,
00410                                             acceptor,
00411                                             options) != 0)
00412                     {
00413                       return -1;
00414                     }
00415 
00416                   // record the port chosen for the IPv4 acceptor
00417                   u_short port = iiop_acceptor->default_address ().get_port_number ();
00418 
00419                   // Create second acceptor for IPV6 traffic
00420                   acceptor =
00421                     (*i)->factory ()->make_acceptor ();
00422 
00423                   if (acceptor == 0)
00424                     {
00425                       if (TAO_debug_level > 0)
00426                         {
00427                           ACE_ERROR ((
00428                               LM_ERROR,
00429                               ACE_TEXT ("TAO (%P|%t) unable to create ")
00430                               ACE_TEXT ("an acceptor for <%s>\n"),
00431                               ACE_TEXT_CHAR_TO_TCHAR ((*i)->protocol_name ().c_str ())
00432                             ));
00433                         }
00434 
00435                       return -1;
00436                     }
00437 
00438                   addr.set (port, ACE_IPV6_ANY, AF_INET6); // IPv6 ANY on specified port
00439 
00440                   iiop_acceptor = dynamic_cast<TAO_IIOP_Acceptor*> (acceptor);
00441 
00442                   if (!iiop_acceptor)
00443                     return -1;
00444 
00445                   iiop_acceptor->set_default_address (addr);
00446 
00447                   if (this->open_default_i (orb_core,
00448                                             reactor,
00449                                             TAO_DEF_GIOP_MAJOR,  // default major
00450                                             TAO_DEF_GIOP_MINOR,  // default minor
00451                                             i,
00452                                             acceptor,
00453                                             options) != 0)
00454                     {
00455                       return -1;
00456                     }
00457                 }
00458               else
00459                 {
00460                   if (this->open_default_i (orb_core,
00461                                             reactor,
00462                                             TAO_DEF_GIOP_MAJOR,  // default major
00463                                             TAO_DEF_GIOP_MINOR,  // default minor
00464                                             i,
00465                                             acceptor,
00466                                             options) != 0)
00467                     {
00468                       return -1;
00469                     }
00470                 }
00471 
00472               opened_endpoint = true;
00473             }
00474         }
00475     }
00476   else
00477     {
00478 #endif /* ACE_WIN32 && ACE_HAS_IPV6 */
00479   TAO_ProtocolFactorySet *pfs = orb_core->protocol_factories ();
00480 
00481   // If the TAO_Acceptor array is zero by the time we get here then no
00482   // endpoints were specified by the user, meaning that the number of
00483   // acceptors will never be more than the number of loaded protocols
00484   // in the ORB core.
00485   if (this->acceptors_ == 0)
00486     {
00487       ACE_NEW_RETURN (this->acceptors_,
00488                       TAO_Acceptor *[pfs->size ()],
00489                       -1);
00490     }
00491 
00492   const TAO_ProtocolFactorySetItor end = pfs->end ();
00493 
00494   // Loop through all the loaded protocols...
00495   for (TAO_ProtocolFactorySetItor i = pfs->begin (); i != end; ++i)
00496     {
00497       // If the protocol requires an explicit -ORBEndpoint option then
00498       // don't use it, otherwise open a default endpoint for that
00499       // protocol, this solves the problem with persistent endpoints
00500       // (such as UNIX domain rendesvouz points) that are not cleaned
00501       // up if the server crashes.
00502       if (!(*i)->factory ()->requires_explicit_endpoint ())
00503         {
00504           if (this->open_default (orb_core,
00505                                   reactor,
00506                                   TAO_DEF_GIOP_MAJOR,  // default major
00507                                   TAO_DEF_GIOP_MINOR,  // default minor
00508                                   i,
00509                                   options) != 0)
00510             {
00511               return -1;
00512             }
00513 
00514           opened_endpoint = true;
00515         }
00516     }
00517 #if defined (ACE_WIN32) && defined (ACE_HAS_IPV6)
00518     }
00519 #endif /* ACE_WIN32) && ACE_HAS_IPV6 */
00520 
00521   if (!opened_endpoint)
00522     {
00523       if (TAO_debug_level > 0)
00524         {
00525           ACE_ERROR ((LM_ERROR,
00526                       ACE_TEXT ("TAO (%P|%t) No default endpoints ")
00527                       ACE_TEXT ("opened.\n")
00528                       ACE_TEXT ("Please specify one or more using ")
00529                       ACE_TEXT ("the \"-ORBListenEndpoints\" ")
00530                       ACE_TEXT ("option.\n")));
00531         }
00532 
00533       return -1;
00534     }
00535 
00536   return 0;
00537 }
00538 
00539 // Used when no endpoints were specified.  Open a default server for
00540 // the indicated protocol.
00541 int
00542 TAO_Acceptor_Registry::open_default (TAO_ORB_Core *orb_core,
00543                                      ACE_Reactor *reactor,
00544                                      int major,
00545                                      int minor,
00546                                      TAO_ProtocolFactorySetItor &factory,
00547                                      const char *options)
00548 {
00549   // No endpoints were specified, we let each protocol pick its own
00550   // default endpoint.
00551 
00552   // Make an acceptor
00553   TAO_Acceptor *acceptor = (*factory)->factory ()->make_acceptor ();
00554 
00555   if (acceptor == 0)
00556     {
00557       if (TAO_debug_level > 0)
00558         {
00559           ACE_ERROR ((
00560               LM_ERROR,
00561               ACE_TEXT ("TAO (%P|%t) unable to create ")
00562               ACE_TEXT ("an acceptor for <%s>\n"),
00563               ACE_TEXT_CHAR_TO_TCHAR ((*factory)->protocol_name ().c_str ())
00564             ));
00565         }
00566 
00567       return -1;
00568     }
00569 
00570   return this->open_default_i (orb_core,
00571                                reactor,
00572                                major,
00573                                minor,
00574                                factory,
00575                                acceptor,
00576                                options);
00577 }
00578 
00579 // Open a default server.
00580 int
00581 TAO_Acceptor_Registry::open_default_i (TAO_ORB_Core *orb_core,
00582                                        ACE_Reactor *reactor,
00583                                        int major,
00584                                        int minor,
00585                                        TAO_ProtocolFactorySetItor &factory,
00586                                        TAO_Acceptor* acceptor,
00587                                        const char *options)
00588 {
00589   // Initialize the acceptor to listen on a default endpoint.
00590   if (acceptor->open_default (orb_core, reactor, major, minor, options) == -1)
00591     {
00592       delete acceptor;
00593 
00594       if (TAO_debug_level > 0)
00595         {
00596           ACE_ERROR ((
00597               LM_ERROR,
00598               ACE_TEXT ("TAO (%P|%t) unable to open ")
00599               ACE_TEXT ("default acceptor for <%C>%p\n"),
00600               (*factory)->protocol_name ().c_str (),
00601               ACE_TEXT ("")
00602             ));
00603         }
00604 
00605       return -1;
00606     }
00607 
00608   this->acceptors_[this->size_++] = acceptor;
00609 
00610   return 0;
00611 }
00612 
00613 int
00614 TAO_Acceptor_Registry::close_all (void)
00615 {
00616   const TAO_AcceptorSetIterator end = this->end ();
00617 
00618   for (TAO_AcceptorSetIterator i = this->begin (); i != end; ++i)
00619     {
00620       if (*i != 0)
00621         {
00622           (*i)->close ();
00623           delete *i;
00624         }
00625     }
00626 
00627   this->size_ = 0;
00628   return 0;
00629 }
00630 
00631 void
00632 TAO_Acceptor_Registry::extract_endpoint_options (ACE_CString &addrs,
00633                                                  ACE_CString &options,
00634                                                  TAO_Protocol_Factory *factory)
00635 {
00636   ACE_CString::size_type const options_index =
00637     addrs.find (factory->options_delimiter ());
00638 
00639   if (options_index == addrs.length () - 1)
00640     {
00641       // Get rid of trailing option delimiter.
00642       addrs = addrs.substring (0, addrs.length () - 1);
00643     }
00644   else if (options_index != ACE_CString::npos)
00645     {
00646       options = addrs.substring (options_index + 1);
00647       addrs = addrs.substring (0, options_index);
00648     }
00649 }
00650 
00651 void
00652 TAO_Acceptor_Registry::extract_endpoint_version (ACE_CString &address,
00653                                                  int &major,
00654                                                  int &minor)
00655 {
00656   // Check if an "N.n@" version prefix was
00657   // specified.
00658   major = TAO_DEF_GIOP_MAJOR;
00659   minor = TAO_DEF_GIOP_MINOR;
00660 
00661   if (ACE_OS::ace_isdigit (address[0])
00662       && address[1] == '.'
00663       && ACE_OS::ace_isdigit (address[2])
00664       && address[3] == '@')
00665     {
00666       major = address[0] - '0';
00667       minor = address[2] - '0';
00668       address = address.substring (4);
00669     }
00670 }
00671 
00672 int
00673 TAO_Acceptor_Registry::open_i (TAO_ORB_Core *orb_core,
00674                                ACE_Reactor *reactor,
00675                                ACE_CString &addrs,
00676                                TAO_ProtocolFactorySetItor &factory,
00677                                bool ignore_address)
00678 {
00679   ACE_CString options_tmp;
00680   this->extract_endpoint_options (addrs, options_tmp, (*factory)->factory ());
00681 
00682   const char *options = 0;
00683 
00684   if (options_tmp.length () > 0)
00685     {
00686       options = options_tmp.c_str ();
00687     }
00688 
00689   char *last_addr = 0;
00690   ACE_Auto_Basic_Array_Ptr<char> addr_str (addrs.rep ());
00691 
00692   const char *astr = ACE_OS::strtok_r (addr_str.get (), ",", &last_addr);
00693 
00694   // Iterate over the addrs specified in the endpoint.
00695 
00696   do
00697     {
00698       // For the first time only through the loop, it is
00699       // possible for astr to be 0.  This indicates that
00700       // the user is requesting the default endpoint for
00701       // the specified protocol.
00702       ACE_CString address (astr == 0 ? "" : astr);
00703 
00704       TAO_Acceptor *acceptor = (*factory)->factory ()->make_acceptor ();
00705 
00706       if (acceptor != 0)
00707         {
00708           // Extract the desired endpoint/protocol version if one
00709           // exists.
00710           int major = TAO_DEF_GIOP_MAJOR;
00711           int minor = TAO_DEF_GIOP_MINOR;
00712           this->extract_endpoint_version (address, major, minor);
00713 
00714           // Check for existence of endpoint.
00715           if (ignore_address || address.length () == 0)
00716             {
00717               // Protocol prefix was specified without any endpoints.
00718               // All TAO pluggable protocols are expected to have the
00719               // ability to create a default endpoint.
00720 #if defined (ACE_WIN32) && defined (ACE_HAS_IPV6)
00721               if ((*factory)->factory ()->tag () == IOP::TAG_INTERNET_IOP)
00722                 {
00723                   // Open first acceptor on IPv4 ANY
00724                   ACE_INET_Addr addr(static_cast<unsigned short> (0)); // IPv4 ANY
00725 
00726                   TAO_IIOP_Acceptor* iiop_acceptor = dynamic_cast<TAO_IIOP_Acceptor*> (acceptor);
00727 
00728                   if (!iiop_acceptor)
00729                     return -1;
00730 
00731                   iiop_acceptor->set_default_address (addr);
00732 
00733                   if (this->open_default_i (orb_core,
00734                                             reactor,
00735                                             major,
00736                                             minor,
00737                                             factory,
00738                                             acceptor,
00739                                             options) == 0)
00740                     {
00741                       // record the port chosen for the IPv4 acceptor
00742                       u_short port = iiop_acceptor->default_address ().get_port_number ();
00743 
00744                       // Create second acceptor for IPV6 traffic
00745                       acceptor =
00746                         (*factory)->factory ()->make_acceptor ();
00747 
00748                       if (acceptor == 0)
00749                         {
00750                           if (TAO_debug_level > 0)
00751                             {
00752                               ACE_ERROR ((
00753                                   LM_ERROR,
00754                                   ACE_TEXT ("TAO (%P|%t) unable to create ")
00755                                   ACE_TEXT ("an acceptor for <%s>\n"),
00756                                   ACE_TEXT_CHAR_TO_TCHAR ((*factory)->protocol_name ().c_str ())
00757                                 ));
00758                             }
00759 
00760                           throw ::CORBA::NO_MEMORY (
00761                             CORBA::SystemException::_tao_minor_code (
00762                               TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE,
00763                               ENOMEM),
00764                             CORBA::COMPLETED_NO);
00765                         }
00766 
00767                       addr.set (port, ACE_IPV6_ANY, AF_INET6); // IPv6 ANY on specified port
00768 
00769                       iiop_acceptor = dynamic_cast<TAO_IIOP_Acceptor*> (acceptor);
00770                       if (!iiop_acceptor)
00771                         return -1;
00772 
00773                       iiop_acceptor->set_default_address (addr);
00774 
00775                       if (this->open_default_i (orb_core,
00776                                                 reactor,
00777                                                 major,
00778                                                 minor,
00779                                                 factory,
00780                                                 acceptor,
00781                                                 options) == 0)
00782                         {
00783                           continue;
00784                         }
00785                     }
00786 
00787                 }
00788               else
00789                 {
00790                   if (this->open_default_i (orb_core,
00791                                             reactor,
00792                                             major,
00793                                             minor,
00794                                             factory,
00795                                             acceptor,
00796                                             options) == 0)
00797                     {
00798                       continue;
00799                     }
00800                 }
00801 
00802               // Could not open a default endpoint, nor an explicit
00803               // one.
00804               throw ::CORBA::INTERNAL (
00805                 CORBA::SystemException::_tao_minor_code (
00806                   TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE,
00807                   0),
00808                 CORBA::COMPLETED_NO);
00809 #else /* ACE_WIN32 && ACE_HAS_IPV6 */
00810               if (this->open_default_i (orb_core,
00811                                         reactor,
00812                                         major,
00813                                         minor,
00814                                         factory,
00815                                         acceptor,
00816                                         options) == 0)
00817                 continue;
00818 
00819               // Could not open a default endpoint, nor an explicit
00820               // one.
00821               else
00822                 {
00823                   throw ::CORBA::INTERNAL (
00824                     CORBA::SystemException::_tao_minor_code (
00825                       TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE,
00826                       0),
00827                     CORBA::COMPLETED_NO);
00828                 }
00829 #endif /* !ACE_WIN32 || !ACE_HAS_IPV6 */
00830             }
00831           // An explicit endpoint was provided.
00832           else if (acceptor->open (orb_core,
00833                                    reactor,
00834                                    major,
00835                                    minor,
00836                                    address.c_str (),
00837                                    options) == -1)
00838             {
00839               /* Need to save the errno value from the acceptor->open(),
00840                * because errno will get reset when we delete acceptor */
00841               int const errno_value = errno;
00842               delete acceptor;
00843 
00844               if (TAO_debug_level > 0)
00845                 {
00846                   ACE_ERROR ((LM_ERROR,
00847                               ACE_TEXT ("TAO (%P|%t) ")
00848                               ACE_TEXT ("unable to open acceptor ")
00849                               ACE_TEXT ("for <%s>%p\n"),
00850                               ACE_TEXT_CHAR_TO_TCHAR (address.c_str ()),
00851                               ACE_TEXT ("")));
00852                 }
00853 
00854               throw ::CORBA::BAD_PARAM (
00855                 CORBA::SystemException::_tao_minor_code (
00856                   TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE,
00857                   errno_value),
00858                 CORBA::COMPLETED_NO);
00859             }
00860 
00861           // add acceptor to list
00862           this->acceptors_[this->size_++] = acceptor;
00863         }
00864       else
00865         {
00866           if (TAO_debug_level > 0)
00867             {
00868               ACE_ERROR ((LM_ERROR,
00869                           ACE_TEXT ("TAO (%P|%t) unable to create ")
00870                           ACE_TEXT ("an acceptor for <%s>.\n"),
00871                           ACE_TEXT_CHAR_TO_TCHAR (address.c_str ())));
00872             }
00873 
00874           throw ::CORBA::NO_MEMORY (
00875             CORBA::SystemException::_tao_minor_code (
00876               TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE,
00877               ENOMEM),
00878             CORBA::COMPLETED_NO);
00879         }
00880     }
00881   while (astr != 0 && (astr = ACE_OS::strtok_r (0, ",", &last_addr)) != 0);
00882 
00883   return 0;
00884 }
00885 
00886 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:37:51 2010 for TAO by  doxygen 1.4.7