00001
00002
00003
00004
00005 #include "orbsvcs/PortableGroup/UIPMC_Profile.h"
00006 #include "orbsvcs/PortableGroup/UIPMC_Acceptor.h"
00007
00008 #include "tao/MProfile.h"
00009 #include "tao/ORB_Core.h"
00010 #include "tao/debug.h"
00011 #include "tao/Protocols_Hooks.h"
00012 #include "tao/ORB_Constants.h"
00013
00014 #include "ace/Auto_Ptr.h"
00015 #include "ace/os_include/os_netdb.h"
00016
00017 #if !defined(__ACE_INLINE__)
00018 #include "orbsvcs/PortableGroup/UIPMC_Acceptor.inl"
00019 #endif
00020
00021 ACE_RCSID (PortableGroup,
00022 UIPMC_Acceptor,
00023 "$Id: UIPMC_Acceptor.cpp 79015 2007-07-24 15:03:04Z vridosh $")
00024
00025 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00026
00027 TAO_UIPMC_Acceptor::TAO_UIPMC_Acceptor (void)
00028 : TAO_Acceptor (IOP::TAG_UIPMC),
00029 addrs_ (0),
00030 hosts_ (0),
00031 endpoint_count_ (0),
00032 version_ (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR),
00033 orb_core_ (0),
00034 connection_handler_ (0)
00035 {
00036 }
00037
00038 TAO_UIPMC_Acceptor::~TAO_UIPMC_Acceptor (void)
00039 {
00040
00041
00042 this->close ();
00043
00044 delete [] this->addrs_;
00045
00046 for (size_t i = 0; i < this->endpoint_count_; ++i)
00047 CORBA::string_free (this->hosts_[i]);
00048
00049 delete [] this->hosts_;
00050 }
00051
00052 int
00053 TAO_UIPMC_Acceptor::create_profile (const TAO::ObjectKey &,
00054 TAO_MProfile &,
00055 CORBA::Short)
00056 {
00057
00058
00059
00060
00061
00062
00063
00064 return 0;
00065 }
00066
00067 int
00068 TAO_UIPMC_Acceptor::is_collocated (const TAO_Endpoint *)
00069 {
00070
00071
00072
00073
00074
00075 return 0;
00076 }
00077
00078 int
00079 TAO_UIPMC_Acceptor::close (void)
00080 {
00081 return 0;
00082 }
00083
00084 int
00085 TAO_UIPMC_Acceptor::open (TAO_ORB_Core *orb_core,
00086 ACE_Reactor *reactor,
00087 int major,
00088 int minor,
00089 const char *address,
00090 const char *options)
00091 {
00092 this->orb_core_ = orb_core;
00093
00094 if (this->hosts_ != 0)
00095 {
00096
00097
00098 ACE_ERROR_RETURN ((LM_ERROR,
00099 ACE_TEXT ("TAO (%P|%t) ")
00100 ACE_TEXT ("UIPMC_Acceptor::open - ")
00101 ACE_TEXT ("hostname already set\n\n")),
00102 -1);
00103 }
00104
00105 if (address == 0)
00106 return -1;
00107
00108 if (major >= 0 && minor >= 0)
00109 this->version_.set_version (static_cast<CORBA::Octet> (major),
00110 static_cast<CORBA::Octet> (minor));
00111
00112 if (this->parse_options (options) == -1)
00113 return -1;
00114
00115 ACE_INET_Addr addr;
00116
00117 const char *port_separator_loc = ACE_OS::strchr (address, ':');
00118 const char *specified_hostname = 0;
00119 char tmp_host[MAXHOSTNAMELEN + 1];
00120
00121 #if defined (ACE_HAS_IPV6)
00122
00123
00124 if ((this->version_.major > TAO_MIN_IPV6_IIOP_MAJOR ||
00125 this->version_.minor >= TAO_MIN_IPV6_IIOP_MINOR) &&
00126 address[0] == '[')
00127 {
00128
00129
00130 const char *cp_pos = ACE_OS::strchr(address, ']');
00131 if (cp_pos == 0)
00132 {
00133
00134 ACE_ERROR_RETURN ((LM_ERROR,
00135 ACE_TEXT ("TAO (%P|%t) - ")
00136 ACE_TEXT ("UIPMC_Acceptor::open, ")
00137 ACE_TEXT ("Invalid IPv6 decimal address specified\n\n")),
00138 -1);
00139 }
00140 else
00141 {
00142 if (cp_pos[1] == ':')
00143 port_separator_loc = cp_pos + 1;
00144 else
00145 port_separator_loc = 0;
00146
00147 const size_t len = cp_pos - (address + 1);
00148 ACE_OS::memcpy (tmp_host, address + 1, len);
00149 tmp_host[len] = '\0';
00150 }
00151 }
00152 else
00153 {
00154 #endif
00155
00156 size_t len = port_separator_loc - address;
00157 ACE_OS::memcpy (tmp_host, address, len);
00158 tmp_host[len] = '\0';
00159 #if defined (ACE_HAS_IPV6)
00160 }
00161 #endif
00162
00163
00164 if (port_separator_loc == 0)
00165 {
00166 ACE_ERROR_RETURN ((LM_ERROR,
00167 ACE_TEXT ("TAO (%P|%t) - ")
00168 ACE_TEXT ("UIPMC_Acceptor::open, ")
00169 ACE_TEXT ("port is not specified\n\n")),
00170 -1);
00171 }
00172
00173 if (addr.set (address) != 0)
00174 return -1;
00175
00176 specified_hostname = tmp_host;
00177
00178 #if defined (ACE_HAS_IPV6)
00179
00180 if (this->orb_core_->orb_params ()->connect_ipv6_only () &&
00181 (addr.get_type () != AF_INET6 ||
00182 addr.is_ipv4_mapped_ipv6 ()))
00183 {
00184 ACE_ERROR_RETURN ((LM_ERROR,
00185 ACE_TEXT ("TAO (%P|%t) - ")
00186 ACE_TEXT ("UIPMC_Acceptor::open, ")
00187 ACE_TEXT ("non-IPv6 endpoints not allowed when ")
00188 ACE_TEXT ("connect_ipv6_only is set\n\n")),
00189 -1);
00190 }
00191 #endif
00192
00193 this->endpoint_count_ = 1;
00194
00195 ACE_NEW_RETURN (this->addrs_,
00196 ACE_INET_Addr[this->endpoint_count_],
00197 -1);
00198
00199 ACE_NEW_RETURN (this->hosts_,
00200 char *[this->endpoint_count_],
00201 -1);
00202
00203 this->hosts_[0] = 0;
00204
00205 if (this->hostname (orb_core,
00206 addr,
00207 this->hosts_[0],
00208 specified_hostname) != 0)
00209 return -1;
00210
00211
00212
00213 if (this->addrs_[0].set (addr) != 0)
00214 return -1;
00215
00216 return this->open_i (addr,
00217 reactor);
00218 }
00219
00220 int
00221 TAO_UIPMC_Acceptor::open_default (TAO_ORB_Core *,
00222 ACE_Reactor *,
00223 int,
00224 int,
00225 const char *)
00226 {
00227
00228
00229
00230 return -1;
00231 }
00232
00233 int
00234 TAO_UIPMC_Acceptor::open_i (const ACE_INET_Addr& addr,
00235 ACE_Reactor *reactor)
00236 {
00237 ACE_NEW_RETURN (this->connection_handler_,
00238 TAO_UIPMC_Mcast_Connection_Handler (this->orb_core_),
00239 -1);
00240
00241 this->connection_handler_->local_addr (addr);
00242 this->connection_handler_->open (0);
00243
00244 int result =
00245 reactor->register_handler (this->connection_handler_,
00246 ACE_Event_Handler::READ_MASK);
00247 if (result == -1)
00248 {
00249
00250 this->connection_handler_->close ();
00251 return result;
00252 }
00253
00254
00255 this->connection_handler_->remove_reference ();
00256
00257
00258
00259
00260
00261 u_short port = addr.get_port_number ();
00262 for (size_t j = 0; j < this->endpoint_count_; ++j)
00263 this->addrs_[j].set_port_number (port, 1);
00264
00265 if (TAO_debug_level > 5)
00266 {
00267 for (size_t i = 0; i < this->endpoint_count_; ++i)
00268 {
00269 ACE_DEBUG ((LM_DEBUG,
00270 ACE_TEXT ("TAO (%P|%t) - UIPMC_Acceptor::open_i ")
00271 ACE_TEXT ("listening on: <%s:%u>\n"),
00272 this->hosts_[i],
00273 this->addrs_[i].get_port_number ()));
00274 }
00275 }
00276
00277 return 0;
00278 }
00279
00280 int
00281 TAO_UIPMC_Acceptor::hostname (TAO_ORB_Core *,
00282 ACE_INET_Addr &addr,
00283 char *&host,
00284 const char *)
00285 {
00286
00287 return this->dotted_decimal_address (addr, host);
00288 }
00289
00290 int
00291 TAO_UIPMC_Acceptor::dotted_decimal_address (ACE_INET_Addr &addr,
00292 char *&host)
00293 {
00294 const char *tmp = addr.get_host_addr ();
00295 if (tmp == 0)
00296 {
00297 if (TAO_debug_level > 0)
00298 ACE_DEBUG ((LM_DEBUG,
00299 ACE_TEXT ("\n\nTAO (%P|%t) ")
00300 ACE_TEXT ("UIPMC_Acceptor::dotted_decimal_address ")
00301 ACE_TEXT ("- %p\n\n"),
00302 ACE_TEXT ("cannot determine hostname")));
00303 return -1;
00304 }
00305
00306 host = CORBA::string_dup (tmp);
00307 return 0;
00308 }
00309
00310 CORBA::ULong
00311 TAO_UIPMC_Acceptor::endpoint_count (void)
00312 {
00313 return this->endpoint_count_;
00314 }
00315
00316 int
00317 TAO_UIPMC_Acceptor::object_key (IOP::TaggedProfile &,
00318 TAO::ObjectKey &)
00319 {
00320
00321 return 1;
00322 }
00323
00324 int
00325 TAO_UIPMC_Acceptor::parse_options (const char *str)
00326 {
00327 if (str == 0)
00328 return 0;
00329
00330
00331
00332
00333
00334 ACE_CString options (str);
00335
00336 size_t len = options.length ();
00337
00338 const char option_delimiter = '&';
00339
00340
00341 CORBA::ULong option_count = 1;
00342
00343
00344
00345 for (size_t i = 0; i < len; ++i)
00346 if (options[i] == option_delimiter)
00347 ++option_count;
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 ACE_CString::size_type begin = 0;
00358 ACE_CString::size_type end = 0;
00359
00360 for (CORBA::ULong j = 0; j < option_count;)
00361 {
00362 if (j < option_count - 1)
00363 end = options.find (option_delimiter, begin);
00364 else
00365 end = len;
00366
00367 ++j;
00368
00369 if (end == begin)
00370 ACE_ERROR_RETURN ((LM_ERROR,
00371 ACE_TEXT ("TAO (%P|%t) Zero length UIPMC option.\n")),
00372 -1);
00373 else if (end != ACE_CString::npos)
00374 {
00375 ACE_CString opt = options.substring (begin, end);
00376
00377 ACE_CString::size_type const slot = opt.find ("=");
00378
00379 if (slot == len - 1
00380 || slot == ACE_CString::npos)
00381 ACE_ERROR_RETURN ((LM_ERROR,
00382 ACE_TEXT ("TAO (%P|%t) UIPMC option <%s> is ")
00383 ACE_TEXT ("missing a value.\n"),
00384 opt.c_str ()),
00385 -1);
00386
00387 ACE_CString name = opt.substring (0, slot);
00388 ACE_CString value = opt.substring (slot + 1);
00389
00390 begin = end + 1;
00391
00392 if (name.length () == 0)
00393 ACE_ERROR_RETURN ((LM_ERROR,
00394 ACE_TEXT ("TAO (%P|%t) Zero length UIPMC ")
00395 ACE_TEXT ("option name.\n")),
00396 -1);
00397
00398 if (name == "priority")
00399 {
00400 ACE_ERROR_RETURN ((LM_ERROR,
00401 ACE_TEXT ("TAO (%P|%t) Invalid UIPMC endpoint format: ")
00402 ACE_TEXT ("endpoint priorities no longer supported. \n"),
00403 value.c_str ()),
00404 -1);
00405 }
00406 else
00407 ACE_ERROR_RETURN ((LM_ERROR,
00408 ACE_TEXT ("TAO (%P|%t) Invalid UIPMC option: <%s>\n"),
00409 name.c_str ()),
00410 -1);
00411 }
00412 else
00413 break;
00414 }
00415 return 0;
00416 }
00417
00418 TAO_END_VERSIONED_NAMESPACE_DECL