TAO_MCAST_Parser Class Reference

Implements the mcast: IOR format. More...

#include <MCAST_Parser.h>

Inheritance diagram for TAO_MCAST_Parser:

Inheritance graph
[legend]
Collaboration diagram for TAO_MCAST_Parser:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 TAO_MCAST_Parser (void)
 Constructor.

virtual ~TAO_MCAST_Parser (void)
 The destructor.

virtual int match_prefix (const char *ior_string) const
virtual CORBA::Object_ptr parse_string (const char *ior, CORBA::ORB_ptr orb) throw (CORBA::SystemException)
 Parse the ior-string that is passed.


Private Member Functions

CORBA::Object_ptr multicast_to_service (const char *service_name, CORBA::UShort port, const char *mcast_address, const char *mcast_ttl, const char *mcast_nic, CORBA::ORB_ptr orb, ACE_Time_Value *timeout)
int multicast_query (char *&buf, const char *service_name, u_short port, const char *mcast_address, const char *mcast_ttl, const char *mcast_nic, ACE_Time_Value *timeout, CORBA::ORB_ptr orb)
void assign_to_variables (const char *&mcast_name_ptr)

Private Attributes

CORBA::String_var mcast_address_
CORBA::String_var mcast_port_
CORBA::String_var mcast_nic_
CORBA::String_var mcast_ttl_
CORBA::String_var service_name_

Detailed Description

Implements the mcast: IOR format.

This class implements the mcast: IOR format. It is dynamically loaded by the ORB and used to parse the string to separate the individual from the list of object addresses .

Definition at line 39 of file MCAST_Parser.h.


Constructor & Destructor Documentation

TAO_BEGIN_VERSIONED_NAMESPACE_DECL ACE_INLINE TAO_MCAST_Parser::TAO_MCAST_Parser void   ) 
 

Constructor.

Definition at line 8 of file MCAST_Parser.i.

00009 {
00010 }

TAO_BEGIN_VERSIONED_NAMESPACE_DECL TAO_MCAST_Parser::~TAO_MCAST_Parser void   )  [virtual]
 

The destructor.

Definition at line 28 of file MCAST_Parser.cpp.

00029 {
00030 }


Member Function Documentation

void TAO_MCAST_Parser::assign_to_variables const char *&  mcast_name_ptr  )  [private]
 

Definition at line 364 of file MCAST_Parser.cpp.

References ACE_CString, ACE_DEBUG, ACE_DEFAULT_MULTICAST_ADDR, ACE_DEFAULT_MULTICASTV6_ADDR, ACE_TEXT, ACE_OS::itoa(), LM_ERROR, mcast_address_, mcast_nic_, mcast_port_, mcast_ttl_, ssize_t, TAO_debug_level, TAO_DEFAULT_IMPLREPO_SERVER_REQUEST_PORT, TAO_DEFAULT_INTERFACEREPO_SERVER_REQUEST_PORT, TAO_DEFAULT_NAME_SERVER_REQUEST_PORT, and TAO_DEFAULT_TRADING_SERVER_REQUEST_PORT.

