00001
00002
00003 #include "tao/Strategies/DIOP_Profile.h"
00004
00005 #if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
00006
00007 #include "tao/CDR.h"
00008 #include "tao/SystemException.h"
00009 #include "tao/ORB.h"
00010 #include "tao/ORB_Core.h"
00011 #include "tao/debug.h"
00012 #include "tao/IIOP_EndpointsC.h"
00013
00014 #include "ace/OS_NS_stdio.h"
00015 #include "ace/OS_NS_string.h"
00016 #include "ace/os_include/os_netdb.h"
00017
00018 ACE_RCSID (Strategies,
00019 DIOP_Profile,
00020 "$Id: DIOP_Profile.cpp 78867 2007-07-13 03:29:33Z johnnyw $")
00021
00022 static const char the_prefix[] = "diop";
00023
00024 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00025
00026 const char TAO_DIOP_Profile::object_key_delimiter_ = '/';
00027
00028 char
00029 TAO_DIOP_Profile::object_key_delimiter (void) const
00030 {
00031 return TAO_DIOP_Profile::object_key_delimiter_;
00032 }
00033
00034
00035 TAO_DIOP_Profile::TAO_DIOP_Profile (const ACE_INET_Addr &addr,
00036 const TAO::ObjectKey &object_key,
00037 const TAO_GIOP_Message_Version &version,
00038 TAO_ORB_Core *orb_core)
00039 : TAO_Profile (TAO_TAG_DIOP_PROFILE,
00040 orb_core,
00041 object_key,
00042 version),
00043 endpoint_ (addr,
00044 orb_core->orb_params ()->use_dotted_decimal_addresses ()),
00045 count_ (1)
00046 {
00047 }
00048
00049 TAO_DIOP_Profile::TAO_DIOP_Profile (const char* host,
00050 CORBA::UShort port,
00051 const TAO::ObjectKey &object_key,
00052 const ACE_INET_Addr &addr,
00053 const TAO_GIOP_Message_Version &version,
00054 TAO_ORB_Core *orb_core)
00055 : TAO_Profile (TAO_TAG_DIOP_PROFILE,
00056 orb_core,
00057 object_key,
00058 version),
00059 endpoint_ (host, port, addr),
00060 count_ (1)
00061 {
00062 }
00063
00064 TAO_DIOP_Profile::TAO_DIOP_Profile (TAO_ORB_Core *orb_core)
00065 : TAO_Profile (TAO_TAG_DIOP_PROFILE,
00066 orb_core,
00067 TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR)),
00068 endpoint_ (),
00069 count_ (1)
00070 {
00071 }
00072
00073 TAO_DIOP_Profile::~TAO_DIOP_Profile (void)
00074 {
00075
00076
00077 TAO_Endpoint *tmp = 0;
00078
00079 for (TAO_Endpoint *next = this->endpoint ()->next ();
00080 next != 0;
00081 next = tmp)
00082 {
00083 tmp = next->next ();
00084 delete next;
00085 }
00086 }
00087
00088
00089
00090
00091
00092
00093 int
00094 TAO_DIOP_Profile::decode_profile (TAO_InputCDR& cdr)
00095 {
00096
00097
00098
00099 if (cdr.read_string (this->endpoint_.host_.out ()) == 0
00100 || cdr.read_ushort (this->endpoint_.port_) == 0)
00101 {
00102 if (TAO_debug_level > 0)
00103 ACE_DEBUG ((LM_DEBUG,
00104 ACE_TEXT ("TAO (%P|%t) - DIOP_Profile::decode_profile, ")
00105 ACE_TEXT ("error while decoding host/port\n")));
00106 return -1;
00107 }
00108
00109 if (cdr.good_bit ())
00110 {
00111
00112 this->endpoint_.object_addr_.set_type (-1);
00113
00114 return 1;
00115 }
00116
00117 return -1;
00118 }
00119
00120 void
00121 TAO_DIOP_Profile::parse_string_i (const char *ior)
00122 {
00123
00124
00125 const char *okd =
00126 ACE_OS::strchr (ior, this->object_key_delimiter_);
00127
00128 if (okd == 0 || okd == ior)
00129 {
00130
00131 throw ::CORBA::INV_OBJREF (
00132 CORBA::SystemException::_tao_minor_code (
00133 TAO::VMCID,
00134 EINVAL),
00135 CORBA::COMPLETED_NO);
00136 }
00137
00138
00139 CORBA::ULong length_host = 0;
00140
00141 const char *cp_pos = ACE_OS::strchr (ior, ':');
00142 #if defined (ACE_HAS_IPV6)
00143
00144 bool ipv6_in_host = false;
00145
00146
00147
00148 if ((this->version ().major > TAO_MIN_IPV6_IIOP_MAJOR ||
00149 this->version ().minor >= TAO_MIN_IPV6_IIOP_MINOR) &&
00150 ior[0] == '[')
00151 {
00152
00153
00154 const char *cp_pos_a = ACE_OS::strchr (ior, ']');
00155 if (cp_pos_a == 0)
00156 {
00157
00158 if (TAO_debug_level > 0)
00159 {
00160 ACE_DEBUG ((LM_ERROR,
00161 ACE_TEXT ("\nTAO (%P|%t) - DIOP_Profile::parse_string_i, ")
00162 ACE_TEXT ("invalid IPv6 decimal address specified.\n")));
00163 }
00164
00165 throw ::CORBA::INV_OBJREF (
00166 CORBA::SystemException::_tao_minor_code (
00167 0,
00168 EINVAL),
00169 CORBA::COMPLETED_NO);
00170 }
00171 else
00172 {
00173 if (cp_pos_a[1] == ':')
00174 cp_pos = cp_pos_a + 1;
00175 else
00176 cp_pos = 0;
00177 ipv6_in_host = true;
00178 }
00179 }
00180 #endif
00181
00182 if (cp_pos == ior)
00183 {
00184
00185 throw ::CORBA::INV_OBJREF (
00186 CORBA::SystemException::_tao_minor_code (
00187 TAO::VMCID,
00188 EINVAL),
00189 CORBA::COMPLETED_NO);
00190 }
00191 else if (cp_pos != 0)
00192 {
00193
00194 CORBA::ULong length_port = okd - cp_pos - 1;
00195
00196 CORBA::String_var tmp = CORBA::string_alloc (length_port);
00197
00198 ACE_OS::strncpy (tmp.inout (), cp_pos + 1, length_port);
00199 tmp[length_port] = '\0';
00200
00201 if (ACE_OS::strspn (tmp.in (), "1234567890") == length_port)
00202 {
00203 this->endpoint_.port_ =
00204 static_cast<CORBA::UShort> (ACE_OS::atoi (tmp.in ()));
00205 }
00206 else
00207 {
00208 ACE_INET_Addr ia;
00209 if (ia.string_to_addr (tmp.in ()) == -1)
00210 {
00211 throw ::CORBA::INV_OBJREF (
00212 CORBA::SystemException::_tao_minor_code (
00213 0,
00214 EINVAL),
00215 CORBA::COMPLETED_NO);
00216 }
00217 else
00218 {
00219 this->endpoint_.port_ = ia.get_port_number ();
00220 }
00221 }
00222
00223 length_host = cp_pos - ior;
00224 }
00225 else
00226 length_host = okd - ior;
00227
00228 #if defined (ACE_HAS_IPV6)
00229 if (ipv6_in_host)
00230 length_host -= 2;
00231 #endif
00232
00233 CORBA::String_var tmp = CORBA::string_alloc (length_host);
00234
00235 #if defined (ACE_HAS_IPV6)
00236 if (ipv6_in_host)
00237 ACE_OS::strncpy (tmp.inout (), ior + 1, length_host);
00238 else
00239 #endif
00240
00241 ACE_OS::strncpy (tmp.inout (), ior, length_host);
00242 tmp[length_host] = '\0';
00243
00244 this->endpoint_.host_ = tmp._retn ();
00245 #if defined (ACE_HAS_IPV6)
00246 this->endpoint_.is_ipv6_decimal_ = ipv6_in_host;
00247 #endif
00248
00249 if (ACE_OS::strcmp (this->endpoint_.host_.in (), "") == 0)
00250 {
00251 ACE_INET_Addr host_addr;
00252
00253 char tmp_host [MAXHOSTNAMELEN + 1];
00254
00255
00256
00257 if (host_addr.get_host_name (tmp_host,
00258 sizeof (tmp_host)) != 0)
00259 {
00260
00261
00262
00263 if (TAO_debug_level > 0)
00264 ACE_DEBUG ((LM_DEBUG,
00265 ACE_TEXT ("TAO (%P|%t) - ")
00266 ACE_TEXT ("DIOP_Profile::parse_string_i, ")
00267 ACE_TEXT ("%p\n\n"),
00268 ACE_TEXT ("cannot determine hostname")));
00269
00270
00271 throw ::CORBA::INV_OBJREF (
00272 CORBA::SystemException::_tao_minor_code (
00273 TAO::VMCID,
00274 EINVAL),
00275 CORBA::COMPLETED_NO);
00276 }
00277 else
00278 this->endpoint_.host_ = CORBA::string_dup (tmp_host);
00279 }
00280
00281 TAO::ObjectKey ok;
00282 TAO::ObjectKey::decode_string_to_sequence (ok,
00283 okd + 1);
00284
00285 (void) this->orb_core ()->object_key_table ().bind (ok,
00286 this->ref_object_key_);
00287 }
00288
00289 CORBA::Boolean
00290 TAO_DIOP_Profile::do_is_equivalent (const TAO_Profile *other_profile)
00291 {
00292 const TAO_DIOP_Profile *op =
00293 dynamic_cast<const TAO_DIOP_Profile *> (other_profile);
00294
00295
00296 if (op == 0)
00297 return 0;
00298
00299
00300 const TAO_DIOP_Endpoint *other_endp = &op->endpoint_;
00301 for (TAO_DIOP_Endpoint *endp = &this->endpoint_;
00302 endp != 0;
00303 endp = endp->next_)
00304 {
00305 if (endp->is_equivalent (other_endp))
00306 other_endp = other_endp->next_;
00307 else
00308 return false;
00309 }
00310
00311 return true;
00312 }
00313
00314 CORBA::ULong
00315 TAO_DIOP_Profile::hash (CORBA::ULong max)
00316 {
00317
00318 CORBA::ULong hashval = 0;
00319 for (TAO_DIOP_Endpoint *endp = &this->endpoint_;
00320 endp != 0;
00321 endp = endp->next_)
00322 {
00323 hashval += endp->hash ();
00324 }
00325
00326 hashval += this->version_.minor;
00327 hashval += this->tag ();
00328
00329 const TAO::ObjectKey &ok =
00330 this->ref_object_key_->object_key ();
00331
00332 if (ok.length () >= 4)
00333 {
00334 hashval += ok[1];
00335 hashval += ok[3];
00336 }
00337
00338 hashval += this->hash_service_i (max);
00339
00340 return hashval % max;
00341 }
00342
00343 TAO_Endpoint*
00344 TAO_DIOP_Profile::endpoint (void)
00345 {
00346 return &this->endpoint_;
00347 }
00348
00349 CORBA::ULong
00350 TAO_DIOP_Profile::endpoint_count (void) const
00351 {
00352 return this->count_;
00353 }
00354
00355 void
00356 TAO_DIOP_Profile::add_endpoint (TAO_DIOP_Endpoint *endp)
00357 {
00358 endp->next_ = this->endpoint_.next_;
00359 this->endpoint_.next_ = endp;
00360
00361 this->count_++;
00362 }
00363
00364 char *
00365 TAO_DIOP_Profile::to_string (void)
00366 {
00367
00368
00369 CORBA::String_var key;
00370 TAO::ObjectKey::encode_sequence_to_string (key.inout (),
00371 this->ref_object_key_->object_key ());
00372
00373 size_t buflen = (
00374 8 +
00375 1 +
00376 1 +
00377 ACE_OS::strlen (key.in ()));
00378 size_t pfx_len = (
00379 ACE_OS::strlen (::the_prefix) +
00380 1 );
00381
00382 const TAO_DIOP_Endpoint *endp = 0;
00383 for (endp = &this->endpoint_; endp != 0; endp = endp->next_)
00384 {
00385 buflen += (
00386 pfx_len +
00387 1 +
00388 1 +
00389 1 +
00390 1 +
00391 ACE_OS::strlen (endp->host ()) +
00392 1 +
00393 5 +
00394 1 );
00395 #if defined (ACE_HAS_IPV6)
00396 if (endp->is_ipv6_decimal_)
00397 buflen += 2;
00398 #endif
00399 }
00400
00401 static const char digits [] = "0123456789";
00402
00403 char * buf = CORBA::string_alloc (static_cast<CORBA::ULong> (buflen));
00404
00405 ACE_OS::strcpy (buf, "corbaloc:");
00406
00407 for (endp = &this->endpoint_; endp != 0; endp = endp->next_)
00408 {
00409 if (&this->endpoint_ != endp)
00410 ACE_OS::strcat (buf, ",");
00411
00412 #if defined (ACE_HAS_IPV6)
00413 if (endp->is_ipv6_decimal_)
00414 {
00415
00416 ACE_CString tmp (endp->host ());
00417 ACE_CString::size_type pos = tmp.find ('%');
00418 if (pos != ACE_CString::npos)
00419 {
00420 tmp = tmp.substr (0, pos + 1);
00421 tmp[pos] = '\0';
00422 }
00423 ACE_OS::sprintf (buf + ACE_OS::strlen (buf),
00424 "%s:%c.%c@[%s]:%d",
00425 ::the_prefix,
00426 digits [this->version_.major],
00427 digits [this->version_.minor],
00428 tmp.c_str (),
00429 endp->port ());
00430 }
00431 else
00432 #endif
00433 ACE_OS::sprintf (buf + ACE_OS::strlen (buf),
00434 "%s:%c.%c@%s:%d",
00435 ::the_prefix,
00436 digits [this->version_.major],
00437 digits [this->version_.minor],
00438 endp->host (),
00439 endp->port ());
00440
00441 }
00442 ACE_OS::sprintf (buf + ACE_OS::strlen (buf),
00443 "%c%s",
00444 this->object_key_delimiter_,
00445 key.in ());
00446
00447 return buf;
00448 }
00449
00450 const char *
00451 TAO_DIOP_Profile::prefix (void)
00452 {
00453 return ::the_prefix;
00454 }
00455
00456 void
00457 TAO_DIOP_Profile::create_profile_body (TAO_OutputCDR &encap) const
00458 {
00459 encap.write_octet (TAO_ENCAP_BYTE_ORDER);
00460
00461
00462 encap.write_octet (this->version_.major);
00463 encap.write_octet (this->version_.minor);
00464
00465
00466 #if defined (ACE_HAS_IPV6)
00467
00468
00469 const char* host;
00470 const char* pos;
00471 if (this->endpoint_.is_ipv6_decimal_ &&
00472 (pos = ACE_OS::strchr (host = this->endpoint_.host (), '%')) != 0)
00473 {
00474 ACE_CString tmp;
00475 size_t len = pos - host;
00476 tmp.set (this->endpoint_.host (), len, 1);
00477 encap.write_string (tmp.c_str ());
00478 }
00479 else
00480 #endif
00481 encap.write_string (this->endpoint_.host ());
00482
00483
00484 encap.write_ushort (this->endpoint_.port ());
00485
00486
00487 if (this->ref_object_key_)
00488 encap << this->ref_object_key_->object_key ();
00489 else
00490 {
00491 ACE_ERROR ((LM_ERROR,
00492 "TAO (%P|%t) - DIOP_Profile::create_profile_body, "
00493 "no object key marshalled\n"));
00494 }
00495
00496 if (this->version_.major > 1
00497 || this->version_.minor > 0)
00498 this->tagged_components ().encode (encap);
00499 }
00500
00501 int
00502 TAO_DIOP_Profile::encode_endpoints (void)
00503 {
00504
00505
00506
00507
00508
00509
00510
00511 TAO::IIOPEndpointSequence endpoints;
00512 endpoints.length (this->count_);
00513
00514 const TAO_DIOP_Endpoint *endpoint = &this->endpoint_;
00515 for (CORBA::ULong i = 0;
00516 i < this->count_;
00517 ++i)
00518 {
00519 #if defined (ACE_HAS_IPV6)
00520 if (endpoint->is_ipv6_decimal_)
00521 {
00522
00523 ACE_CString tmp (endpoint->host ());
00524 ACE_CString::size_type pos = tmp.find ('%');
00525 if (pos != ACE_CString::npos)
00526 {
00527 tmp = tmp.substr (0, pos + 1);
00528 tmp[pos] = '\0';
00529 endpoints[i].host = tmp.c_str ();
00530 }
00531 else
00532 endpoints[i].host = tmp.c_str ();
00533 }
00534 else
00535 #endif
00536 endpoints[i].host = endpoint->host ();
00537 endpoints[i].port = endpoint->port ();
00538 endpoints[i].priority = endpoint->priority ();
00539
00540 endpoint = endpoint->next_;
00541 }
00542
00543
00544 TAO_OutputCDR out_cdr;
00545 if ((out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)
00546 == 0)
00547 || (out_cdr << endpoints) == 0)
00548 return -1;
00549
00550 this->set_tagged_components (out_cdr);
00551
00552 return 0;
00553 }
00554
00555 int
00556 TAO_DIOP_Profile::decode_endpoints (void)
00557 {
00558 IOP::TaggedComponent tagged_component;
00559 tagged_component.tag = TAO_TAG_ENDPOINTS;
00560
00561 if (this->tagged_components_.get_component (tagged_component))
00562 {
00563 const CORBA::Octet *buf =
00564 tagged_component.component_data.get_buffer ();
00565
00566 TAO_InputCDR in_cdr (reinterpret_cast<const char*> (buf),
00567 tagged_component.component_data.length ());
00568
00569
00570 CORBA::Boolean byte_order;
00571 if ((in_cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00572 return -1;
00573 in_cdr.reset_byte_order (static_cast<int> (byte_order));
00574
00575
00576 TAO::IIOPEndpointSequence endpoints;
00577
00578 if (! (in_cdr >> endpoints))
00579 return -1;
00580
00581
00582
00583
00584 this->endpoint_.priority (endpoints[0].priority);
00585
00586
00587
00588
00589
00590
00591
00592 for (CORBA::ULong i = endpoints.length () - 1;
00593 i > 0;
00594 --i)
00595 {
00596 TAO_DIOP_Endpoint *endpoint = 0;
00597 ACE_NEW_RETURN (endpoint,
00598 TAO_DIOP_Endpoint (endpoints[i].host,
00599 endpoints[i].port,
00600 endpoints[i].priority),
00601 -1);
00602
00603 this->add_endpoint (endpoint);
00604 }
00605 }
00606
00607 return 0;
00608 }
00609
00610 TAO_END_VERSIONED_NAMESPACE_DECL
00611
00612 #endif