Acceptor_Registry.cpp

Go to the documentation of this file.
00001 // $Id: Acceptor_Registry.cpp 79109 2007-07-31 07:23:49Z 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 79109 2007-07-31 07:23:49Z 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               const int 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 =
00554     (*factory)->factory ()->make_acceptor ();
00555 
00556   if (acceptor == 0)
00557     {
00558       if (TAO_debug_level > 0)
00559         {
00560           ACE_ERROR ((
00561               LM_ERROR,
00562               ACE_TEXT ("TAO (%P|%t) unable to create ")
00563               ACE_TEXT ("an acceptor for <%s>\n"),
00564               ACE_TEXT_CHAR_TO_TCHAR ((*factory)->protocol_name ().c_str ())
00565             ));
00566         }
00567 
00568       return -1;
00569     }
00570 
00571   return this->open_default_i (orb_core,
00572                                reactor,
00573                                major,
00574                                minor,
00575                                factory,
00576                                acceptor,
00577                                options);
00578 }
00579 
00580 // Open a default server.
00581 int
00582 TAO_Acceptor_Registry::open_default_i (TAO_ORB_Core *orb_core,
00583                                        ACE_Reactor *reactor,
00584                                        int major,
00585                                        int minor,
00586                                        TAO_ProtocolFactorySetItor &factory,
00587                                        TAO_Acceptor* acceptor,
00588                                        const char *options)
00589 {
00590   // Initialize the acceptor to listen on a default endpoint.
00591   if (acceptor->open_default (orb_core,
00592                               reactor,
00593                               major,
00594                               minor,
00595                               options) == -1)
00596     {
00597       delete acceptor;
00598 
00599       if (TAO_debug_level > 0)
00600         {
00601           ACE_ERROR ((
00602               LM_ERROR,
00603               ACE_TEXT ("TAO (%P|%t) unable to open ")
00604               ACE_TEXT ("default acceptor for <%s>%p\n"),
00605               ACE_TEXT_CHAR_TO_TCHAR ((*factory)->protocol_name ().c_str ()),
00606               ACE_TEXT ("")
00607             ));
00608         }
00609 
00610       return -1;
00611     }
00612 
00613   this->acceptors_[this->size_++] = acceptor;
00614 
00615   return 0;
00616 }
00617 
00618 int
00619 TAO_Acceptor_Registry::close_all (void)
00620 {
00621   const TAO_AcceptorSetIterator end = this->end ();
00622 
00623   for (TAO_AcceptorSetIterator i = this->begin (); i != end; ++i)
00624     {
00625       if (*i == 0)
00626         {
00627           continue;
00628         }
00629 
00630       (*i)->close ();
00631 
00632       delete *i;
00633     }
00634 
00635   this->size_ = 0;
00636   return 0;
00637 }
00638 
00639 void
00640 TAO_Acceptor_Registry::extract_endpoint_options (ACE_CString &addrs,
00641                                                  ACE_CString &options,
00642                                                  TAO_Protocol_Factory *factory)
00643 {
00644   ACE_CString::size_type const options_index =
00645     addrs.find (factory->options_delimiter ());
00646 
00647   if (options_index == addrs.length () - 1)
00648     {
00649       // Get rid of trailing option delimiter.
00650       addrs = addrs.substring (0, addrs.length () - 1);
00651     }
00652   else if (options_index != ACE_CString::npos)
00653     {
00654       options = addrs.substring (options_index + 1);
00655       addrs = addrs.substring (0, options_index);
00656     }
00657 }
00658 
00659 void
00660 TAO_Acceptor_Registry::extract_endpoint_version (ACE_CString &address,
00661                                                  int &major,
00662                                                  int &minor)
00663 {
00664   // Check if an "N.n@" version prefix was
00665   // specified.
00666   major = TAO_DEF_GIOP_MAJOR;
00667   minor = TAO_DEF_GIOP_MINOR;
00668 
00669   if (ACE_OS::ace_isdigit (address[0])
00670       && address[1] == '.'
00671       && ACE_OS::ace_isdigit (address[2])
00672       && address[3] == '@')
00673     {
00674       major = address[0] - '0';
00675       minor = address[2] - '0';
00676       address = address.substring (4);
00677     }
00678 }
00679 
00680 int
00681 TAO_Acceptor_Registry::open_i (TAO_ORB_Core *orb_core,
00682                                ACE_Reactor *reactor,
00683                                ACE_CString &addrs,
00684                                TAO_ProtocolFactorySetItor &factory,
00685                                bool ignore_address)
00686 {
00687   ACE_CString options_tmp;
00688   this->extract_endpoint_options (addrs,
00689                                   options_tmp,
00690                                   (*factory)->factory ());
00691 
00692   const char *options = 0;
00693 
00694   if (options_tmp.length () > 0)
00695     options = options_tmp.c_str ();
00696 
00697   char *last_addr = 0;
00698   ACE_Auto_Basic_Array_Ptr<char> addr_str (addrs.rep ());
00699 
00700   const char *astr = ACE_OS::strtok_r (addr_str.get (),
00701                                        ",",
00702                                        &last_addr);
00703 
00704   // Iterate over the addrs specified in the endpoint.
00705 
00706   do
00707     {
00708       // For the first time only through the loop, it is
00709       // possible for astr to be 0.  This indicates that
00710       // the user is requesting the default endpoint for
00711       // the specified protocol.
00712       ACE_CString address (astr == 0 ? "" : astr);
00713 
00714       TAO_Acceptor *acceptor =
00715         (*factory)->factory ()->make_acceptor ();
00716 
00717       if (acceptor != 0)
00718         {
00719           // Extract the desired endpoint/protocol version if one
00720           // exists.
00721           int major = TAO_DEF_GIOP_MAJOR;
00722           int minor = TAO_DEF_GIOP_MINOR;
00723           this->extract_endpoint_version (address,
00724                                           major,
00725                                           minor);
00726 
00727           // Check for existence of endpoint.
00728           if (ignore_address || address.length () == 0)
00729             {
00730               // Protocol prefix was specified without any endpoints.
00731               // All TAO pluggable protocols are expected to have the
00732               // ability to create a default endpoint.
00733 #if defined (ACE_WIN32) && defined (ACE_HAS_IPV6)
00734               if ((*factory)->factory ()->tag () == IOP::TAG_INTERNET_IOP)
00735                 {
00736                   // Open first acceptor on IPv4 ANY
00737                   ACE_INET_Addr addr(static_cast<unsigned short> (0)); // IPv4 ANY
00738 
00739                   TAO_IIOP_Acceptor* iiop_acceptor = dynamic_cast<TAO_IIOP_Acceptor*> (acceptor);
00740 
00741                   if (!iiop_acceptor)
00742                     return -1;
00743 
00744                   iiop_acceptor->set_default_address (addr);
00745 
00746                   if (this->open_default_i (orb_core,
00747                                             reactor,
00748                                             major,
00749                                             minor,
00750                                             factory,
00751                                             acceptor,
00752                                             options) == 0)
00753                     {
00754                       // record the port chosen for the IPv4 acceptor
00755                       u_short port = iiop_acceptor->default_address ().get_port_number ();
00756 
00757                       // Create second acceptor for IPV6 traffic
00758                       acceptor =
00759                         (*factory)->factory ()->make_acceptor ();
00760 
00761                       if (acceptor == 0)
00762                         {
00763                           if (TAO_debug_level > 0)
00764                             {
00765                               ACE_ERROR ((
00766                                   LM_ERROR,
00767                                   ACE_TEXT ("TAO (%P|%t) unable to create ")
00768                                   ACE_TEXT ("an acceptor for <%s>\n"),
00769                                   ACE_TEXT_CHAR_TO_TCHAR ((*factory)->protocol_name ().c_str ())
00770                                 ));
00771                             }
00772 
00773                           throw ::CORBA::NO_MEMORY (
00774                             CORBA::SystemException::_tao_minor_code (
00775                               TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE,
00776                               ENOMEM),
00777                             CORBA::COMPLETED_NO);
00778                         }
00779 
00780                       addr.set (port, ACE_IPV6_ANY, AF_INET6); // IPv6 ANY on specified port
00781 
00782                       iiop_acceptor = dynamic_cast<TAO_IIOP_Acceptor*> (acceptor);
00783                       if (!iiop_acceptor)
00784                         return -1;
00785 
00786                       iiop_acceptor->set_default_address (addr);
00787 
00788                       if (this->open_default_i (orb_core,
00789                                                 reactor,
00790                                                 major,
00791                                                 minor,
00792                                                 factory,
00793                                                 acceptor,
00794                                                 options) == 0)
00795                         {
00796                           continue;
00797                         }
00798                     }
00799 
00800                 }
00801               else
00802                 {
00803                   if (this->open_default_i (orb_core,
00804                                             reactor,
00805                                             major,
00806                                             minor,
00807                                             factory,
00808                                             acceptor,
00809                                             options) == 0)
00810                     {
00811                       continue;
00812                     }
00813                 }
00814 
00815               // Could not open a default endpoint, nor an explicit
00816               // one.
00817               throw ::CORBA::INTERNAL (
00818                 CORBA::SystemException::_tao_minor_code (
00819                   TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE,
00820                   0),
00821                 CORBA::COMPLETED_NO);
00822 #else /* ACE_WIN32 && ACE_HAS_IPV6 */
00823               if (this->open_default_i (orb_core,
00824                                         reactor,
00825                                         major,
00826                                         minor,
00827                                         factory,
00828                                         acceptor,
00829                                         options) == 0)
00830                 continue;
00831 
00832               // Could not open a default endpoint, nor an explicit
00833               // one.
00834               else
00835                 {
00836                   throw ::CORBA::INTERNAL (
00837                     CORBA::SystemException::_tao_minor_code (
00838                       TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE,
00839                       0),
00840                     CORBA::COMPLETED_NO);
00841                 }
00842 #endif /* !ACE_WIN32 || !ACE_HAS_IPV6 */
00843             }
00844           // An explicit endpoint was provided.
00845           else if (acceptor->open (orb_core,
00846                                    reactor,
00847                                    major,
00848                                    minor,
00849                                    address.c_str (),
00850                                    options) == -1)
00851             {
00852               /* Need to save the errno value from the acceptor->open(),
00853                * because errno will get reset when we delete acceptor */
00854               const int errno_value = errno;
00855               delete acceptor;
00856 
00857               if (TAO_debug_level > 0)
00858                 {
00859                   ACE_ERROR ((LM_ERROR,
00860                               ACE_TEXT ("TAO (%P|%t) ")
00861                               ACE_TEXT ("unable to open acceptor ")
00862                               ACE_TEXT ("for <%s>%p\n"),
00863                               ACE_TEXT_CHAR_TO_TCHAR (address.c_str ()),
00864                               ACE_TEXT ("")));
00865                 }
00866 
00867               throw ::CORBA::BAD_PARAM (
00868                 CORBA::SystemException::_tao_minor_code (
00869                   TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE,
00870                   errno_value),
00871                 CORBA::COMPLETED_NO);
00872             }
00873 
00874           // add acceptor to list
00875           this->acceptors_[this->size_++] = acceptor;
00876         }
00877       else
00878         {
00879           if (TAO_debug_level > 0)
00880             {
00881               ACE_ERROR ((LM_ERROR,
00882                           ACE_TEXT ("TAO (%P|%t) unable to create ")
00883                           ACE_TEXT ("an acceptor for <%s>.\n"),
00884                           ACE_TEXT_CHAR_TO_TCHAR (address.c_str ())));
00885             }
00886 
00887           throw ::CORBA::NO_MEMORY (
00888             CORBA::SystemException::_tao_minor_code (
00889               TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE,
00890               ENOMEM),
00891             CORBA::COMPLETED_NO);
00892         }
00893     }
00894   while (astr != 0 && (astr = ACE_OS::strtok_r (0, ",", &last_addr)) != 0);
00895 
00896   return 0;
00897 }
00898 
00899 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Sun Jan 27 13:07:31 2008 for TAO by doxygen 1.3.6