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 78995 2007-07-23 11:59:20Z johnnyw $")
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_ (),
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,
00393 reactor);
00394 }
00395
00396 int
00397 TAO_IIOP_Acceptor::open_default (TAO_ORB_Core *orb_core,
00398 ACE_Reactor *reactor,
00399 int major,
00400 int minor,
00401 const char *options)
00402 {
00403 this->orb_core_ = orb_core;
00404
00405 if (this->hosts_ != 0)
00406 {
00407
00408
00409 ACE_ERROR_RETURN ((LM_ERROR,
00410 ACE_TEXT ("TAO (%P|%t) - ")
00411 ACE_TEXT ("IIOP_Acceptor::open_default, ")
00412 ACE_TEXT ("hostname already set\n\n")),
00413 -1);
00414 }
00415
00416 if (major >= 0 && minor >= 0)
00417 this->version_.set_version (static_cast<CORBA::Octet> (major),
00418 static_cast<CORBA::Octet> (minor));
00419
00420
00421 if (this->parse_options (options) == -1)
00422 return -1;
00423
00424
00425 if (this->probe_interfaces (orb_core) == -1)
00426 return -1;
00427
00428
00429
00430
00431 ACE_INET_Addr addr;
00432
00433 if (addr.set (this->default_address_) != 0)
00434 return -1;
00435
00436 return this->open_i (addr, reactor);
00437 }
00438
00439 int
00440 TAO_IIOP_Acceptor::open_i (const ACE_INET_Addr& addr,
00441 ACE_Reactor *reactor)
00442 {
00443 ACE_NEW_RETURN (this->creation_strategy_,
00444 CREATION_STRATEGY (this->orb_core_),
00445 -1);
00446
00447 ACE_NEW_RETURN (this->concurrency_strategy_,
00448 CONCURRENCY_STRATEGY (this->orb_core_),
00449 -1);
00450
00451 ACE_NEW_RETURN (this->accept_strategy_,
00452 ACCEPT_STRATEGY (this->orb_core_),
00453 -1);
00454
00455 unsigned short requested_port = addr.get_port_number ();
00456 if (requested_port == 0)
00457 {
00458
00459 if (this->base_acceptor_.open (addr,
00460 reactor,
00461 this->creation_strategy_,
00462 this->accept_strategy_,
00463 this->concurrency_strategy_,
00464 0, 0, 0, 1,
00465 this->reuse_addr_) == -1)
00466 {
00467 if (TAO_debug_level > 0)
00468 ACE_DEBUG ((LM_DEBUG,
00469 ACE_TEXT ("TAO (%P|%t) - IIOP_Acceptor::open_i, ")
00470 ACE_TEXT ("%p, "),
00471 ACE_TEXT ("cannot open acceptor\n")));
00472 return -1;
00473 }
00474 }
00475 else
00476 {
00477 ACE_INET_Addr a(addr);
00478
00479 bool found_a_port = false;
00480 ACE_UINT32 last_port = requested_port + this->port_span_ - 1;
00481 if (last_port > ACE_MAX_DEFAULT_PORT)
00482 {
00483 last_port = ACE_MAX_DEFAULT_PORT;
00484 }
00485
00486 for (ACE_UINT32 p = requested_port; p <= last_port; p++)
00487 {
00488 if (TAO_debug_level > 5)
00489 ACE_DEBUG ((LM_DEBUG,
00490 ACE_TEXT ("TAO (%P|%t) - IIOP_Acceptor::open_i, ")
00491 ACE_TEXT ("trying to listen on port %d\n"), p));
00492
00493
00494 a.set_port_number ((u_short)p);
00495 if (this->base_acceptor_.open (a,
00496 reactor,
00497 this->creation_strategy_,
00498 this->accept_strategy_,
00499 this->concurrency_strategy_,
00500 0, 0, 0, 1,
00501 this->reuse_addr_) != -1)
00502 {
00503 found_a_port = true;
00504 break;
00505 }
00506 }
00507
00508
00509 if (! found_a_port)
00510 {
00511 if (TAO_debug_level > 0)
00512 ACE_DEBUG ((LM_DEBUG,
00513 ACE_TEXT ("TAO (%P|%t) - IIOP_Acceptor::open_i, ")
00514 ACE_TEXT ("cannot open acceptor in port range (%d,%d)")
00515 ACE_TEXT ("- %p\n"),
00516 requested_port, last_port, ACE_TEXT("")));
00517 return -1;
00518 }
00519 }
00520
00521 #if defined (ACE_HAS_IPV6) && defined (ACE_HAS_IPV6_V6ONLY)
00522
00523
00524 if (this->orb_core_->orb_params ()->connect_ipv6_only () &&
00525 addr.is_any ())
00526 {
00527 if (TAO_debug_level > 5)
00528 ACE_DEBUG ((LM_DEBUG,
00529 ACE_TEXT("TAO (%P|%t) - IIOP_Acceptor::open_i, ")
00530 ACE_TEXT("setting IPV6_V6ONLY\n")));
00531
00532
00533 int on = 1;
00534 if (this->base_acceptor_.acceptor ().set_option (IPPROTO_IPV6,
00535 IPV6_V6ONLY,
00536 (void *) &on,
00537 sizeof (on)) == -1)
00538 {
00539 ACE_ERROR ((LM_ERROR,
00540 ACE_TEXT ("TAO (%P|%t) - IIOP_Acceptor::open_i, ")
00541 ACE_TEXT ("%p\n"),
00542 ACE_TEXT ("cannot set IPV6_V6ONLY")));
00543 }
00544 }
00545 #endif
00546
00547 ACE_INET_Addr address;
00548
00549
00550
00551 if (this->base_acceptor_.acceptor ().get_local_addr (address) != 0)
00552 {
00553 if (TAO_debug_level > 0)
00554 ACE_ERROR ((LM_ERROR,
00555 ACE_TEXT ("TAO (%P|%t) - IIOP_Acceptor::open_i, ")
00556 ACE_TEXT ("%p"),
00557 ACE_TEXT ("cannot get local addr\n")));
00558 return -1;
00559 }
00560
00561
00562
00563
00564
00565 unsigned short port = address.get_port_number ();
00566 for (CORBA::ULong j = 0; j < this->endpoint_count_; ++j)
00567 this->addrs_[j].set_port_number (port, 1);
00568
00569 this->default_address_.set_port_number (port);
00570
00571 (void) this->base_acceptor_.acceptor().enable (ACE_CLOEXEC);
00572
00573
00574
00575
00576 if (TAO_debug_level > 5)
00577 {
00578 for (CORBA::ULong i = 0; i < this->endpoint_count_; ++i)
00579 {
00580 ACE_DEBUG ((LM_DEBUG,
00581 ACE_TEXT ("TAO (%P|%t) - IIOP_Acceptor::open_i, ")
00582 ACE_TEXT ("listening on: <%s:%u>\n"),
00583 ACE_TEXT_CHAR_TO_TCHAR(this->hosts_[i]),
00584 this->addrs_[i].get_port_number ()));
00585 }
00586 }
00587
00588 return 0;
00589 }
00590
00591 int
00592 TAO_IIOP_Acceptor::hostname (TAO_ORB_Core *orb_core,
00593 ACE_INET_Addr &addr,
00594 char *&host,
00595 const char *specified_hostname)
00596 {
00597 if (this->hostname_in_ior_ != 0)
00598 {
00599 if (TAO_debug_level >= 5)
00600 ACE_DEBUG ((LM_DEBUG,
00601 ACE_TEXT ("TAO (%P|%t) IIOP_Acceptor - ")
00602 ACE_TEXT ("Overriding the hostname with <%s>\n"),
00603 this->hostname_in_ior_));
00604
00605 host = CORBA::string_dup (this->hostname_in_ior_);
00606 }
00607 else if (orb_core->orb_params ()->use_dotted_decimal_addresses ())
00608 {
00609
00610
00611 return this->dotted_decimal_address (addr, host);
00612 }
00613 else if (specified_hostname != 0)
00614 {
00615
00616
00617 host = CORBA::string_dup (specified_hostname);
00618 }
00619 else
00620 {
00621 char tmp_host[MAXHOSTNAMELEN + 1];
00622
00623
00624 #if defined (ACE_HAS_IPV6)
00625
00626
00627
00628
00629 if (addr.is_ipv4_compat_ipv6 () ||
00630 addr.get_host_name (tmp_host, sizeof (tmp_host)) != 0)
00631 #else
00632 if (addr.get_host_name (tmp_host, sizeof (tmp_host)) != 0)
00633 #endif
00634 {
00635
00636 return this->dotted_decimal_address (addr, host);
00637 }
00638 else
00639 {
00640 host = CORBA::string_dup (tmp_host);
00641 }
00642 }
00643
00644 return 0;
00645 }
00646
00647
00648 int
00649 TAO_IIOP_Acceptor::parse_address (const char *address,
00650 ACE_INET_Addr &addr,
00651 ACE_CString &specified_hostname,
00652 int *def_type)
00653 {
00654 {
00655 ACE_INET_Addr tmp;
00656 addr.set (tmp);
00657 specified_hostname.clear();
00658 }
00659
00660 const char *port_separator_loc = ACE_OS::strchr (address, ':');
00661 char tmp_host[MAXHOSTNAMELEN + 1];
00662 tmp_host[0] = '\0';
00663 bool host_defaulted = port_separator_loc == address;
00664 bool ipv6_in_host = false;
00665 if (def_type)
00666 *def_type = AF_UNSPEC;
00667
00668 #if defined (ACE_HAS_IPV6)
00669
00670
00671 if ((this->version_.major > TAO_MIN_IPV6_IIOP_MAJOR ||
00672 this->version_.minor >= TAO_MIN_IPV6_IIOP_MINOR) &&
00673 address[0] == '[')
00674 {
00675
00676
00677 char const * const cp_pos = ACE_OS::strchr (address, ']');
00678 if (cp_pos == 0)
00679 {
00680
00681 ACE_ERROR_RETURN ((LM_ERROR,
00682 ACE_TEXT ("TAO (%P|%t) - ")
00683 ACE_TEXT ("IIOP_Acceptor::open, ")
00684 ACE_TEXT ("Invalid IPv6 decimal address specified\n\n")),
00685 -1);
00686 }
00687 else
00688 {
00689
00690 size_t const len = cp_pos - (address + 1);
00691
00692 if (len >= sizeof (tmp_host))
00693 return -1;
00694
00695 ipv6_in_host = true;
00696 host_defaulted = (cp_pos == address+1) ||
00697 (cp_pos == address+3 && address[1] == ':' && address[2] == ':');
00698 if (cp_pos[1] == ':')
00699 port_separator_loc = cp_pos + 1;
00700 else
00701 port_separator_loc = 0;
00702 if (def_type)
00703 *def_type = AF_INET6;
00704
00705 ACE_OS::memcpy (tmp_host, address + 1, len);
00706 tmp_host[len] = '\0';
00707 }
00708 }
00709 else
00710 #endif
00711 if (!host_defaulted)
00712 {
00713 if (port_separator_loc != 0)
00714 {
00715
00716 size_t const len = port_separator_loc - address;
00717
00718 if (len >= sizeof (tmp_host))
00719 return -1;
00720
00721 ACE_OS::memcpy (tmp_host, address, len);
00722 tmp_host[len] = '\0';
00723 }
00724 else
00725 ACE_OS::strcpy (tmp_host, address);
00726 }
00727
00728 if (!ipv6_in_host && !host_defaulted)
00729 {
00730 if (addr.set((unsigned short)0,tmp_host) != 0)
00731 return -1;
00732 this->default_address_.set(addr);
00733 host_defaulted = addr.is_any();
00734 if (def_type)
00735 *def_type = AF_INET;
00736 }
00737
00738 if (host_defaulted)
00739 {
00740
00741 unsigned short portno = 0;
00742 if (port_separator_loc != 0)
00743 {
00744 portno =
00745 static_cast<u_short> (ACE_OS::atoi (port_separator_loc +
00746 sizeof (':')));
00747 }
00748 this->default_address_.set_port_number (portno);
00749
00750
00751 if (addr.set (this->default_address_) != 0)
00752 return -1;
00753 }
00754 else if (port_separator_loc == 0)
00755 {
00756
00757
00758 specified_hostname = tmp_host[0] == '\0' ? address : tmp_host;
00759 if (addr.set ((unsigned short) 0,
00760 specified_hostname.c_str()) != 0)
00761 return -1;
00762 }
00763 else
00764 {
00765
00766 if (addr.set (address) != 0)
00767 return -1;
00768 if (tmp_host[0] == '\0')
00769 {
00770
00771 size_t const len = port_separator_loc - address;
00772
00773 if (len >= sizeof (tmp_host))
00774 return -1;
00775
00776 ACE_OS::memcpy (tmp_host, address, len);
00777 tmp_host[len] = '\0';
00778 }
00779 specified_hostname = tmp_host;
00780 }
00781
00782 return 1;
00783 }
00784
00785
00786 int
00787 TAO_IIOP_Acceptor::dotted_decimal_address (ACE_INET_Addr &addr,
00788 char *&host)
00789 {
00790 int result = 0;
00791 const char *tmp = 0;
00792
00793
00794
00795
00796
00797
00798 if (addr.is_any ())
00799 {
00800 ACE_INET_Addr new_addr;
00801 #if defined (ACE_HAS_IPV6)
00802 result = new_addr.set (addr.get_port_number (),
00803 addr.get_host_name (),
00804 1,
00805 addr.get_type ());
00806 #else
00807 result = new_addr.set (addr.get_port_number (),
00808 addr.get_host_name ());
00809 #endif
00810 tmp = new_addr.get_host_addr ();
00811 }
00812 else
00813 tmp = addr.get_host_addr ();
00814
00815 if (tmp == 0 || result != 0)
00816 {
00817 if (TAO_debug_level > 0)
00818 ACE_ERROR ((LM_ERROR,
00819 ACE_TEXT ("TAO (%P|%t) - ")
00820 ACE_TEXT ("IIOP_Acceptor::dotted_decimal_address, ")
00821 ACE_TEXT ("- %p, "),
00822 ACE_TEXT ("cannot determine hostname\n")));
00823 return -1;
00824 }
00825
00826 host = CORBA::string_dup (tmp);
00827 return 0;
00828 }
00829
00830 int
00831 TAO_IIOP_Acceptor::probe_interfaces (TAO_ORB_Core *orb_core, int def_type)
00832 {
00833
00834
00835
00836
00837 ACE_INET_Addr *if_addrs = 0;
00838 size_t if_cnt = 0;
00839
00840 if (ACE::get_ip_interfaces (if_cnt, if_addrs) != 0
00841 && errno != ENOTSUP)
00842 {
00843
00844
00845
00846 return -1;
00847 }
00848
00849 if (if_cnt == 0 || if_addrs == 0)
00850 {
00851 if (TAO_debug_level > 0)
00852 {
00853 ACE_DEBUG ((LM_WARNING,
00854 ACE_TEXT ("TAO (%P|%t) - Unable to probe network ")
00855 ACE_TEXT ("interfaces. Using default.\n")));
00856 }
00857
00858 if_cnt = 1;
00859 delete [] if_addrs;
00860 ACE_NEW_RETURN (if_addrs,
00861 ACE_INET_Addr[if_cnt],
00862 -1);
00863 }
00864
00865
00866
00867 size_t lo_cnt = 0;
00868 for (size_t j = 0; j < if_cnt; ++j)
00869 if (if_addrs[j].is_loopback ())
00870 ++lo_cnt;
00871
00872 #if defined (ACE_HAS_IPV6)
00873 size_t ipv4_cnt = 0;
00874 size_t ipv4_lo_cnt = 0;
00875 size_t ipv6_ll = 0;
00876 bool ipv6_non_ll = false;
00877
00878
00879 for (size_t j = 0; j < if_cnt; ++j)
00880 if (if_addrs[j].get_type () != AF_INET6 ||
00881 if_addrs[j].is_ipv4_mapped_ipv6 ())
00882 {
00883 ++ipv4_cnt;
00884 if (if_addrs[j].is_loopback ())
00885 ++ipv4_lo_cnt;
00886 }
00887 else if (!if_addrs[j].is_linklocal () &&
00888 !if_addrs[j].is_loopback())
00889 {
00890 ipv6_non_ll = true;
00891 }
00892 else if (!orb_core->orb_params ()->use_ipv6_link_local () &&
00893 if_addrs[j].is_linklocal ())
00894 {
00895 ++ipv6_ll;
00896 }
00897 #endif
00898
00899
00900
00901 ACE_Auto_Basic_Array_Ptr<ACE_INET_Addr> safe_if_addrs (if_addrs);
00902
00903 #if defined (ACE_HAS_IPV6)
00904 bool ipv4_only = def_type == AF_INET;
00905 bool ipv6_only = (def_type == AF_INET6) ||
00906 orb_core->orb_params ()->connect_ipv6_only ();
00907 #if defined (ACE_WIN32)
00908 if (this->default_address_.get_type () == AF_INET)
00909 ipv4_only = true;
00910 else
00911 ipv6_only = true;
00912 #endif
00913
00914
00915
00916 bool ignore_lo;
00917 if (ipv6_only)
00918
00919 ignore_lo = ipv6_non_ll;
00920 else if (ipv4_only)
00921 ignore_lo = ipv4_cnt != ipv4_lo_cnt;
00922 else
00923 ignore_lo = if_cnt != lo_cnt;
00924
00925
00926 size_t if_ok_cnt = if_cnt;
00927 if (ipv6_only)
00928 {
00929 if_ok_cnt -= ipv4_cnt;
00930 lo_cnt -= ipv4_lo_cnt;
00931 ipv4_lo_cnt = 0;
00932 }
00933 else if (ipv4_only)
00934 {
00935 if_ok_cnt = ipv4_cnt;
00936 lo_cnt = ipv4_lo_cnt;
00937 ipv6_ll = 0;
00938 }
00939
00940
00941
00942
00943
00944 if (!ipv4_only && !ipv6_non_ll)
00945 lo_cnt = ipv4_lo_cnt;
00946
00947 if (!ignore_lo)
00948 this->endpoint_count_ = static_cast<CORBA::ULong> (if_ok_cnt - ipv6_ll);
00949 else
00950 this->endpoint_count_ = static_cast<CORBA::ULong> (if_ok_cnt - ipv6_ll - lo_cnt);
00951 #else
00952
00953
00954
00955 bool ignore_lo;
00956 ignore_lo = if_cnt != lo_cnt;
00957 if (!ignore_lo)
00958 this->endpoint_count_ = static_cast<CORBA::ULong> (if_cnt);
00959 else
00960 this->endpoint_count_ = static_cast<CORBA::ULong> (if_cnt - lo_cnt);
00961 #endif
00962
00963 if (this->endpoint_count_ == 0)
00964 {
00965 if (TAO_debug_level > 0)
00966 ACE_DEBUG ((LM_DEBUG,
00967 ACE_TEXT("(%P|%t) TAO_IIOP_Acceptor::probe_interfaces ")
00968 ACE_TEXT("found no usable addresses, def_type = %d\n"),
00969 def_type));
00970 return -1;
00971 }
00972
00973 ACE_NEW_RETURN (this->addrs_,
00974 ACE_INET_Addr[this->endpoint_count_],
00975 -1);
00976
00977 ACE_NEW_RETURN (this->hosts_,
00978 char *[this->endpoint_count_],
00979 -1);
00980
00981 ACE_OS::memset (this->hosts_, 0, sizeof (char*) * this->endpoint_count_);
00982
00983
00984
00985
00986 size_t host_cnt = 0;
00987
00988 for (size_t i = 0; i < if_cnt; ++i)
00989 {
00990 #if defined (ACE_HAS_IPV6)
00991
00992
00993 if (ignore_lo &&
00994 if_addrs[i].is_loopback () &&
00995 (ipv4_only ||
00996 ipv6_non_ll ||
00997 if_addrs[i].get_type () != AF_INET6))
00998 continue;
00999
01000
01001 if (ipv4_only &&
01002 (if_addrs[i].get_type () != AF_INET))
01003 continue;
01004
01005
01006 if (ipv6_only &&
01007 (if_addrs[i].get_type () != AF_INET6 ||
01008 if_addrs[i].is_ipv4_mapped_ipv6 ()))
01009 continue;
01010
01011
01012 if (!orb_core->orb_params ()->use_ipv6_link_local () &&
01013 if_addrs[i].is_linklocal ())
01014 continue;
01015 #else
01016
01017
01018 if (ignore_lo &&
01019 if_addrs[i].is_loopback ())
01020 continue;
01021 #endif
01022
01023 if (this->hostname (orb_core,
01024 if_addrs[i],
01025 this->hosts_[host_cnt]) != 0)
01026 return -1;
01027
01028
01029
01030 if (this->addrs_[host_cnt].set (if_addrs[i]) != 0)
01031 return -1;
01032
01033 ++host_cnt;
01034 }
01035
01036 return 0;
01037 }
01038
01039 CORBA::ULong
01040 TAO_IIOP_Acceptor::endpoint_count (void)
01041 {
01042 return this->endpoint_count_;
01043 }
01044
01045 int
01046 TAO_IIOP_Acceptor::object_key (IOP::TaggedProfile &profile,
01047 TAO::ObjectKey &object_key)
01048 {
01049
01050 #if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
01051 TAO_InputCDR cdr (profile.profile_data.mb ());
01052 #else
01053 TAO_InputCDR cdr (reinterpret_cast<char*> (profile.profile_data.get_buffer ()),
01054 profile.profile_data.length ());
01055 #endif
01056
01057 CORBA::Octet major;
01058 CORBA::Octet minor = CORBA::Octet();
01059
01060
01061
01062 if (!(cdr.read_octet (major)
01063 && cdr.read_octet (minor)))
01064 {
01065 if (TAO_debug_level > 0)
01066 {
01067 ACE_DEBUG ((LM_DEBUG,
01068 ACE_TEXT ("TAO (%P|%t) - TAO_IIOP_Acceptor::object_key, v%d.%d\n"),
01069 major,
01070 minor));
01071 }
01072 return -1;
01073 }
01074
01075 CORBA::String_var host;
01076 CORBA::UShort port = 0;
01077
01078
01079 if (cdr.read_string (host.out ()) == 0
01080 || cdr.read_ushort (port) == 0)
01081 {
01082 if (TAO_debug_level > 0)
01083 {
01084 ACE_DEBUG ((LM_DEBUG,
01085 ACE_TEXT ("TAO (%P|%t) - TAO_IIOP_Acceptor::object_key, ")
01086 ACE_TEXT ("error while decoding host/port\n")));
01087 }
01088 return -1;
01089 }
01090
01091
01092 if ((cdr >> object_key) == 0)
01093 return -1;
01094
01095
01096
01097 return 1;
01098 }
01099
01100 int
01101 TAO_IIOP_Acceptor::parse_options (const char *str)
01102 {
01103 if (str == 0)
01104 return 0;
01105
01106
01107
01108
01109
01110 const ACE_CString options (str);
01111
01112 const size_t len = options.length ();
01113
01114 static const char option_delimiter = '&';
01115
01116
01117 int argc = 1;
01118
01119 for (size_t i = 0; i < len; ++i)
01120 if (options[i] == option_delimiter)
01121 argc++;
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131 ACE_CString *argv_base = 0;
01132 ACE_NEW_RETURN (argv_base, ACE_CString[argc],-1);
01133 ACE_CString **argv = 0;
01134 ACE_NEW_RETURN (argv, ACE_CString*[argc],-1);
01135
01136 ACE_CString::size_type begin = 0;
01137 ACE_CString::size_type end = 0;
01138 int result = 0;
01139 for (int j = 0; j < argc; ++j)
01140 {
01141 if (j < argc - 1)
01142 end = options.find (option_delimiter, begin);
01143 else
01144 end = len;
01145
01146 if (end == begin)
01147 {
01148 ACE_ERROR ((LM_ERROR,
01149 ACE_TEXT ("TAO (%P|%t) - Zero length IIOP option.\n")));
01150 result = -1;
01151 break;
01152 }
01153 else if (end != options.npos)
01154 {
01155 argv_base[j] = options.substring (begin, end - begin);
01156 argv[j] = &argv_base[j];
01157 begin = end + 1;
01158 }
01159 else
01160 {
01161 break;
01162 }
01163 }
01164
01165 if (result == 0)
01166 result = this->parse_options_i (argc,argv);
01167
01168 if (argc > 0)
01169 {
01170 ACE_ERROR ((LM_ERROR,
01171 ACE_TEXT ("TAO (%P|%t) - IIOP")
01172 ACE_TEXT (" endpoint has %d unknown options:\n"),
01173 argc));
01174 for (int i = 0; i < argc; i++)
01175 ACE_ERROR ((LM_ERROR,
01176 ACE_TEXT("\t%s\n"),
01177 argv[i]->c_str()));
01178 result = -1;
01179 }
01180 delete [] argv;
01181 delete [] argv_base;
01182 return result;
01183 }
01184
01185 int
01186 TAO_IIOP_Acceptor::parse_options_i (int &argc,
01187 ACE_CString **argv)
01188 {
01189 int i = 0;
01190 while (i < argc)
01191 {
01192 ACE_CString::size_type const len = argv[i]->length ();
01193 ACE_CString::size_type const slot = argv[i]->find ('=');
01194
01195 if (slot == len - 1
01196 || slot == ACE_CString::npos)
01197 ACE_ERROR_RETURN ((LM_ERROR,
01198 ACE_TEXT ("TAO (%P|%t) - IIOP option <%s> is ")
01199 ACE_TEXT ("missing a value.\n"),
01200 ACE_TEXT_CHAR_TO_TCHAR(argv[i]->c_str ())),
01201 -1);
01202
01203 ACE_CString name = argv[i]->substring (0, slot);
01204 ACE_CString value = argv[i]->substring (slot + 1);
01205
01206 if (name.length () == 0)
01207 ACE_ERROR_RETURN ((LM_ERROR,
01208 ACE_TEXT ("TAO (%P|%t) Zero length IIOP ")
01209 ACE_TEXT ("option name.\n")),
01210 -1);
01211 if (name == "portspan")
01212 {
01213 int range = static_cast <int> (ACE_OS::atoi (value.c_str ()));
01214
01215 if (range < 1 || range > ACE_MAX_DEFAULT_PORT)
01216 ACE_ERROR_RETURN ((LM_ERROR,
01217 ACE_TEXT ("TAO (%P|%t) Invalid IIOP endpoint ")
01218 ACE_TEXT ("portspan: <%s>\n")
01219 ACE_TEXT ("Valid range 1 -- %d\n"),
01220 value.c_str (), ACE_MAX_DEFAULT_PORT),
01221 -1);
01222
01223 this->port_span_ = static_cast <u_short> (range);
01224 }
01225 else if (name == "hostname_in_ior")
01226 {
01227 this->hostname_in_ior_ = value.rep ();
01228 }
01229 else if (name == "reuse_addr")
01230 {
01231 this->reuse_addr_ = ACE_OS::atoi (value.c_str ());
01232 }
01233 else
01234 {
01235
01236 ++i;
01237 continue;
01238 }
01239
01240
01241
01242
01243 --argc;
01244 ACE_CString *temp = argv[i];
01245 for (int j = i; j <= argc-1; ++j)
01246 argv[j] = argv[j+1];
01247 argv[argc] = temp;
01248 }
01249 return 0;
01250 }
01251
01252 TAO_END_VERSIONED_NAMESPACE_DECL
01253
01254 #endif
01255
01256