00001
00002
00003
00004 #include "tao/Strategies/DIOP_Acceptor.h"
00005
00006 #if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
00007
00008 #include "tao/Strategies/DIOP_Profile.h"
00009 #include "tao/MProfile.h"
00010 #include "tao/ORB_Core.h"
00011 #include "tao/debug.h"
00012 #include "tao/Protocols_Hooks.h"
00013 #include "tao/Codeset_Manager.h"
00014 #include "tao/CDR.h"
00015
00016 #include "ace/Auto_Ptr.h"
00017 #include "ace/OS_NS_string.h"
00018
00019 #if !defined(__ACE_INLINE__)
00020 #include "tao/Strategies/DIOP_Acceptor.inl"
00021 #endif
00022
00023 #include "ace/os_include/os_netdb.h"
00024
00025 ACE_RCSID (Strategies,
00026 DIOP_Acceptor,
00027 "$Id: DIOP_Acceptor.cpp 79033 2007-07-26 09:26:46Z vridosh $")
00028
00029 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00030
00031 TAO_DIOP_Acceptor::TAO_DIOP_Acceptor (void)
00032 : TAO_Acceptor (TAO_TAG_DIOP_PROFILE),
00033 addrs_ (0),
00034 hosts_ (0),
00035 endpoint_count_ (0),
00036 version_ (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR),
00037 orb_core_ (0),
00038 #if defined (ACE_HAS_IPV6)
00039 default_address_ (static_cast<unsigned short> (0), ACE_IPV6_ANY, AF_INET6),
00040 #else
00041 default_address_ (static_cast<unsigned short> (0), static_cast<ACE_UINT32> (INADDR_ANY)),
00042 #endif
00043 connection_handler_ (0)
00044 {
00045 }
00046
00047 TAO_DIOP_Acceptor::~TAO_DIOP_Acceptor (void)
00048 {
00049
00050
00051 this->close ();
00052
00053 delete [] this->addrs_;
00054
00055 for (CORBA::ULong i = 0; i < this->endpoint_count_; ++i)
00056 CORBA::string_free (this->hosts_[i]);
00057
00058 delete [] this->hosts_;
00059 }
00060
00061
00062
00063
00064 int
00065 TAO_DIOP_Acceptor::create_profile (const TAO::ObjectKey & object_key,
00066 TAO_MProfile &mprofile,
00067 CORBA::Short priority)
00068 {
00069
00070 if (this->endpoint_count_ == 0)
00071 return -1;
00072
00073
00074
00075 if (priority == TAO_INVALID_PRIORITY &&
00076 this->orb_core_->orb_params ()->shared_profile () == 0)
00077 return this->create_new_profile (object_key, mprofile, priority);
00078 else
00079 return this->create_shared_profile (object_key, mprofile, priority);
00080 }
00081
00082 int
00083 TAO_DIOP_Acceptor::create_new_profile (const TAO::ObjectKey &object_key,
00084 TAO_MProfile &mprofile,
00085 CORBA::Short priority)
00086 {
00087
00088 int count = mprofile.profile_count ();
00089 if ((mprofile.size () - count) < this->endpoint_count_
00090 && mprofile.grow (count + this->endpoint_count_) == -1)
00091 return -1;
00092
00093
00094 for (CORBA::ULong i = 0; i < this->endpoint_count_; ++i)
00095 {
00096
00097 if (i > 0
00098 && (this->addrs_[i].get_port_number () == this->addrs_[0].get_port_number ())
00099 && ACE_OS::strcmp (this->hosts_[i], this->hosts_[0]) == 0)
00100 continue;
00101
00102 TAO_DIOP_Profile *pfile = 0;
00103 ACE_NEW_RETURN (pfile,
00104 TAO_DIOP_Profile (this->hosts_[i],
00105 this->addrs_[i].get_port_number (),
00106 object_key,
00107 this->addrs_[i],
00108 this->version_,
00109 this->orb_core_),
00110 -1);
00111 pfile->endpoint ()->priority (priority);
00112
00113 if (mprofile.give_profile (pfile) == -1)
00114 {
00115 pfile->_decr_refcnt ();
00116 pfile = 0;
00117 return -1;
00118 }
00119
00120
00121
00122
00123 if (this->orb_core_->orb_params ()->std_profile_components () == 0
00124 || (this->version_.major == 1 && this->version_.minor == 0))
00125 continue;
00126
00127 pfile->tagged_components ().set_orb_type (TAO_ORB_TYPE);
00128
00129 TAO_Codeset_Manager *csm = this->orb_core_->codeset_manager ();
00130 if (csm)
00131 csm->set_codeset (pfile->tagged_components ());
00132 }
00133
00134 return 0;
00135 }
00136
00137 int
00138 TAO_DIOP_Acceptor::create_shared_profile (const TAO::ObjectKey &object_key,
00139 TAO_MProfile &mprofile,
00140 CORBA::Short priority)
00141 {
00142 CORBA::ULong index = 0;
00143 TAO_Profile *pfile = 0;
00144 TAO_DIOP_Profile *diop_profile = 0;
00145
00146
00147 for (TAO_PHandle i = 0; i != mprofile.profile_count (); ++i)
00148 {
00149 pfile = mprofile.get_profile (i);
00150 if (pfile->tag () == TAO_TAG_DIOP_PROFILE)
00151 {
00152 diop_profile = dynamic_cast<TAO_DIOP_Profile *> (pfile);
00153 break;
00154 }
00155 }
00156
00157
00158
00159 if (diop_profile == 0)
00160 {
00161 ACE_NEW_RETURN (diop_profile,
00162 TAO_DIOP_Profile (this->hosts_[0],
00163 this->addrs_[0].get_port_number (),
00164 object_key,
00165 this->addrs_[0],
00166 this->version_,
00167 this->orb_core_),
00168 -1);
00169 diop_profile->endpoint ()->priority (priority);
00170
00171 if (mprofile.give_profile (diop_profile) == -1)
00172 {
00173 diop_profile->_decr_refcnt ();
00174 diop_profile = 0;
00175 return -1;
00176 }
00177
00178 if (this->orb_core_->orb_params ()->std_profile_components () != 0
00179 && (this->version_.major >= 1 && this->version_.minor >= 1))
00180 {
00181 diop_profile->tagged_components ().set_orb_type (TAO_ORB_TYPE);
00182 TAO_Codeset_Manager *csm = this->orb_core_->codeset_manager ();
00183 if (csm)
00184 csm->set_codeset (pfile->tagged_components ());
00185 }
00186
00187 index = 1;
00188 }
00189
00190
00191 for (;
00192 index < this->endpoint_count_;
00193 ++index)
00194 {
00195 if (index > 0 &&
00196 this->addrs_[index].get_port_number () == this->addrs_[0].get_port_number () &&
00197 ACE_OS::strcmp (this->hosts_[index], this->hosts_[0]) == 0)
00198 continue;
00199
00200 TAO_DIOP_Endpoint *endpoint = 0;
00201 ACE_NEW_RETURN (endpoint,
00202 TAO_DIOP_Endpoint (this->hosts_[index],
00203 this->addrs_[index].get_port_number (),
00204 this->addrs_[index]),
00205 -1);
00206 endpoint->priority (priority);
00207 diop_profile->add_endpoint (endpoint);
00208 }
00209
00210 return 0;
00211 }
00212
00213 int
00214 TAO_DIOP_Acceptor::is_collocated (const TAO_Endpoint *endpoint)
00215 {
00216 const TAO_DIOP_Endpoint *endp =
00217 dynamic_cast<const TAO_DIOP_Endpoint *> (endpoint);
00218
00219
00220 if (endp == 0)
00221 return 0;
00222
00223 for (CORBA::ULong i = 0; i < this->endpoint_count_; ++i)
00224 {
00225
00226
00227
00228
00229
00230
00231 if (endp->port () == this->addrs_[i].get_port_number ()
00232 && ACE_OS::strcmp (endp->host (), this->hosts_[i]) == 0)
00233 return 1;
00234 }
00235
00236 return 0;
00237 }
00238
00239 int
00240 TAO_DIOP_Acceptor::close (void)
00241 {
00242 return 0;
00243 }
00244
00245 int
00246 TAO_DIOP_Acceptor::open (TAO_ORB_Core *orb_core,
00247 ACE_Reactor *reactor,
00248 int major,
00249 int minor,
00250 const char *address,
00251 const char *options)
00252 {
00253 this->orb_core_ = orb_core;
00254
00255 if (this->hosts_ != 0)
00256 {
00257
00258
00259 ACE_ERROR_RETURN ((LM_ERROR,
00260 ACE_TEXT ("TAO (%P|%t) - ")
00261 ACE_TEXT ("DIOP_Acceptor::open, ")
00262 ACE_TEXT ("hostname already set\n\n")),
00263 -1);
00264 }
00265
00266 if (address == 0)
00267 return -1;
00268
00269 if (major >=0 && minor >= 0)
00270 this->version_.set_version (static_cast<CORBA::Octet> (major),
00271 static_cast<CORBA::Octet> (minor));
00272
00273 if (this->parse_options (options) == -1)
00274 return -1;
00275
00276 ACE_CString specified_hostname;
00277 ACE_INET_Addr addr;
00278 int def_type = AF_UNSPEC;
00279
00280 if (this->parse_address (address,
00281 addr,
00282 specified_hostname,
00283 &def_type) == -1)
00284 return -1;
00285
00286 if (specified_hostname.length () == 0)
00287 {
00288
00289
00290
00291
00292
00293 if (this->probe_interfaces (orb_core, def_type) == -1)
00294 return -1;
00295
00296
00297
00298
00299 addr.set (this->default_address_);
00300
00301 return this->open_i (addr,
00302 reactor);
00303 }
00304
00305 #if defined (ACE_HAS_IPV6)
00306
00307 if (this->orb_core_->orb_params ()->connect_ipv6_only () &&
00308 (addr.get_type () != AF_INET6 ||
00309 addr.is_ipv4_mapped_ipv6 ()))
00310 {
00311 ACE_ERROR_RETURN ((LM_ERROR,
00312 ACE_TEXT ("TAO (%P|%t) - ")
00313 ACE_TEXT ("DIOP_Acceptor::open, ")
00314 ACE_TEXT ("non-IPv6 endpoints not allowed when ")
00315 ACE_TEXT ("connect_ipv6_only is set\n\n")),
00316 -1);
00317 }
00318 #endif
00319
00320 if (TAO_debug_level > 2)
00321 {
00322 ACE_DEBUG ((LM_DEBUG,
00323 ACE_TEXT ("TAO (%P|%t) - ")
00324 ACE_TEXT ("DIOP_Acceptor::open, specified host=%s:%d\n"),
00325 (specified_hostname.length () == 0 ? "<null>" : specified_hostname.c_str ()),
00326 addr.get_port_number ()));
00327 }
00328
00329 this->endpoint_count_ = 1;
00330
00331 ACE_NEW_RETURN (this->addrs_,
00332 ACE_INET_Addr[this->endpoint_count_],
00333 -1);
00334
00335 ACE_NEW_RETURN (this->hosts_,
00336 char *[this->endpoint_count_],
00337 -1);
00338
00339 this->hosts_[0] = 0;
00340
00341 if (this->hostname (orb_core,
00342 addr,
00343 this->hosts_[0],
00344 specified_hostname.c_str ()) != 0)
00345 return -1;
00346
00347
00348
00349 if (this->addrs_[0].set (addr) != 0)
00350 return -1;
00351
00352 return this->open_i (addr,
00353 reactor);
00354 }
00355
00356 int
00357 TAO_DIOP_Acceptor::open_default (TAO_ORB_Core *orb_core,
00358 ACE_Reactor *reactor,
00359 int major,
00360 int minor,
00361 const char *options)
00362 {
00363 this->orb_core_ = orb_core;
00364
00365 if (this->hosts_ != 0)
00366 {
00367
00368
00369 ACE_ERROR_RETURN ((LM_ERROR,
00370 ACE_TEXT ("TAO (%P|%t) - ")
00371 ACE_TEXT ("DIOP_Acceptor::open_default, ")
00372 ACE_TEXT ("hostname already set\n\n")),
00373 -1);
00374 }
00375
00376 if (major >= 0 && minor >= 0)
00377 this->version_.set_version (static_cast<CORBA::Octet> (major),
00378 static_cast<CORBA::Octet> (minor));
00379
00380
00381 if (this->parse_options (options) == -1)
00382 return -1;
00383
00384
00385 if (this->probe_interfaces (orb_core) == -1)
00386 return -1;
00387
00388
00389
00390
00391 ACE_INET_Addr addr;
00392
00393 if (addr.set (this->default_address_) != 0)
00394 return -1;
00395
00396 return this->open_i (addr, reactor);
00397 }
00398
00399 int
00400 TAO_DIOP_Acceptor::open_i (const ACE_INET_Addr& addr,
00401 ACE_Reactor *reactor)
00402 {
00403 ACE_NEW_RETURN (this->connection_handler_,
00404 TAO_DIOP_Connection_Handler (this->orb_core_),
00405 -1);
00406
00407 this->connection_handler_->local_addr (addr);
00408 int result = this->connection_handler_->open_server ();
00409 if (result == -1)
00410 {
00411 delete this->connection_handler_;
00412 return result;
00413 }
00414
00415
00416 result =
00417 reactor->register_handler (this->connection_handler_,
00418 ACE_Event_Handler::READ_MASK);
00419 if (result == -1)
00420 {
00421
00422 this->connection_handler_->close ();
00423 return result;
00424 }
00425
00426
00427 this->connection_handler_->remove_reference ();
00428
00429 ACE_INET_Addr address;
00430
00431
00432
00433 if (this->connection_handler_->peer ().get_local_addr (address) != 0)
00434 {
00435 if (TAO_debug_level > 0)
00436 ACE_ERROR ((LM_ERROR,
00437 ACE_TEXT ("TAO (%P|%t) DIOP_Acceptor::open_i, ")
00438 ACE_TEXT ("%p"),
00439 ACE_TEXT ("cannot get local addr\n\n")));
00440 return -1;
00441 }
00442
00443
00444
00445
00446
00447 unsigned short port = address.get_port_number ();
00448 for (CORBA::ULong j = 0; j < this->endpoint_count_; ++j)
00449 this->addrs_[j].set_port_number (port, 1);
00450
00451 this->default_address_.set_port_number (port);
00452
00453 if (TAO_debug_level > 5)
00454 {
00455 for (CORBA::ULong i = 0; i < this->endpoint_count_; ++i)
00456 {
00457 ACE_DEBUG ((LM_DEBUG,
00458 ACE_TEXT ("TAO (%P|%t) - DIOP_Acceptor::open_i, ")
00459 ACE_TEXT ("listening on: <%s:%u>\n"),
00460 ACE_TEXT_CHAR_TO_TCHAR (this->hosts_[i]),
00461 this->addrs_[i].get_port_number ()));
00462 }
00463 }
00464
00465 return 0;
00466 }
00467
00468 int
00469 TAO_DIOP_Acceptor::hostname (TAO_ORB_Core *orb_core,
00470 ACE_INET_Addr &addr,
00471 char *&host,
00472 const char *specified_hostname)
00473 {
00474 if (orb_core->orb_params ()->use_dotted_decimal_addresses ())
00475 {
00476
00477
00478 return this->dotted_decimal_address (addr, host);
00479 }
00480 else if (specified_hostname != 0)
00481 {
00482
00483
00484 host = CORBA::string_dup (specified_hostname);
00485 }
00486 else
00487 {
00488 char tmp_host[MAXHOSTNAMELEN + 1];
00489
00490
00491 #if defined (ACE_HAS_IPV6)
00492
00493
00494
00495
00496 if (addr.is_ipv4_compat_ipv6 () ||
00497 addr.get_host_name (tmp_host, sizeof (tmp_host)) != 0)
00498 #else
00499 if (addr.get_host_name (tmp_host, sizeof (tmp_host)) != 0)
00500 #endif
00501 {
00502
00503 return this->dotted_decimal_address (addr, host);
00504 }
00505 else
00506 {
00507 host = CORBA::string_dup (tmp_host);
00508 }
00509 }
00510
00511 return 0;
00512 }
00513
00514 int
00515 TAO_DIOP_Acceptor::parse_address (const char *address,
00516 ACE_INET_Addr &addr,
00517 ACE_CString &specified_hostname,
00518 int *def_type)
00519 {
00520 {
00521 ACE_INET_Addr tmp;
00522 addr.set (tmp);
00523 specified_hostname.clear();
00524 }
00525
00526 const char *port_separator_loc = ACE_OS::strchr (address, ':');
00527 char tmp_host[MAXHOSTNAMELEN + 1];
00528 tmp_host[0] = '\0';
00529 bool host_defaulted = port_separator_loc == address;
00530 bool ipv6_in_host = false;
00531 if (def_type)
00532 *def_type = AF_UNSPEC;
00533
00534 #if defined (ACE_HAS_IPV6)
00535
00536
00537 if ((this->version_.major > TAO_MIN_IPV6_IIOP_MAJOR ||
00538 this->version_.minor >= TAO_MIN_IPV6_IIOP_MINOR) &&
00539 address[0] == '[')
00540 {
00541
00542
00543 char const * const cp_pos = ACE_OS::strchr (address, ']');
00544 if (cp_pos == 0)
00545 {
00546
00547 ACE_ERROR_RETURN ((LM_ERROR,
00548 ACE_TEXT ("TAO (%P|%t) - ")
00549 ACE_TEXT ("DIOP_Acceptor::open, ")
00550 ACE_TEXT ("invalid IPv6 decimal address specified\n\n")),
00551 -1);
00552 }
00553 else
00554 {
00555
00556 size_t const len = cp_pos - (address + 1);
00557
00558 if (len >= sizeof (tmp_host))
00559 return -1;
00560
00561 ipv6_in_host = true;
00562 host_defaulted = (cp_pos == address+1) ||
00563 (cp_pos == address+3 && address[1] == ':' && address[2] == ':');
00564 if (cp_pos[1] == ':')
00565 port_separator_loc = cp_pos + 1;
00566 else
00567 port_separator_loc = 0;
00568 if (def_type)
00569 *def_type = AF_INET6;
00570
00571 ACE_OS::memcpy (tmp_host, address + 1, len);
00572 tmp_host[len] = '\0';
00573 }
00574 }
00575 else
00576 #endif
00577 if (!host_defaulted)
00578 {
00579 if (port_separator_loc != 0)
00580 {
00581
00582 size_t const len = port_separator_loc - address;
00583
00584 if (len >= sizeof (tmp_host))
00585 return -1;
00586
00587 ACE_OS::memcpy (tmp_host, address, len);
00588 tmp_host[len] = '\0';
00589 }
00590 else
00591 ACE_OS::strcpy (tmp_host, address);
00592 }
00593
00594 if (!ipv6_in_host && !host_defaulted)
00595 {
00596 if (addr.set ((unsigned short) 0, tmp_host) != 0)
00597 return -1;
00598 this->default_address_.set (addr);
00599 host_defaulted = addr.is_any ();
00600 if (def_type)
00601 *def_type = AF_INET;
00602 }
00603
00604 if (host_defaulted)
00605 {
00606
00607 unsigned short portno = 0;
00608 if (port_separator_loc != 0)
00609 {
00610 portno =
00611 static_cast<u_short> (ACE_OS::atoi (port_separator_loc +
00612 sizeof (':')));
00613 }
00614 this->default_address_.set_port_number (portno);
00615
00616
00617 if (addr.set (this->default_address_) != 0)
00618 return -1;
00619 }
00620 else if (port_separator_loc == 0)
00621 {
00622
00623
00624 specified_hostname = tmp_host[0] == '\0' ? address : tmp_host;
00625 if (addr.set ((unsigned short) 0,
00626 specified_hostname.c_str ()) != 0)
00627 return -1;
00628 }
00629 else
00630 {
00631
00632 if (addr.set (address) != 0)
00633 return -1;
00634 if (tmp_host[0] == '\0')
00635 {
00636
00637 size_t const len = port_separator_loc - address;
00638
00639 if (len >= sizeof (tmp_host))
00640 return -1;
00641
00642 ACE_OS::memcpy (tmp_host, address, len);
00643 tmp_host[len] = '\0';
00644 }
00645 specified_hostname = tmp_host;
00646 }
00647
00648 return 1;
00649 }
00650
00651 int
00652 TAO_DIOP_Acceptor::dotted_decimal_address (ACE_INET_Addr &addr,
00653 char *&host)
00654 {
00655 int result = 0;
00656 const char *tmp = 0;
00657
00658
00659
00660
00661
00662
00663 if (addr.is_any ())
00664 {
00665 ACE_INET_Addr new_addr;
00666 #if defined (ACE_HAS_IPV6)
00667 result = new_addr.set (addr.get_port_number (),
00668 addr.get_host_name (),
00669 1,
00670 addr.get_type ());
00671 #else
00672 result = new_addr.set (addr.get_port_number (),
00673 addr.get_host_name ());
00674 #endif
00675 tmp = new_addr.get_host_addr ();
00676 }
00677 else
00678 tmp = addr.get_host_addr ();
00679
00680 if (tmp == 0 || result != 0)
00681 {
00682 if (TAO_debug_level > 0)
00683 ACE_DEBUG ((LM_DEBUG,
00684 ACE_TEXT ("TAO (%P|%t) - ")
00685 ACE_TEXT ("DIOP_Acceptor::dotted_decimal_address, ")
00686 ACE_TEXT ("%p\n\n"),
00687 ACE_TEXT ("cannot determine hostname")));
00688 return -1;
00689 }
00690
00691 host = CORBA::string_dup (tmp);
00692 return 0;
00693 }
00694
00695 int
00696 TAO_DIOP_Acceptor::probe_interfaces (TAO_ORB_Core *orb_core, int def_type)
00697 {
00698
00699
00700
00701
00702 ACE_INET_Addr *if_addrs = 0;
00703 size_t if_cnt = 0;
00704
00705 if (ACE::get_ip_interfaces (if_cnt,
00706 if_addrs) != 0
00707 && errno != ENOTSUP)
00708 {
00709
00710
00711
00712 return -1;
00713 }
00714
00715 if (if_cnt == 0 || if_addrs == 0)
00716 {
00717 if (TAO_debug_level > 0)
00718 {
00719 ACE_DEBUG ((LM_WARNING,
00720 ACE_TEXT ("TAO (%P|%t) - Unable to probe network ")
00721 ACE_TEXT ("interfaces. Using default.")));
00722 }
00723
00724 if_cnt = 1;
00725 delete [] if_addrs;
00726 ACE_NEW_RETURN (if_addrs,
00727 ACE_INET_Addr[if_cnt],
00728 -1);
00729 }
00730
00731
00732
00733 size_t lo_cnt = 0;
00734 for (size_t j = 0; j < if_cnt; ++j)
00735 if (if_addrs[j].is_loopback ())
00736 lo_cnt++;
00737
00738 #if defined (ACE_HAS_IPV6)
00739 size_t ipv4_cnt = 0;
00740 size_t ipv4_lo_cnt = 0;
00741 size_t ipv6_ll = 0;
00742 bool ipv6_non_ll = false;
00743
00744
00745 for (size_t j = 0; j < if_cnt; ++j)
00746 if (if_addrs[j].get_type () != AF_INET6 ||
00747 if_addrs[j].is_ipv4_mapped_ipv6 ())
00748 {
00749 ++ipv4_cnt;
00750 if (if_addrs[j].is_loopback ())
00751 ++ipv4_lo_cnt;
00752 }
00753 else if (!if_addrs[j].is_linklocal () &&
00754 !if_addrs[j].is_loopback())
00755 {
00756 ipv6_non_ll = true;
00757 }
00758 else if (!orb_core->orb_params ()->use_ipv6_link_local () &&
00759 if_addrs[j].is_linklocal ())
00760 {
00761 ++ipv6_ll;
00762 }
00763 #endif
00764
00765
00766
00767 ACE_Auto_Basic_Array_Ptr<ACE_INET_Addr> safe_if_addrs (if_addrs);
00768
00769 #if defined (ACE_HAS_IPV6)
00770 bool ipv4_only = def_type == AF_INET;
00771 bool ipv6_only = (def_type == AF_INET6) ||
00772 orb_core->orb_params ()->connect_ipv6_only ();
00773 #if defined (ACE_WIN32)
00774 if (this->default_address_.get_type () == AF_INET)
00775 ipv4_only = true;
00776 else
00777 ipv6_only = true;
00778 #endif
00779
00780
00781
00782 bool ignore_lo;
00783 if (ipv6_only)
00784
00785 ignore_lo = ipv6_non_ll;
00786 else if (ipv4_only)
00787 ignore_lo = ipv4_cnt != ipv4_lo_cnt;
00788 else
00789 ignore_lo = if_cnt != lo_cnt;
00790
00791
00792 size_t if_ok_cnt = if_cnt;
00793 if (ipv6_only)
00794 {
00795 if_ok_cnt -= ipv4_cnt;
00796 lo_cnt -= ipv4_lo_cnt;
00797 ipv4_lo_cnt = 0;
00798 }
00799 else if (ipv4_only)
00800 {
00801 if_ok_cnt = ipv4_cnt;
00802 lo_cnt = ipv4_lo_cnt;
00803 }
00804
00805
00806
00807
00808
00809 if (!ipv4_only && !ipv6_non_ll)
00810 lo_cnt = ipv4_lo_cnt;
00811
00812 if (!ignore_lo)
00813 this->endpoint_count_ = static_cast<CORBA::ULong> (if_ok_cnt - ipv6_ll);
00814 else
00815 this->endpoint_count_ = static_cast<CORBA::ULong> (if_ok_cnt - ipv6_ll - lo_cnt);
00816 #else
00817
00818
00819
00820 bool ignore_lo;
00821 ignore_lo = if_cnt != lo_cnt;
00822 if (!ignore_lo)
00823 this->endpoint_count_ = static_cast<CORBA::ULong> (if_cnt);
00824 else
00825 this->endpoint_count_ = static_cast<CORBA::ULong> (if_cnt - lo_cnt);
00826 #endif
00827
00828 if (this->endpoint_count_ == 0)
00829 {
00830 if (TAO_debug_level > 0)
00831 ACE_DEBUG ((LM_DEBUG,
00832 ACE_TEXT("(%P|%t) - DIOP_Acceptor::probe_interfaces, ")
00833 ACE_TEXT("found no usable addresses, def_type = %d\n"),
00834 def_type));
00835 return -1;
00836 }
00837
00838 ACE_NEW_RETURN (this->addrs_,
00839 ACE_INET_Addr[this->endpoint_count_],
00840 -1);
00841
00842 ACE_NEW_RETURN (this->hosts_,
00843 char *[this->endpoint_count_],
00844 -1);
00845
00846 ACE_OS::memset (this->hosts_, 0, sizeof (char*) * this->endpoint_count_);
00847
00848
00849
00850
00851 size_t host_cnt = 0;
00852
00853 for (size_t i = 0; i < if_cnt; ++i)
00854 {
00855 #if defined (ACE_HAS_IPV6)
00856
00857
00858 if (ignore_lo &&
00859 if_addrs[i].is_loopback () &&
00860 (ipv4_only ||
00861 ipv6_non_ll ||
00862 if_addrs[i].get_type () != AF_INET6))
00863 continue;
00864
00865
00866 if (ipv4_only &&
00867 (if_addrs[i].get_type () != AF_INET))
00868 continue;
00869
00870
00871 if (ipv6_only &&
00872 (if_addrs[i].get_type () != AF_INET6 ||
00873 if_addrs[i].is_ipv4_mapped_ipv6 ()))
00874 continue;
00875
00876
00877 if (!orb_core->orb_params ()->use_ipv6_link_local () &&
00878 if_addrs[i].is_linklocal ())
00879 continue;
00880 #else
00881
00882
00883 if (ignore_lo &&
00884 if_addrs[i].is_loopback ())
00885 continue;
00886 #endif
00887
00888 if (this->hostname (orb_core,
00889 if_addrs[i],
00890 this->hosts_[host_cnt]) != 0)
00891 return -1;
00892
00893
00894
00895 if (this->addrs_[host_cnt].set (if_addrs[i]) != 0)
00896 return -1;
00897
00898 host_cnt++;
00899 }
00900
00901 return 0;
00902 }
00903
00904 CORBA::ULong
00905 TAO_DIOP_Acceptor::endpoint_count (void)
00906 {
00907 return this->endpoint_count_;
00908 }
00909
00910 int
00911 TAO_DIOP_Acceptor::object_key (IOP::TaggedProfile &profile,
00912 TAO::ObjectKey &object_key)
00913 {
00914
00915 #if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
00916 TAO_InputCDR cdr (profile.profile_data.mb ());
00917 #else
00918 TAO_InputCDR cdr (reinterpret_cast<char*> (profile.profile_data.get_buffer ()),
00919 profile.profile_data.length ());
00920 #endif
00921
00922 CORBA::Octet major;
00923 CORBA::Octet minor = CORBA::Octet();
00924
00925
00926
00927 if (!(cdr.read_octet (major)
00928 && cdr.read_octet (minor)))
00929 {
00930 if (TAO_debug_level > 0)
00931 {
00932 ACE_DEBUG ((LM_DEBUG,
00933 ACE_TEXT ("TAO (%P|%t) - DIOP_Profile::object_key, v%d.%d\n"),
00934 major,
00935 minor));
00936 }
00937 return -1;
00938 }
00939
00940 CORBA::String_var host;
00941 CORBA::UShort port = 0;
00942
00943
00944 if (cdr.read_string (host.out ()) == 0
00945 || cdr.read_ushort (port) == 0)
00946 {
00947 if (TAO_debug_level > 0)
00948 {
00949 ACE_DEBUG ((LM_DEBUG,
00950 ACE_TEXT ("TAO (%P|%t) - DIOP_Acceptor::object_key, ")
00951 ACE_TEXT ("error while decoding host/port")));
00952 }
00953 return -1;
00954 }
00955
00956
00957 if ((cdr >> object_key) == 0)
00958 return -1;
00959
00960
00961
00962 return 1;
00963 }
00964
00965 int
00966 TAO_DIOP_Acceptor::parse_options (const char *str)
00967 {
00968 if (str == 0)
00969 return 0;
00970
00971
00972
00973
00974
00975 const ACE_CString options (str);
00976
00977 const size_t len = options.length ();
00978
00979 static const char option_delimiter = '&';
00980
00981
00982 CORBA::ULong option_count = 1;
00983
00984
00985
00986 for (size_t i = 0; i < len; ++i)
00987 if (options[i] == option_delimiter)
00988 ++option_count;
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998 ACE_CString::size_type begin = 0;
00999 ACE_CString::size_type end = 0;
01000
01001 for (CORBA::ULong j = 0; j < option_count;)
01002 {
01003 if (j < option_count - 1)
01004 end = options.find (option_delimiter, begin);
01005 else
01006 end = len;
01007
01008 ++j;
01009
01010 if (end == begin)
01011 {
01012 ACE_ERROR_RETURN ((LM_ERROR,
01013 ACE_TEXT ("TAO (%P|%t) - Zero length DIOP option.\n")),
01014 -1);
01015 }
01016 else if (end != ACE_CString::npos)
01017 {
01018 ACE_CString opt = options.substring (begin, end - begin);
01019
01020 ACE_CString::size_type const slot = opt.find ("=");
01021
01022 if (slot == len - 1
01023 || slot == ACE_CString::npos)
01024 ACE_ERROR_RETURN ((LM_ERROR,
01025 ACE_TEXT ("TAO (%P|%t) - DIOP option <%s> is ")
01026 ACE_TEXT ("missing a value.\n"),
01027 ACE_TEXT_CHAR_TO_TCHAR (opt.c_str ())),
01028 -1);
01029
01030 ACE_CString name = opt.substring (0, slot);
01031 ACE_CString value = opt.substring (slot + 1);
01032
01033 begin = end + 1;
01034
01035 if (name.length () == 0)
01036 ACE_ERROR_RETURN ((LM_ERROR,
01037 ACE_TEXT ("TAO (%P|%t) - Zero length DIOP ")
01038 ACE_TEXT ("option name.\n")),
01039 -1);
01040
01041 if (name == "priority")
01042 {
01043 ACE_ERROR_RETURN ((LM_ERROR,
01044 ACE_TEXT ("TAO (%P|%t) - Invalid DIOP endpoint format: ")
01045 ACE_TEXT ("endpoint priorities no longer supported. \n")),
01046 -1);
01047 }
01048 else
01049 {
01050 ACE_ERROR_RETURN ((LM_ERROR,
01051 ACE_TEXT ("TAO (%P|%t) - Invalid DIOP option: <%s>\n"),
01052 ACE_TEXT_CHAR_TO_TCHAR (name.c_str ())),
01053 -1);
01054 }
01055 }
01056 else
01057 {
01058 break;
01059 }
01060 }
01061 return 0;
01062 }
01063
01064 TAO_END_VERSIONED_NAMESPACE_DECL
01065
01066 #endif