00365 {
00366   /*
00367    * The format now is "multicast_address:port:nicaddress:ttl/object_key"
00368    */
00369   ACE_CString mcast_name_cstring (mcast_name);
00370 
00371   ssize_t pos_colon1 = mcast_name_cstring.find (':', 0);
00372 #if defined (ACE_HAS_IPV6)
00373   // IPv6 numeric address in host string?
00374   bool ipv6_in_host = false;
00375 
00376   // Check if this is an mcast address containing a
00377   // decimal IPv6 address representation.
00378   if (mcast_name_cstring[0] == '[')
00379     {
00380       // In this case we have to find the end of the numeric address and
00381       // start looking for the port separator from there.
00382       int cp_pos = mcast_name_cstring.find (']', 0);
00383       if (cp_pos == 0)
00384         {
00385           // No valid IPv6 address specified.
00386           if (TAO_debug_level > 0)
00387             {
00388               ACE_DEBUG ((LM_ERROR,
00389                           ACE_TEXT ("\nTAO (%P|%t) MCAST_Parser: ")
00390                           ACE_TEXT ("Invalid IPv6 decimal address specified.\n")));
00391             }
00392 
00393           return;
00394         }
00395       else
00396         {
00397           if (mcast_name_cstring[cp_pos + 1] == ':')    // Look for a port
00398             pos_colon1 = cp_pos + 1;
00399           else
00400             pos_colon1 = cp_pos;
00401           ipv6_in_host = true; // host string contains full IPv6 numeric address
00402         }
00403     }
00404 #endif  /* ACE_HAS_IPV6 */
00405 
00406   if (pos_colon1 == 0)
00407     {
00408 #if defined (ACE_HAS_IPV6)
00409       const char *default_addr = ACE_DEFAULT_MULTICASTV6_ADDR;
00410 #else /* ACE_HAS_IPV6 */
00411       const char *default_addr = ACE_DEFAULT_MULTICAST_ADDR;
00412 #endif  /* !ACE_HAS_IPV6 */
00413       this->mcast_address_ = default_addr;
00414     }
00415   else
00416     {
00417 #if defined (ACE_HAS_IPV6)
00418       if (ipv6_in_host)
00419         this->mcast_address_ =
00420           mcast_name_cstring.substring (1,
00421                                         pos_colon1 - 2).c_str ();
00422       else
00423 #endif  /* ACE_HAS_IPV6 */
00424       this->mcast_address_ =
00425         mcast_name_cstring.substring (0,
00426                                       pos_colon1).c_str ();
00427     }
00428   mcast_name_cstring =
00429     mcast_name_cstring.substring (pos_colon1 + 1,
00430                                   mcast_name_cstring.length() -
00431                                   pos_colon1);
00432 
00433   ssize_t pos_colon2 = mcast_name_cstring.find (':', 0);
00434 
00435   if (pos_colon2 == 0)
00436     {
00437       /*
00438        * If the port is not specified, use the default.
00439        * The default multicast port is the same as the default port
00440        * no. for Naming_Service, for now. But for other services,
00441        * check and modify the default values as needed.
00442        */
00443       char default_port[33];
00444 
00445       int trial_port = TAO_DEFAULT_NAME_SERVER_REQUEST_PORT;
00446 
00447       if (mcast_name_cstring.find ("InterfaceRepository") !=
00448           ACE_CString::npos)
00449         {
00450           trial_port = TAO_DEFAULT_INTERFACEREPO_SERVER_REQUEST_PORT;
00451         }
00452       else if (mcast_name_cstring.find ("ImplRepoService") !=
00453                ACE_CString::npos)
00454         {
00455            trial_port = TAO_DEFAULT_IMPLREPO_SERVER_REQUEST_PORT;
00456         }
00457       else if (mcast_name_cstring.find ("TradingService") !=
00458                ACE_CString::npos)
00459         {
00460            trial_port = TAO_DEFAULT_TRADING_SERVER_REQUEST_PORT;
00461         }
00462 
00463 
00464       ACE_OS::itoa (trial_port, default_port, 10);
00465 
00466       this->mcast_port_ = (const char *) default_port;
00467     }
00468   else
00469     {
00470       this->mcast_port_ = mcast_name_cstring.substring (0,
00471                                                         pos_colon2).c_str ();
00472     }
00473 
00474   mcast_name_cstring =
00475     mcast_name_cstring.substring (pos_colon2 + 1,
00476                                   mcast_name_cstring.length() - pos_colon2);
00477 
00478 
00479   ssize_t pos_colon3 = mcast_name_cstring.find (':', 0);
00480 
00481   this->mcast_nic_ =
00482     mcast_name_cstring.substring (0,
00483                                   pos_colon3).c_str ();
00484 
00485   mcast_name_cstring =
00486     mcast_name_cstring.substring (pos_colon3 + 1,
00487                                   mcast_name_cstring.length() - pos_colon3);
00488 
00489   ssize_t pos_colon4 = mcast_name_cstring.find ('/', 0);
00490 
00491   if (pos_colon4 == 0)
00492     {
00493       // And, the default TTL to be 1
00494       const char *default_ttl = "1";
00495       this->mcast_ttl_ = default_ttl;
00496     }
00497   else
00498     {
00499       this->mcast_ttl_ =
00500         mcast_name_cstring.substring (0,
00501                                       pos_colon4).c_str ();
00502     }
00503   mcast_name_cstring =
00504     mcast_name_cstring.substring (pos_colon4,
00505                                   mcast_name_cstring.length() - pos_colon4);
00506 
00507   this->service_name_ =
00508     mcast_name_cstring.substring (1,
00509                                   mcast_name_cstring.length()
00510                                   -1).c_str ();
00511 }

