Acceptor_Registry.cpp

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