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