Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

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 Methods

 TAO_MCAST_Parser (void)
 Constructor. More...

virtual ~TAO_MCAST_Parser (void)
 The destructor. More...

virtual int match_prefix (const char *ior_string) const
 = The IOR_Parser methods, please read the documentation in IOR_Parser.h. More...

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


Private Methods

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 ACE_ENV_ARG_DECL_NOT_USED)
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 <obj_addr> from the list of object addresses <obj_addr_list>.

Definition at line 37 of file MCAST_Parser.h.


Constructor & Destructor Documentation

ACE_INLINE TAO_MCAST_Parser::TAO_MCAST_Parser void   
 

Constructor.

Definition at line 4 of file MCAST_Parser.i.

00005 {
00006 }

TAO_MCAST_Parser::~TAO_MCAST_Parser void    [virtual]
 

The destructor.

Definition at line 24 of file MCAST_Parser.cpp.

00025 {
00026 }


Member Function Documentation

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

Definition at line 344 of file MCAST_Parser.cpp.

References ACE_CString, ACE_DEFAULT_MULTICAST_ADDR, ACE_OS_String::itoa, mcast_address_, mcast_nic_, mcast_port_, mcast_ttl_, service_name_, 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.

00345 {
00346   /*
00347    * The format now is "multicast_address:port:nicaddress:ttl/object_key"
00348    */
00349   ACE_CString mcast_name_cstring (mcast_name);
00350 
00351   int pos_colon1 = mcast_name_cstring.find (':', 0);
00352 
00353   if (pos_colon1 == 0)
00354     {
00355       const char *default_addr = ACE_DEFAULT_MULTICAST_ADDR;
00356       this->mcast_address_ = default_addr;
00357     }
00358   else
00359     {
00360       this->mcast_address_ =
00361         mcast_name_cstring.substring (0,
00362                                       pos_colon1).c_str ();
00363     }
00364   mcast_name_cstring =
00365     mcast_name_cstring.substring (pos_colon1 + 1,
00366                                   mcast_name_cstring.length() -
00367                                   pos_colon1);
00368 
00369   int pos_colon2 = mcast_name_cstring.find (':', 0);
00370 
00371   if (pos_colon2 == 0)
00372     {
00373       /*
00374        * If the port is not specified, use the default.
00375        * The default multicast port is the same as the default port
00376        * no. for Naming_Service, for now. But for other services,
00377        * check and modify the default values as needed.
00378        */
00379       char default_port[33];
00380 
00381       int trial_port = TAO_DEFAULT_NAME_SERVER_REQUEST_PORT;
00382 
00383       if (mcast_name_cstring.find ("InterfaceRepository") !=
00384           ACE_CString::npos)
00385         {
00386           trial_port = TAO_DEFAULT_INTERFACEREPO_SERVER_REQUEST_PORT;
00387         }
00388       else if (mcast_name_cstring.find ("ImplRepoService") !=
00389                ACE_CString::npos)
00390         {
00391            trial_port = TAO_DEFAULT_IMPLREPO_SERVER_REQUEST_PORT;
00392         }
00393       else if (mcast_name_cstring.find ("TradingService") !=
00394                ACE_CString::npos)
00395         {
00396            trial_port = TAO_DEFAULT_TRADING_SERVER_REQUEST_PORT;
00397         }
00398 
00399 
00400       ACE_OS_String::itoa (trial_port, default_port, 10);
00401 
00402       this->mcast_port_ = (const char *) default_port;
00403     }
00404   else
00405     {
00406       this->mcast_port_ = mcast_name_cstring.substring (0,
00407                                                         pos_colon2).c_str ();
00408     }
00409 
00410   mcast_name_cstring =
00411     mcast_name_cstring.substring (pos_colon2 + 1,
00412                                   mcast_name_cstring.length() - pos_colon2);
00413 
00414 
00415   int pos_colon3 = mcast_name_cstring.find (':', 0);
00416 
00417   this->mcast_nic_ =
00418     mcast_name_cstring.substring (0,
00419                                   pos_colon3).c_str ();
00420 
00421   mcast_name_cstring =
00422     mcast_name_cstring.substring (pos_colon3 + 1,
00423                                   mcast_name_cstring.length() - pos_colon3);
00424 
00425   int pos_colon4 = mcast_name_cstring.find ('/', 0);
00426 
00427   if (pos_colon4 == 0)
00428     {
00429       // And, the default TTL to be 1
00430       const char *default_ttl = "1";
00431       this->mcast_ttl_ = default_ttl;
00432     }
00433   else
00434     {
00435       this->mcast_ttl_ =
00436         mcast_name_cstring.substring (0,
00437                                       pos_colon4).c_str ();
00438     }
00439   mcast_name_cstring =
00440     mcast_name_cstring.substring (pos_colon4,
00441                                   mcast_name_cstring.length() - pos_colon4);
00442 
00443   this->service_name_ =
00444     mcast_name_cstring.substring (1,
00445                                   mcast_name_cstring.length()
00446                                   -1).c_str ();
00447 }

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 31 of file MCAST_Parser.cpp.

References mcast_prefix, and ACE_OS_String::strncmp.

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

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 120 of file MCAST_Parser.cpp.

References ACE_SOCK_Acceptor::accept, ACE_CString, ACE_DEBUG, ACE_ERROR, ACE_HTONS, ACE_NTOHS, ACE_TEXT, ACE_OS::atoi, ACE_SOCK_Acceptor::close, ACE_SOCK_Stream::close, ACE_INET_Addr::get_port_number, iovec::iov_base, iovec::iov_len, IP_MULTICAST_TTL, LM_DEBUG, LM_ERROR, ACE_SOCK_Dgram::open, ACE_SOCK_Acceptor::open, ACE_SOCK_Stream::recv_n, ACE_Addr::sap_any, ACE_SOCK_Dgram::send, ACE_INET_Addr::set, ACE_SOCK_Dgram::set_nic, ssize_t, ACE_OS_String::strcasecmp, CORBA::string_alloc, TAO_DEFAULT_IOR_SIZE, and TAO_DEFAULT_SERVICE_RESOLUTION_TIMEOUT.

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

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    ACE_ENV_ARG_DECL_NOT_USED
[private]
 

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

Parse the ior-string that is passed.

Implements TAO_IOR_Parser.

Definition at line 39 of file MCAST_Parser.cpp.

References ACE_CHECK_RETURN, ACE_ENV_ARG_DECL, ACE_ENV_ARG_PARAMETER, and ACE_OS::atoi.

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


Member Data Documentation

CORBA::String_var TAO_MCAST_Parser::mcast_address_ [private]
 

Definition at line 81 of file MCAST_Parser.h.

Referenced by assign_to_variables.

CORBA::String_var TAO_MCAST_Parser::mcast_nic_ [private]
 

Definition at line 83 of file MCAST_Parser.h.

Referenced by assign_to_variables.

CORBA::String_var TAO_MCAST_Parser::mcast_port_ [private]
 

Definition at line 82 of file MCAST_Parser.h.

Referenced by assign_to_variables.

CORBA::String_var TAO_MCAST_Parser::mcast_ttl_ [private]
 

Definition at line 84 of file MCAST_Parser.h.

Referenced by assign_to_variables.

CORBA::String_var TAO_MCAST_Parser::service_name_ [private]
 

Definition at line 85 of file MCAST_Parser.h.

Referenced by assign_to_variables.


The documentation for this class was generated from the following files:
Generated on Mon Jun 16 15:28:26 2003 for TAO by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002