mcast
: IOR format.
More...
#include <MCAST_Parser.h>
Inheritance diagram for TAO_MCAST_Parser:
Public Member Functions | |
TAO_MCAST_Parser (void) | |
Constructor. | |
virtual | ~TAO_MCAST_Parser (void) |
The destructor. | |
virtual bool | match_prefix (const char *ior_string) const |
virtual CORBA::Object_ptr | parse_string (const char *ior, CORBA::ORB_ptr orb) |
Parse the ior-string that is passed. | |
Private Member Functions | |
CORBA::Object_ptr | multicast_to_service (const char *service_name, unsigned short port, const char *mcast_address, int mcast_ttl, const char *mcast_nic, CORBA::ORB_ptr orb, ACE_Time_Value *timeout) |
int | multicast_query (char *&buf, const char *service_name, unsigned short port, const char *mcast_address, int mcast_ttl, const char *mcast_nic, ACE_Time_Value *timeout, CORBA::ORB_ptr orb) |
void | assign_to_variables (char const *mcast_name_ptr) |
Private Attributes | |
CORBA::String_var | mcast_address_ |
unsigned short | mcast_port_ |
Default multicast port (currently Name Service mcast port). | |
CORBA::String_var | mcast_nic_ |
Multicast network interface card. | |
int | mcast_ttl_ |
Default time-to-live (default is 1). | |
CORBA::String_var | service_name_ |
Multicast service name. |
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 41 of file MCAST_Parser.h.
|
Constructor.
|
|
The destructor.
Definition at line 30 of file MCAST_Parser.cpp.
00031 { 00032 } |
|
Definition at line 350 of file MCAST_Parser.cpp. References ACE_CString, ACE_DEFAULT_MULTICAST_ADDR, ACE_ERROR, ACE_TEXT, ACE_OS::atoi(), LM_ERROR, mcast_address_, mcast_nic_, mcast_port_, mcast_ttl_, TAO_debug_level, TAO_DEFAULT_IMPLREPO_SERVER_REQUEST_PORT, TAO_DEFAULT_INTERFACEREPO_SERVER_REQUEST_PORT, and TAO_DEFAULT_TRADING_SERVER_REQUEST_PORT. Referenced by parse_string().
00351 { 00352 /* 00353 * The format now is "multicast_address:port:nicaddress:ttl/object_key" 00354 */ 00355 ACE_CString mcast_name_cstring (mcast_name); 00356 00357 ACE_CString::size_type pos_colon1 = 00358 mcast_name_cstring.find (':', 0); 00359 00360 #if defined (ACE_HAS_IPV6) 00361 // IPv6 numeric address in host string? 00362 bool ipv6_in_host = false; 00363 00364 // Check if this is an mcast address containing a 00365 // decimal IPv6 address representation. 00366 if (mcast_name_cstring[0] == '[') 00367 { 00368 // In this case we have to find the end of the numeric address and 00369 // start looking for the port separator from there. 00370 ACE_CString::size_type const cp_pos = 00371 mcast_name_cstring.find (']', 0); 00372 if (cp_pos == 0) 00373 { 00374 // No valid IPv6 address specified. 00375 if (TAO_debug_level > 0) 00376 { 00377 ACE_ERROR ((LM_ERROR, 00378 ACE_TEXT ("\nTAO (%P|%t) MCAST_Parser: ") 00379 ACE_TEXT ("Invalid IPv6 decimal address specified.\n"))); 00380 } 00381 00382 return; 00383 } 00384 else 00385 { 00386 if (mcast_name_cstring[cp_pos + 1] == ':') // Look for a port 00387 pos_colon1 = cp_pos + 1; 00388 else 00389 pos_colon1 = cp_pos; 00390 ipv6_in_host = true; // host string contains full IPv6 numeric address 00391 } 00392 } 00393 #endif /* ACE_HAS_IPV6 */ 00394 00395 if (pos_colon1 == 0) 00396 { 00397 #if defined (ACE_HAS_IPV6) 00398 const char default_addr[] = ACE_DEFAULT_MULTICASTV6_ADDR; 00399 #else /* ACE_HAS_IPV6 */ 00400 const char default_addr[] = ACE_DEFAULT_MULTICAST_ADDR; 00401 #endif /* !ACE_HAS_IPV6 */ 00402 this->mcast_address_ = default_addr; 00403 } 00404 else 00405 { 00406 #if defined (ACE_HAS_IPV6) 00407 if (ipv6_in_host) 00408 this->mcast_address_ = 00409 mcast_name_cstring.substring (1, 00410 pos_colon1 - 2).c_str (); 00411 else 00412 #endif /* ACE_HAS_IPV6 */ 00413 this->mcast_address_ = 00414 mcast_name_cstring.substring (0, 00415 pos_colon1).c_str (); 00416 } 00417 mcast_name_cstring = 00418 mcast_name_cstring.substring (pos_colon1 + 1, 00419 mcast_name_cstring.length() - 00420 pos_colon1); 00421 00422 ACE_CString::size_type const pos_colon2 = 00423 mcast_name_cstring.find (':', 0); 00424 00425 if (pos_colon2 == 0) 00426 { 00427 if (mcast_name_cstring.find ("InterfaceRepository") != 00428 ACE_CString::npos) 00429 { 00430 this->mcast_port_ = 00431 TAO_DEFAULT_INTERFACEREPO_SERVER_REQUEST_PORT; 00432 } 00433 else if (mcast_name_cstring.find ("ImplRepoService") != 00434 ACE_CString::npos) 00435 { 00436 this->mcast_port_ = 00437 TAO_DEFAULT_IMPLREPO_SERVER_REQUEST_PORT; 00438 } 00439 else if (mcast_name_cstring.find ("TradingService") != 00440 ACE_CString::npos) 00441 { 00442 this->mcast_port_ = TAO_DEFAULT_TRADING_SERVER_REQUEST_PORT; 00443 } 00444 } 00445 else 00446 { 00447 int const the_port = 00448 ACE_OS::atoi (mcast_name_cstring.substring (0, 00449 pos_colon2).c_str ()); 00450 00451 if (the_port > 0 && the_port < 0xffffL) 00452 this->mcast_port_ = the_port; 00453 } 00454 00455 mcast_name_cstring = 00456 mcast_name_cstring.substring (pos_colon2 + 1, 00457 mcast_name_cstring.length() - pos_colon2); 00458 00459 00460 ACE_CString::size_type const pos_colon3 = mcast_name_cstring.find (':', 0); 00461 00462 this->mcast_nic_ = 00463 mcast_name_cstring.substring (0, 00464 pos_colon3).c_str (); 00465 00466 mcast_name_cstring = 00467 mcast_name_cstring.substring (pos_colon3 + 1, 00468 mcast_name_cstring.length() - pos_colon3); 00469 00470 ACE_CString::size_type const pos_colon4 = 00471 mcast_name_cstring.find ('/', 0); 00472 00473 if (pos_colon4 != 0) 00474 { 00475 // Change TTL to non-default value. 00476 int const the_ttl = 00477 ACE_OS::atoi (mcast_name_cstring.substring (0, pos_colon4).c_str ()); 00478 00479 if (the_ttl > 0 && the_ttl <= 255) // Valid TTLs: (0, 255] 00480 this->mcast_ttl_ = the_ttl; 00481 } 00482 00483 mcast_name_cstring = 00484 mcast_name_cstring.substring (pos_colon4, 00485 mcast_name_cstring.length() - pos_colon4); 00486 00487 this->service_name_ = 00488 mcast_name_cstring.substring (1, 00489 mcast_name_cstring.length() - 1).c_str (); 00490 } |
|
= The IOR_Parser methods, please read the documentation in IOR_Parser.h Implements TAO_IOR_Parser. Definition at line 35 of file MCAST_Parser.cpp. References mcast_prefix, and ACE_OS::strncmp().
00036 { 00037 return (ACE_OS::strncmp (ior_string, 00038 ::mcast_prefix, 00039 sizeof (::mcast_prefix) - 1) == 0); 00040 } |
|
Definition at line 108 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_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(), IP_MULTICAST_TTL, IPPROTO_IP, 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. Referenced by multicast_to_service().
00116 { 00117 ACE_INET_Addr my_addr; 00118 ACE_SOCK_Acceptor acceptor; 00119 ACE_SOCK_Stream stream; 00120 ACE_SOCK_Dgram dgram; 00121 00122 ssize_t result = 0; 00123 00124 // Bind listener to any port and then find out what the port was. 00125 #if defined (ACE_HAS_IPV6) 00126 if (acceptor.open (ACE_Addr::sap_any, 0, AF_INET6) == -1 00127 #else /* ACE_HAS_IPV6 */ 00128 if (acceptor.open (ACE_Addr::sap_any) == -1 00129 #endif /* !ACE_HAS_IPV6 */ 00130 || acceptor.get_local_addr (my_addr) == -1) 00131 { 00132 ACE_ERROR ((LM_ERROR, 00133 ACE_TEXT ("acceptor.open () || ") 00134 ACE_TEXT ("acceptor.get_local_addr () failed\n"))); 00135 result = -1; 00136 } 00137 else 00138 { 00139 if (TAO_debug_level > 0) 00140 { 00141 ACE_TCHAR addr[64]; 00142 my_addr.addr_to_string (addr, sizeof(addr)); 00143 ACE_DEBUG ((LM_DEBUG, 00144 "(%P|%t) TAO_MCAST_Parser: acceptor local address %s.\n", 00145 addr)); 00146 } 00147 00148 ACE_INET_Addr multicast_addr (port, 00149 mcast_address); 00150 00151 // Set the address if multicast_discovery_endpoint option 00152 // is specified for the Naming Service. 00153 ACE_CString mde (orb->orb_core ()->orb_params () 00154 ->mcast_discovery_endpoint ()); 00155 00156 if (ACE_OS::strcasecmp (service_name, 00157 "NameService") == 0 00158 && mde.length () != 0) 00159 if (multicast_addr.set (mde.c_str()) == -1) 00160 { 00161 ACE_ERROR ((LM_ERROR, 00162 ACE_TEXT("ORB.cpp: Multicast address setting failed\n"))); 00163 stream.close (); 00164 dgram.close (); 00165 acceptor.close (); 00166 return -1; 00167 } 00168 00169 // Open the datagram. 00170 if (dgram.open (ACE_Addr::sap_any, multicast_addr.get_type ()) == -1) 00171 { 00172 ACE_ERROR ((LM_ERROR, 00173 ACE_TEXT ("Unable to open the Datagram!\n"))); 00174 result = -1; 00175 } 00176 else 00177 { 00178 // Set NIC 00179 dgram.set_nic (ACE_TEXT_CHAR_TO_TCHAR (mcast_nic), 00180 multicast_addr.get_type ()); 00181 00182 // Set TTL 00183 int mcast_ttl_optval = mcast_ttl; 00184 00185 #if defined (ACE_HAS_IPV6) 00186 if (multicast_addr.get_type () == AF_INET6) 00187 { 00188 if (dgram.set_option ( 00189 IPPROTO_IPV6, 00190 IPV6_MULTICAST_HOPS, 00191 &mcast_ttl_optval, 00192 sizeof (mcast_ttl_optval)) != 0) 00193 return -1; 00194 } 00195 else 00196 #endif /* ACE_HAS_IPV6 */ 00197 if (dgram.set_option ( 00198 IPPROTO_IP, 00199 IP_MULTICAST_TTL, 00200 &mcast_ttl_optval, 00201 sizeof (mcast_ttl_optval)) != 0) 00202 result = -1; 00203 00204 // Convert the acceptor port into network byte order. 00205 ACE_UINT16 response_port = 00206 (ACE_UINT16) ACE_HTONS (my_addr.get_port_number ()); 00207 00208 // Length of service name we will send. 00209 CORBA::Short data_len = 00210 (CORBA::Short) ACE_HTONS (ACE_OS::strlen (service_name) + 1); 00211 00212 // Vector we will send. It contains: 1) length of service 00213 // name string, 2)port on which we are listening for 00214 // replies, and 3) name of service we are looking for. 00215 const int iovcnt = 3; 00216 iovec iovp[iovcnt]; 00217 00218 // The length of service name string. 00219 iovp[0].iov_base = (char *) &data_len; 00220 iovp[0].iov_len = sizeof (CORBA::Short); 00221 00222 // The port at which we are listening. 00223 iovp[1].iov_base = (char *) &response_port; 00224 iovp[1].iov_len = sizeof (ACE_UINT16); 00225 00226 // The service name string. 00227 iovp[2].iov_base = (char *) service_name; 00228 iovp[2].iov_len = 00229 static_cast<u_long> (ACE_OS::strlen (service_name) + 1); 00230 00231 // Send the multicast. 00232 result = dgram.send (iovp, 00233 iovcnt, 00234 multicast_addr); 00235 00236 if (TAO_debug_level > 0) 00237 ACE_DEBUG ((LM_DEBUG, 00238 ACE_TEXT ("\nsent multicast request."))); 00239 00240 // Check for errors. 00241 if (result == -1) 00242 ACE_ERROR ((LM_ERROR, 00243 ACE_TEXT ("%p\n"), 00244 ACE_TEXT ("error sending IIOP multicast"))); 00245 else 00246 { 00247 if (TAO_debug_level > 0) 00248 ACE_DEBUG ((LM_DEBUG, 00249 ACE_TEXT ("\n%N; Sent multicast.") 00250 ACE_TEXT ("# of bytes sent is %d.\n"), 00251 result)); 00252 // Wait for response until timeout. 00253 ACE_Time_Value tv ( 00254 timeout == 0 00255 ? ACE_Time_Value (TAO_DEFAULT_SERVICE_RESOLUTION_TIMEOUT) 00256 : *timeout); 00257 00258 // Accept reply connection from server. 00259 if (acceptor.accept (stream, 00260 0, 00261 &tv) == -1) 00262 { 00263 ACE_ERROR ((LM_ERROR, 00264 ACE_TEXT ("%p\n"), 00265 ACE_TEXT ("multicast_query: unable to accept"))); 00266 result = -1; 00267 } 00268 else 00269 { 00270 // Receive the IOR. 00271 00272 // IOR length. 00273 CORBA::Short ior_len; 00274 result = stream.recv_n (&ior_len, 00275 sizeof ior_len, 00276 0, 00277 &tv); 00278 if (result != sizeof (ior_len)) 00279 { 00280 ACE_ERROR ((LM_ERROR, 00281 ACE_TEXT ("%p\n"), 00282 ACE_TEXT ("multicast_query: unable to receive ") 00283 ACE_TEXT ("ior length"))); 00284 result = -1; 00285 } 00286 else 00287 { 00288 // Allocate more space for the ior if we don't 00289 // have enough. 00290 ior_len = (CORBA::Short) ACE_NTOHS (ior_len); 00291 if (ior_len >= TAO_DEFAULT_IOR_SIZE) 00292 { 00293 buf = CORBA::string_alloc (ior_len); 00294 if (buf == 0) 00295 { 00296 ACE_ERROR ((LM_ERROR, 00297 ACE_TEXT ("%p\n"), 00298 ACE_TEXT ("multicast_query: unable to ") 00299 ACE_TEXT ("allocate memory"))); 00300 result = -1; 00301 } 00302 } 00303 00304 if (result != -1) 00305 { 00306 // Receive the ior. 00307 result = stream.recv_n (buf, 00308 ior_len, 00309 0, 00310 &tv); 00311 if (result == -1) 00312 ACE_ERROR ((LM_ERROR, 00313 ACE_TEXT ( "%p\n"), 00314 ACE_TEXT ("error reading ior"))); 00315 else if (TAO_debug_level > 0) 00316 ACE_DEBUG ((LM_DEBUG, 00317 ACE_TEXT ("%N: service resolved to IOR <%s>\n"), 00318 ACE_TEXT_CHAR_TO_TCHAR (buf))); 00319 } 00320 } 00321 } 00322 } 00323 } 00324 if (result == -1) 00325 { 00326 ACE_ERROR ((LM_ERROR, 00327 ACE_TEXT("\nmulticast discovery of %s failed.\n"), 00328 ACE_TEXT_CHAR_TO_TCHAR (service_name))); 00329 00330 if (ACE_OS::strcasecmp (service_name, 00331 "NameService") == 0) 00332 { 00333 ACE_ERROR ((LM_ERROR, 00334 ACE_TEXT("Specify -m 1 when starting Naming_Service,\n") 00335 ACE_TEXT("or see http://www.theaceorb.com/faq/#115\n") 00336 ACE_TEXT("for using NameService without multicast.\n\n"))); 00337 } 00338 } 00339 } 00340 00341 // Clean up. 00342 stream.close (); 00343 dgram.close (); 00344 acceptor.close (); 00345 00346 return result == -1 ? -1 : 0; 00347 } |
|
Definition at line 67 of file MCAST_Parser.cpp. References TAO_Pseudo_Var_T< T >::_retn(), multicast_query(), CORBA::Object_var, CORBA::ORB_ptr, CORBA::ORB::string_to_object(), CORBA::String_var, and TAO_DEFAULT_IOR_SIZE. Referenced by parse_string().
00074 { 00075 char buf[TAO_DEFAULT_IOR_SIZE]; 00076 char * ior = buf; 00077 00078 // Use UDP multicast to locate the service. 00079 int const result = this->multicast_query (ior, 00080 service_name, 00081 port, 00082 mcast_address, 00083 mcast_ttl, 00084 mcast_nic, 00085 timeout, 00086 orb); 00087 00088 CORBA::Object_var return_value; 00089 00090 if (result == 0) 00091 { 00092 CORBA::String_var cleaner; 00093 // If the IOR didn't fit into <buf>, memory for it was dynamically 00094 // allocated - make sure it gets deallocated. 00095 if (ior != buf) 00096 cleaner = ior; 00097 00098 // Convert IOR to an object reference. 00099 return_value = 00100 orb->string_to_object (ior); 00101 } 00102 00103 // Return object reference. 00104 return return_value._retn (); 00105 } |
|
Parse the ior-string that is passed.
Implements TAO_IOR_Parser. Definition at line 43 of file MCAST_Parser.cpp. References assign_to_variables(), CORBA::ORB::get_timeout(), TAO::String_var< charT >::in(), mcast_address_, mcast_nic_, mcast_port_, mcast_ttl_, multicast_to_service(), and CORBA::ORB_ptr.
00044 { 00045 char const * const mcast_name = 00046 ior + sizeof (::mcast_prefix) + 1; 00047 00048 assign_to_variables (mcast_name); 00049 00050 /* 00051 * Now that we got the global variables. 00052 * we can invoke multicast_to_service and multicast_query 00053 */ 00054 ACE_Time_Value *timeout = orb->get_timeout (); 00055 00056 return 00057 this->multicast_to_service (service_name_.in (), 00058 this->mcast_port_, 00059 this->mcast_address_.in (), 00060 this->mcast_ttl_, 00061 this->mcast_nic_.in (), 00062 orb, 00063 timeout); 00064 } |
|
Definition at line 83 of file MCAST_Parser.h. Referenced by assign_to_variables(), and parse_string(). |
|
Multicast network interface card.
Definition at line 89 of file MCAST_Parser.h. Referenced by assign_to_variables(), and parse_string(). |
|
Default multicast port (currently Name Service mcast port).
Definition at line 86 of file MCAST_Parser.h. Referenced by assign_to_variables(), and parse_string(). |
|
Default time-to-live (default is 1).
Definition at line 92 of file MCAST_Parser.h. Referenced by assign_to_variables(), and parse_string(). |
|
Multicast service name.
Definition at line 95 of file MCAST_Parser.h. |