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.i"
00021 #endif
00022
00023 #include "ace/os_include/os_netdb.h"
00024
00025 ACE_RCSID (Strategies,
00026 DIOP_Acceptor,
00027 "DIOP_Acceptor.cpp,v 1.28 2006/05/16 12:35:17 jwillemsen Exp")
00028
00029 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00030
00031 TAO_DIOP_Acceptor::TAO_DIOP_Acceptor (CORBA::Boolean flag)
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 lite_flag_ (flag),
00039 connection_handler_ (0)
00040 {
00041 }
00042
00043 TAO_DIOP_Acceptor::~TAO_DIOP_Acceptor (void)
00044 {
00045
00046
00047 this->close ();
00048
00049 delete [] this->addrs_;
00050
00051 for (size_t i = 0; i < this->endpoint_count_; ++i)
00052 CORBA::string_free (this->hosts_[i]);
00053
00054 delete [] this->hosts_;
00055 }
00056
00057
00058
00059
00060 int
00061 TAO_DIOP_Acceptor::create_profile (const TAO::ObjectKey & object_key,
00062 TAO_MProfile &mprofile,
00063 CORBA::Short priority)
00064 {
00065
00066 if (this->endpoint_count_ == 0)
00067 return -1;
00068
00069
00070
00071 if (priority == TAO_INVALID_PRIORITY)
00072 return this->create_new_profile (object_key,
00073 mprofile,
00074 priority);
00075 else
00076 return this->create_shared_profile (object_key,
00077 mprofile,
00078 priority);
00079 }
00080
00081 int
00082 TAO_DIOP_Acceptor::create_new_profile (const TAO::ObjectKey &object_key,
00083 TAO_MProfile &mprofile,
00084 CORBA::Short priority)
00085 {
00086
00087 int const count = mprofile.profile_count ();
00088 if ((mprofile.size () - count) < this->endpoint_count_
00089 && mprofile.grow (count + this->endpoint_count_) == -1)
00090 return -1;
00091
00092
00093 for (size_t i = 0; i < this->endpoint_count_; ++i)
00094 {
00095 TAO_DIOP_Profile *pfile = 0;
00096 ACE_NEW_RETURN (pfile,
00097 TAO_DIOP_Profile (this->hosts_[i],
00098 this->addrs_[i].get_port_number (),
00099 object_key,
00100 this->addrs_[i],
00101 this->version_,
00102 this->orb_core_),
00103 -1);
00104 pfile->endpoint ()->priority (priority);
00105
00106 if (mprofile.give_profile (pfile) == -1)
00107 {
00108 pfile->_decr_refcnt ();
00109 pfile = 0;
00110 return -1;
00111 }
00112
00113
00114
00115
00116 if (this->orb_core_->orb_params ()->std_profile_components () == 0
00117 || (this->version_.major == 1 && this->version_.minor == 0))
00118 continue;
00119
00120 pfile->tagged_components ().set_orb_type (TAO_ORB_TYPE);
00121
00122 TAO_Codeset_Manager *csm = this->orb_core_->codeset_manager();
00123 if (csm)
00124 csm->set_codeset(pfile->tagged_components());
00125 }
00126
00127 return 0;
00128 }
00129
00130 int
00131 TAO_DIOP_Acceptor::create_shared_profile (const TAO::ObjectKey &object_key,
00132 TAO_MProfile &mprofile,
00133 CORBA::Short priority)
00134 {
00135 size_t index = 0;
00136 TAO_Profile *pfile = 0;
00137 TAO_DIOP_Profile *iiop_profile = 0;
00138
00139
00140 for (TAO_PHandle i = 0; i != mprofile.profile_count (); ++i)
00141 {
00142 pfile = mprofile.get_profile (i);
00143 if (pfile->tag () == TAO_TAG_DIOP_PROFILE)
00144 {
00145 iiop_profile = dynamic_cast<TAO_DIOP_Profile *> (pfile);
00146 break;
00147 }
00148 }
00149
00150
00151
00152 if (iiop_profile == 0)
00153 {
00154 ACE_NEW_RETURN (iiop_profile,
00155 TAO_DIOP_Profile (this->hosts_[0],
00156 this->addrs_[0].get_port_number (),
00157 object_key,
00158 this->addrs_[0],
00159 this->version_,
00160 this->orb_core_),
00161 -1);
00162 iiop_profile->endpoint ()->priority (priority);
00163
00164 if (mprofile.give_profile (iiop_profile) == -1)
00165 {
00166 iiop_profile->_decr_refcnt ();
00167 iiop_profile = 0;
00168 return -1;
00169 }
00170
00171 if (this->orb_core_->orb_params ()->std_profile_components () != 0
00172 && (this->version_.major >= 1 && this->version_.minor >= 1))
00173 {
00174 iiop_profile->tagged_components ().set_orb_type (TAO_ORB_TYPE);
00175 TAO_Codeset_Manager *csm = this->orb_core_->codeset_manager();
00176 if (csm)
00177 csm->set_codeset(pfile->tagged_components());
00178 }
00179
00180 index = 1;
00181 }
00182
00183
00184 for (;
00185 index < this->endpoint_count_;
00186 ++index)
00187 {
00188 TAO_DIOP_Endpoint *endpoint = 0;
00189 ACE_NEW_RETURN (endpoint,
00190 TAO_DIOP_Endpoint (this->hosts_[index],
00191 this->addrs_[index].get_port_number (),
00192 this->addrs_[index]),
00193 -1);
00194 endpoint->priority (priority);
00195 iiop_profile->add_endpoint (endpoint);
00196 }
00197
00198 return 0;
00199 }
00200
00201 int
00202 TAO_DIOP_Acceptor::is_collocated (const TAO_Endpoint *endpoint)
00203 {
00204 const TAO_DIOP_Endpoint *endp =
00205 dynamic_cast<const TAO_DIOP_Endpoint *> (endpoint);
00206
00207
00208 if (endp == 0)
00209 return 0;
00210
00211 for (size_t i = 0; i < this->endpoint_count_; ++i)
00212 {
00213
00214
00215
00216
00217
00218
00219 if (endp->port() == this->addrs_[i].get_port_number()
00220 && ACE_OS::strcmp(endp->host(), this->hosts_[i]) == 0)
00221 return 1;
00222 }
00223
00224 return 0;
00225 }
00226
00227 int
00228 TAO_DIOP_Acceptor::close (void)
00229 {
00230 return 0;
00231 }
00232
00233 int
00234 TAO_DIOP_Acceptor::open (TAO_ORB_Core *orb_core,
00235 ACE_Reactor *reactor,
00236 int major,
00237 int minor,
00238 const char *address,
00239 const char *options)
00240 {
00241 this->orb_core_ = orb_core;
00242
00243 if (this->hosts_ != 0)
00244 {
00245
00246
00247 ACE_ERROR_RETURN ((LM_ERROR,
00248 ACE_TEXT ("TAO (%P|%t) ")
00249 ACE_TEXT ("DIOP_Acceptor::open - ")
00250 ACE_TEXT ("hostname already set\n\n")),
00251 -1);
00252 }
00253
00254 if (address == 0)
00255 return -1;
00256
00257 if (major >=0 && minor >= 0)
00258 this->version_.set_version (static_cast<CORBA::Octet> (major),
00259 static_cast<CORBA::Octet> (minor));
00260
00261 if (this->parse_options (options) == -1)
00262 return -1;
00263
00264 ACE_INET_Addr addr;
00265
00266 const char *port_separator_loc = ACE_OS::strchr (address, ':');
00267 const char *specified_hostname = 0;
00268 char tmp_host[MAXHOSTNAMELEN + 1];
00269
00270 if (port_separator_loc == address)
00271 {
00272
00273
00274
00275
00276
00277 if (this->probe_interfaces (orb_core) == -1)
00278 return -1;
00279
00280
00281 if (addr.set (address + sizeof (':')) != 0)
00282 return -1;
00283
00284
00285 if (addr.set (addr.get_port_number (),
00286 static_cast<ACE_UINT32> (INADDR_ANY),
00287 1) != 0)
00288 return -1;
00289 else
00290 return this->open_i (addr,
00291 reactor);
00292 }
00293 else if (port_separator_loc == 0)
00294 {
00295
00296
00297 if (addr.set ((unsigned short) 0, address) != 0)
00298 return -1;
00299
00300 specified_hostname = address;
00301 }
00302 else
00303 {
00304
00305 if (addr.set (address) != 0)
00306 return -1;
00307
00308
00309 size_t len = port_separator_loc - address;
00310 ACE_OS::memcpy (tmp_host, address, len);
00311 tmp_host[len] = '\0';
00312
00313 specified_hostname = tmp_host;
00314 }
00315
00316 this->endpoint_count_ = 1;
00317
00318 ACE_NEW_RETURN (this->addrs_,
00319 ACE_INET_Addr[this->endpoint_count_],
00320 -1);
00321
00322 ACE_NEW_RETURN (this->hosts_,
00323 char *[this->endpoint_count_],
00324 -1);
00325
00326 this->hosts_[0] = 0;
00327
00328 if (this->hostname (orb_core,
00329 addr,
00330 this->hosts_[0],
00331 specified_hostname) != 0)
00332 return -1;
00333
00334
00335
00336 if (this->addrs_[0].set (addr) != 0)
00337 return -1;
00338
00339 return this->open_i (addr,
00340 reactor);
00341 }
00342
00343 int
00344 TAO_DIOP_Acceptor::open_default (TAO_ORB_Core *orb_core,
00345 ACE_Reactor *reactor,
00346 int major,
00347 int minor,
00348 const char *options)
00349 {
00350 this->orb_core_ = orb_core;
00351
00352 if (this->hosts_ != 0)
00353 {
00354
00355
00356 ACE_ERROR_RETURN ((LM_ERROR,
00357 ACE_TEXT ("TAO (%P|%t) ")
00358 ACE_TEXT ("DIOP_Acceptor::open_default - ")
00359 ACE_TEXT ("hostname already set\n\n")),
00360 -1);
00361 }
00362
00363 if (major >=0 && minor >= 0)
00364 this->version_.set_version (static_cast<CORBA::Octet> (major),
00365 static_cast<CORBA::Octet> (minor));
00366
00367
00368 if (this->parse_options (options) == -1)
00369 return -1;
00370
00371
00372 if (this->probe_interfaces (orb_core) == -1)
00373 return -1;
00374
00375
00376
00377
00378 ACE_INET_Addr addr;
00379
00380 if (addr.set (static_cast<unsigned short> (0),
00381 static_cast<ACE_UINT32> (INADDR_ANY),
00382 1) != 0)
00383 return -1;
00384
00385 return this->open_i (addr,
00386 reactor);
00387 }
00388
00389 int
00390 TAO_DIOP_Acceptor::open_i (const ACE_INET_Addr& addr,
00391 ACE_Reactor *reactor)
00392 {
00393 ACE_NEW_RETURN (this->connection_handler_,
00394 TAO_DIOP_Connection_Handler (this->orb_core_,
00395 this->lite_flag_),
00396 -1);
00397
00398 this->connection_handler_->local_addr (addr);
00399 this->connection_handler_->open_server ();
00400
00401
00402 int const result =
00403 reactor->register_handler (this->connection_handler_,
00404 ACE_Event_Handler::READ_MASK);
00405 if (result == -1)
00406 return result;
00407
00408
00409 this->connection_handler_->remove_reference ();
00410
00411 ACE_INET_Addr address;
00412
00413
00414
00415 if (this->connection_handler_->dgram ().get_local_addr (address) != 0)
00416 {
00417 if (TAO_debug_level > 0)
00418 ACE_ERROR ((LM_ERROR,
00419 ACE_TEXT ("TAO (%P|%t) DIOP_Acceptor::open_i ")
00420 ACE_TEXT ("- %p"),
00421 ACE_TEXT ("cannot get local addr\n")));
00422 return -1;
00423 }
00424
00425
00426
00427
00428
00429 u_short const port = address.get_port_number ();
00430 for (size_t j = 0; j < this->endpoint_count_; ++j)
00431 this->addrs_[j].set_port_number (port, 1);
00432
00433 if (TAO_debug_level > 5)
00434 {
00435 for (size_t i = 0; i < this->endpoint_count_; ++i)
00436 {
00437 ACE_DEBUG ((LM_DEBUG,
00438 ACE_TEXT ("\nTAO (%P|%t) DIOP_Acceptor::open_i - ")
00439 ACE_TEXT ("listening on: <%s:%u>\n"),
00440 ACE_TEXT_CHAR_TO_TCHAR (this->hosts_[i]),
00441 this->addrs_[i].get_port_number ()));
00442 }
00443 }
00444
00445 return 0;
00446 }
00447
00448 int
00449 TAO_DIOP_Acceptor::hostname (TAO_ORB_Core *orb_core,
00450 ACE_INET_Addr &addr,
00451 char *&host,
00452 const char *specified_hostname)
00453 {
00454 if (orb_core->orb_params ()->use_dotted_decimal_addresses ())
00455 {
00456
00457
00458 return this->dotted_decimal_address (addr, host);
00459 }
00460 else
00461 if (specified_hostname != 0)
00462 {
00463
00464
00465 host = CORBA::string_dup (specified_hostname);
00466 }
00467 else
00468 {
00469 char tmp_host[MAXHOSTNAMELEN + 1];
00470
00471
00472 if (addr.get_host_name (tmp_host, sizeof (tmp_host)) != 0)
00473 {
00474
00475 return this->dotted_decimal_address (addr, host);
00476 }
00477 else
00478 {
00479 host = CORBA::string_dup (tmp_host);
00480 }
00481 }
00482
00483 return 0;
00484 }
00485
00486 int
00487 TAO_DIOP_Acceptor::dotted_decimal_address (ACE_INET_Addr &addr,
00488 char *&host)
00489 {
00490 const char *tmp = addr.get_host_addr ();
00491 if (tmp == 0)
00492 {
00493 if (TAO_debug_level > 0)
00494 ACE_DEBUG ((LM_DEBUG,
00495 ACE_TEXT ("\n\nTAO (%P|%t) ")
00496 ACE_TEXT ("DIOP_Acceptor::dotted_decimal_address ")
00497 ACE_TEXT ("- %p\n\n"),
00498 ACE_TEXT ("cannot determine hostname")));
00499 return -1;
00500 }
00501
00502 host = CORBA::string_dup (tmp);
00503 return 0;
00504 }
00505
00506 int
00507 TAO_DIOP_Acceptor::probe_interfaces (TAO_ORB_Core *orb_core)
00508 {
00509
00510
00511
00512
00513 ACE_INET_Addr *if_addrs = 0;
00514 size_t if_cnt = 0;
00515
00516 if (ACE::get_ip_interfaces (if_cnt,
00517 if_addrs) != 0
00518 && errno != ENOTSUP)
00519 {
00520
00521
00522
00523 return -1;
00524 }
00525
00526 if (if_cnt == 0 || if_addrs == 0)
00527 {
00528 if (TAO_debug_level > 0)
00529 {
00530 ACE_DEBUG ((LM_WARNING,
00531 ACE_TEXT ("TAO (%P|%t) Unable to probe network ")
00532 ACE_TEXT ("interfaces. Using default.")));
00533 }
00534
00535 if_cnt = 1;
00536 delete [] if_addrs;
00537 ACE_NEW_RETURN (if_addrs,
00538 ACE_INET_Addr[if_cnt],
00539 -1);
00540 }
00541
00542
00543
00544 size_t lo_cnt = 0;
00545 for (size_t j = 0; j < if_cnt; ++j)
00546 if (if_addrs[j].get_ip_address () == INADDR_LOOPBACK)
00547 lo_cnt++;
00548
00549
00550
00551 ACE_Auto_Basic_Array_Ptr<ACE_INET_Addr> safe_if_addrs (if_addrs);
00552
00553
00554
00555
00556 if (if_cnt == lo_cnt)
00557 this->endpoint_count_ = static_cast<CORBA::ULong> (if_cnt);
00558 else
00559 this->endpoint_count_ = static_cast<CORBA::ULong> (if_cnt - lo_cnt);
00560
00561 ACE_NEW_RETURN (this->addrs_,
00562 ACE_INET_Addr[this->endpoint_count_],
00563 -1);
00564
00565 ACE_NEW_RETURN (this->hosts_,
00566 char *[this->endpoint_count_],
00567 -1);
00568
00569 ACE_OS::memset (this->hosts_, 0, sizeof (char*) * this->endpoint_count_);
00570
00571
00572
00573
00574 size_t host_cnt = 0;
00575
00576 for (size_t i = 0; i < if_cnt; ++i)
00577 {
00578
00579
00580 if (if_cnt != lo_cnt &&
00581 if_addrs[i].get_ip_address() == INADDR_LOOPBACK)
00582 continue;
00583
00584 if (this->hostname (orb_core,
00585 if_addrs[i],
00586 this->hosts_[host_cnt]) != 0)
00587 return -1;
00588
00589
00590
00591 if (this->addrs_[host_cnt].set (if_addrs[i]) != 0)
00592 return -1;
00593
00594 host_cnt++;
00595 }
00596
00597 return 0;
00598 }
00599
00600 CORBA::ULong
00601 TAO_DIOP_Acceptor::endpoint_count (void)
00602 {
00603 return this->endpoint_count_;
00604 }
00605
00606 int
00607 TAO_DIOP_Acceptor::object_key (IOP::TaggedProfile &profile,
00608 TAO::ObjectKey &object_key)
00609 {
00610
00611 #if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
00612 TAO_InputCDR cdr (profile.profile_data.mb ());
00613 #else
00614 TAO_InputCDR cdr (reinterpret_cast<char*> (profile.profile_data.get_buffer ()),
00615 profile.profile_data.length ());
00616 #endif
00617
00618 CORBA::Octet major;
00619 CORBA::Octet minor = CORBA::Octet();
00620
00621
00622
00623 if (!(cdr.read_octet (major)
00624 && cdr.read_octet (minor)))
00625 {
00626 if (TAO_debug_level > 0)
00627 {
00628 ACE_DEBUG ((LM_DEBUG,
00629 ACE_TEXT ("TAO (%P|%t) DIOP_Profile::decode - v%d.%d\n"),
00630 major,
00631 minor));
00632 }
00633 return -1;
00634 }
00635
00636 CORBA::String_var host;
00637 CORBA::UShort port = 0;
00638
00639
00640 if (cdr.read_string (host.out ()) == 0
00641 || cdr.read_ushort (port) == 0)
00642 {
00643 if (TAO_debug_level > 0)
00644 {
00645 ACE_DEBUG ((LM_DEBUG,
00646 ACE_TEXT ("TAO (%P|%t) TAO_DIOP_Acceptor::object_key - ")
00647 ACE_TEXT ("error while decoding host/port")));
00648 }
00649 return -1;
00650 }
00651
00652
00653 if ((cdr >> object_key) == 0)
00654 return -1;
00655
00656
00657
00658 return 1;
00659 }
00660
00661
00662 int
00663 TAO_DIOP_Acceptor::parse_options (const char *str)
00664 {
00665 if (str == 0)
00666 return 0;
00667
00668
00669
00670
00671
00672 ACE_CString options (str);
00673
00674 size_t len = options.length ();
00675
00676 const char option_delimiter = '&';
00677
00678
00679
00680 CORBA::ULong option_count = 1;
00681
00682
00683
00684
00685 for (size_t i = 0; i < len; ++i)
00686 if (options[i] == option_delimiter)
00687 option_count++;
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697 ssize_t begin = 0;
00698 ssize_t end = -1;
00699
00700 for (CORBA::ULong j = 0; j < option_count; ++j)
00701 {
00702 begin += end + 1;
00703
00704 if (j < option_count - 1)
00705 end = options.find (option_delimiter, begin);
00706 else
00707 end = (len - begin);
00708
00709 if (end == begin)
00710 ACE_ERROR_RETURN ((LM_ERROR,
00711 ACE_TEXT ("TAO (%P|%t) Zero length DIOP option.\n")),
00712 -1);
00713 else if (end != ACE_CString::npos)
00714 {
00715 ACE_CString opt = options.substring (begin, end);
00716
00717 ssize_t slot = opt.find ("=");
00718
00719 if (slot == static_cast<ssize_t> (len - 1)
00720 || slot == ACE_CString::npos)
00721 ACE_ERROR_RETURN ((LM_ERROR,
00722 ACE_TEXT ("TAO (%P|%t) DIOP option <%s> is ")
00723 ACE_TEXT ("missing a value.\n"),
00724 ACE_TEXT_CHAR_TO_TCHAR (opt.c_str ())),
00725 -1);
00726
00727 ACE_CString name = opt.substring (0, slot);
00728 ACE_CString value = opt.substring (slot + 1);
00729
00730 if (name.length () == 0)
00731 ACE_ERROR_RETURN ((LM_ERROR,
00732 ACE_TEXT ("TAO (%P|%t) Zero length DIOP ")
00733 ACE_TEXT ("option name.\n")),
00734 -1);
00735
00736 if (name == "priority")
00737 {
00738 ACE_ERROR_RETURN ((LM_ERROR,
00739 ACE_TEXT ("TAO (%P|%t) Invalid DIOP endpoint format: ")
00740 ACE_TEXT ("endpoint priorities no longer supported. \n")),
00741 -1);
00742 }
00743 else
00744 ACE_ERROR_RETURN ((LM_ERROR,
00745 ACE_TEXT ("TAO (%P|%t) Invalid DIOP option: <%s>\n"),
00746 ACE_TEXT_CHAR_TO_TCHAR (name.c_str ())),
00747 -1);
00748 }
00749 }
00750 return 0;
00751 }
00752
00753 TAO_END_VERSIONED_NAMESPACE_DECL
00754
00755 #endif