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