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