int TAO_MCAST_Parser::match_prefix const char *  ior_string  )  const [virtual]
 

= The IOR_Parser methods, please read the documentation in IOR_Parser.h

Implements TAO_IOR_Parser.

Definition at line 33 of file MCAST_Parser.cpp.

References mcast_prefix, and ACE_OS::strncmp().

00034 {
00035   return (ACE_OS::strncmp (ior_string,
00036                            ::mcast_prefix,
00037                            sizeof (::mcast_prefix) - 1) == 0);
00038 }

int TAO_MCAST_Parser::multicast_query char *&  buf,
const char *  service_name,
u_short  port,
const char *  mcast_address,
const char *  mcast_ttl,
const char *  mcast_nic,
ACE_Time_Value timeout,
CORBA::ORB_ptr  orb
[private]
 

Definition at line 122 of file MCAST_Parser.cpp.

References ACE_SOCK_Acceptor::accept(), ACE_CString, ACE_DEBUG, ACE_ERROR, ACE_HTONS, ACE_NTOHS, ACE_TCHAR, ACE_TEXT, ACE_TEXT_CHAR_TO_TCHAR, ACE_INET_Addr::addr_to_string(), ACE_OS::atoi(), ACE_SOCK_Acceptor::close(), ACE_SOCK::close(), ACE_SOCK_Stream::close(), ACE_SOCK::get_local_addr(), ACE_INET_Addr::get_port_number(), ACE_Addr::get_type(), iovec::iov_base, iovec::iov_len, IP_MULTICAST_TTL, LM_DEBUG, LM_ERROR, TAO_ORB_Parameters::mcast_discovery_endpoint(), ACE_SOCK_Dgram::open(), ACE_SOCK_Acceptor::open(), CORBA::ORB::orb_core(), TAO_ORB_Core::orb_params(), CORBA::ORB_ptr, ACE_SOCK_Stream::recv_n(), ACE_SOCK_Dgram::send(), ACE_INET_Addr::set(), ACE_SOCK_Dgram::set_nic(), ACE_SOCK::set_option(), ssize_t, ACE_OS::strcasecmp(), CORBA::string_alloc(), ACE_OS::strlen(), TAO_debug_level, TAO_DEFAULT_IOR_SIZE, and TAO_DEFAULT_SERVICE_RESOLUTION_TIMEOUT.

00130 {
00131   ACE_INET_Addr my_addr;
00132   ACE_SOCK_Acceptor acceptor;
00133   ACE_SOCK_Stream stream;
00134   ACE_SOCK_Dgram dgram;
00135 
00136   ssize_t result = 0;
00137 
00138   // Bind listener to any port and then find out what the port was.
00139 #if defined (ACE_HAS_IPV6)
00140   if (acceptor.open (ACE_Addr::sap_any, 0, AF_INET6) == -1
00141 #else /* ACE_HAS_IPV6 */
00142   if (acceptor.open (ACE_Addr::sap_any) == -1
00143 #endif /* !ACE_HAS_IPV6 */
00144       || acceptor.get_local_addr (my_addr) == -1)
00145     {
00146       ACE_ERROR ((LM_ERROR,
00147                   ACE_TEXT ("acceptor.open () || ")
00148                   ACE_TEXT ("acceptor.get_local_addr () failed\n")));
00149       result = -1;
00150     }
00151   else
00152     {
00153       if (TAO_debug_level > 0)
00154         {
00155           ACE_TCHAR addr[64];
00156           my_addr.addr_to_string (addr, sizeof(addr));
00157           ACE_DEBUG ((LM_DEBUG,
00158                       "(%P|%t) TAO_MCAST_Parser: acceptor local address %s.\n",
00159                       addr));
00160         }
00161 
00162       ACE_INET_Addr multicast_addr (port,
00163                                     mcast_address);
00164 
00165       // Set the address if multicast_discovery_endpoint option
00166       // is specified for the Naming Service.
00167       ACE_CString mde (orb->orb_core ()->orb_params ()
00168                        ->mcast_discovery_endpoint ());
00169 
00170       if (ACE_OS::strcasecmp (service_name,
00171                               "NameService") == 0
00172           && mde.length () != 0)
00173         if (multicast_addr.set (mde.c_str()) == -1)
00174           {
00175             ACE_ERROR ((LM_ERROR,
00176                         ACE_TEXT("ORB.cpp: Multicast address setting failed\n")));
00177             stream.close ();
00178             dgram.close ();
00179             acceptor.close ();
00180             return -1;
00181           }
00182 
00183       // Open the datagram.
00184       if (dgram.open (ACE_Addr::sap_any) == -1)
00185         {
00186           ACE_ERROR ((LM_ERROR,
00187                       ACE_TEXT ("Unable to open the Datagram!\n")));
00188           result = -1;
00189         }
00190       else
00191         {
00192           // Set NIC
00193           dgram.set_nic (ACE_TEXT_CHAR_TO_TCHAR (mcast_nic),
00194                          multicast_addr.get_type ());
00195 
00196           // Set TTL
00197           int mcast_ttl_optval = ACE_OS::atoi (mcast_ttl);
00198 
00199 #if defined (ACE_HAS_IPV6)
00200           if (multicast_addr.get_type () == AF_INET6)
00201             {
00202               if (dgram.set_option (
00203                     IPPROTO_IPV6,
00204                     IPV6_MULTICAST_HOPS,
00205                     &mcast_ttl_optval,
00206                     sizeof (mcast_ttl_optval)) != 0)
00207                 return -1;
00208             }
00209           else
00210 #endif  /* ACE_HAS_IPV6 */
00211           if (dgram.set_option (
00212                 IPPROTO_IP,
00213                 IP_MULTICAST_TTL,
00214                 &mcast_ttl_optval,
00215                 sizeof (mcast_ttl_optval)) != 0)
00216             result = -1;
00217 
00218           // Convert the acceptor port into network byte order.
00219           ACE_UINT16 response_port =
00220             (ACE_UINT16) ACE_HTONS (my_addr.get_port_number ());
00221 
00222           // Length of service name we will send.
00223           CORBA::Short data_len =
00224             (CORBA::Short) ACE_HTONS (ACE_OS::strlen (service_name) + 1);
00225 
00226           // Vector we will send.  It contains: 1) length of service
00227           // name string, 2)port on which we are listening for
00228           // replies, and 3) name of service we are looking for.
00229           const int iovcnt = 3;
00230           iovec iovp[iovcnt];
00231 
00232           // The length of service name string.
00233           iovp[0].iov_base = (char *) &data_len;
00234           iovp[0].iov_len  = sizeof (CORBA::Short);
00235 
00236           // The port at which we are listening.
00237           iovp[1].iov_base = (char *) &response_port;
00238           iovp[1].iov_len  = sizeof (ACE_UINT16);
00239 
00240           // The service name string.
00241           iovp[2].iov_base = (char *) service_name;
00242           iovp[2].iov_len  =
00243             static_cast<u_long> (ACE_OS::strlen (service_name) + 1);
00244 
00245           // Send the multicast.
00246           result = dgram.send (iovp,
00247                                iovcnt,
00248                                multicast_addr);
00249 
00250           if (TAO_debug_level > 0)
00251             ACE_DEBUG ((LM_DEBUG,
00252                         ACE_TEXT ("\nsent multicast request.")));
00253 
00254           // Check for errors.
00255           if (result == -1)
00256             ACE_ERROR ((LM_ERROR,
00257                         ACE_TEXT ("%p\n"),
00258                         ACE_TEXT ("error sending IIOP multicast")));
00259           else
00260             {
00261               if (TAO_debug_level > 0)
00262                 ACE_DEBUG ((LM_DEBUG,
00263                             ACE_TEXT ("\n%N; Sent multicast.")
00264                             ACE_TEXT ("# of bytes sent is %d.\n"),
00265                             result));
00266               // Wait for response until timeout.
00267               ACE_Time_Value tv (
00268                 timeout == 0
00269                 ? ACE_Time_Value (TAO_DEFAULT_SERVICE_RESOLUTION_TIMEOUT)
00270                 : *timeout);
00271 
00272               // Accept reply connection from server.
00273               if (acceptor.accept (stream,
00274                                    0,
00275                                    &tv) == -1)
00276                 {
00277                   ACE_ERROR ((LM_ERROR,
00278                               ACE_TEXT ("%p\n"),
00279                               ACE_TEXT ("multicast_query: unable to accept")));
00280                   result = -1;
00281                 }
00282               else
00283                 {
00284                   // Receive the IOR.
00285 
00286                   // IOR length.
00287                   CORBA::Short ior_len;
00288                   result = stream.recv_n (&ior_len,
00289                                           sizeof ior_len,
00290                                           0,
00291                                           &tv);
00292                   if (result != sizeof (ior_len))
00293                     {
00294                       ACE_ERROR ((LM_ERROR,
00295                                   ACE_TEXT ("%p\n"),
00296                                   ACE_TEXT ("multicast_query: unable to receive ")
00297                                   ACE_TEXT ("ior length")));
00298                       result = -1;
00299                     }
00300                   else
00301                     {
00302                       // Allocate more space for the ior if we don't
00303                       // have enough.
00304                       ior_len = (CORBA::Short) ACE_NTOHS (ior_len);
00305                       if (ior_len > TAO_DEFAULT_IOR_SIZE)
00306                         {
00307                           buf = CORBA::string_alloc (ior_len);
00308                           if (buf == 0)
00309                             {
00310                               ACE_ERROR ((LM_ERROR,
00311                                           ACE_TEXT ("%p\n"),
00312                                           ACE_TEXT ("multicast_query: unable to ")
00313                                           ACE_TEXT ("allocate memory")));
00314                               result = -1;
00315                             }
00316                         }
00317 
00318                       if (result != -1)
00319                         {
00320                           // Receive the ior.
00321                           result = stream.recv_n (buf,
00322                                                   ior_len,
00323                                                   0,
00324                                                   &tv);
00325                           if (result == -1)
00326                             ACE_ERROR ((LM_ERROR,
00327                                         ACE_TEXT ( "%p\n"),
00328                                         ACE_TEXT ("error reading ior")));
00329                           else if (TAO_debug_level > 0)
00330                             ACE_DEBUG ((LM_DEBUG,
00331                                         ACE_TEXT ("%N: service resolved to IOR <%s>\n"),
00332                                         ACE_TEXT_CHAR_TO_TCHAR (buf)));
00333                         }
00334                     }
00335                 }
00336             }
00337         }
00338         if (result == -1)
00339           {
00340             ACE_ERROR ((LM_ERROR,
00341                         ACE_TEXT("\nmulticast discovery of %s failed.\n"),
00342                         ACE_TEXT_CHAR_TO_TCHAR (service_name)));
00343 
00344             if (ACE_OS::strcasecmp (service_name,
00345                                     "NameService") == 0)
00346              {
00347                ACE_ERROR ((LM_ERROR,
00348                            ACE_TEXT("Specify -m 1 when starting Naming_Service,\n")
00349                            ACE_TEXT("or see http://www.theaceorb.com/faq/#115\n")
00350                            ACE_TEXT("for using NameService without multicast.\n\n")));
00351              }
00352           }
00353     }
00354 
00355   // Clean up.
00356   stream.close ();
00357   dgram.close ();
00358   acceptor.close ();
00359 
00360   return result == -1 ? -1 : 0;
00361 }

CORBA::Object_ptr TAO_MCAST_Parser::multicast_to_service const char *  service_name,
CORBA::UShort  port,
const char *  mcast_address,
const char *  mcast_ttl,
const char *  mcast_nic,
CORBA::ORB_ptr  orb,
ACE_Time_Value timeout
[private]
 

CORBA::Object_ptr TAO_MCAST_Parser::parse_string const char *  ior,
CORBA::ORB_ptr  orb
throw (CORBA::SystemException) [virtual]
 

Parse the ior-string that is passed.

Implements TAO_IOR_Parser.

Definition at line 41 of file MCAST_Parser.cpp.

References CORBA::Object::_nil(), ACE_CHECK_RETURN, ACE_ENV_ARG_PARAMETER, ACE_OS::atoi(), CORBA::Object_ptr, and CORBA::ORB_ptr.

00045 {
00046   const char *mcast_name =
00047     ior + sizeof (::mcast_prefix) + 1;
00048 
00049   assign_to_variables (mcast_name);
00050 
00051   /*
00052    * Now that we got the global variables.
00053    * we can invoke multicast_to_service and multicast_query
00054    */
00055   CORBA::Object_ptr object = CORBA::Object::_nil ();
00056 
00057   CORBA::UShort const port =
00058     (CORBA::UShort) ACE_OS::atoi (this->mcast_port_.in ());
00059 
00060   ACE_Time_Value *timeout = orb->get_timeout ();
00061 
00062   object = multicast_to_service (service_name_.in (),
00063                                  port,
00064                                  this->mcast_address_.in (),
00065                                  this->mcast_ttl_.in (),
00066                                  this->mcast_nic_.in (),
00067                                  orb,
00068                                  timeout
00069                                   ACE_ENV_ARG_PARAMETER);
00070   ACE_CHECK_RETURN (CORBA::Object::_nil ());
00071 
00072   return object;
00073 }


Member Data Documentation

CORBA::String_var TAO_MCAST_Parser::mcast_address_ [private]
 

Definition at line 83 of file MCAST_Parser.h.

Referenced by assign_to_variables().

CORBA::String_var TAO_MCAST_Parser::mcast_nic_ [private]
 

Definition at line 85 of file MCAST_Parser.h.

Referenced by assign_to_variables().

CORBA::String_var TAO_MCAST_Parser::mcast_port_ [private]
 

Definition at line 84 of file MCAST_Parser.h.

Referenced by assign_to_variables().

CORBA::String_var TAO_MCAST_Parser::mcast_ttl_ [private]
 

Definition at line 86 of file MCAST_Parser.h.

Referenced by assign_to_variables().

CORBA::String_var TAO_MCAST_Parser::service_name_ [private]
 

Definition at line 87 of file MCAST_Parser.h.


The documentation for this class was generated from the following files:
Generated on Thu Nov 9 12:22:29 2006 for TAO by doxygen 1.3.6