00001 #include "tao/Strategies/SCIOP_Connector.h"
00002 #include "tao/Strategies/SCIOP_Profile.h"
00003
00004 #if TAO_HAS_SCIOP == 1
00005
00006 #include "tao/debug.h"
00007 #include "tao/ORB_Core.h"
00008 #include "tao/Client_Strategy_Factory.h"
00009 #include "tao/SystemException.h"
00010 #include "tao/Base_Transport_Property.h"
00011 #include "tao/Protocols_Hooks.h"
00012 #include "tao/Transport_Cache_Manager.h"
00013 #include "tao/Connect_Strategy.h"
00014 #include "tao/Thread_Lane_Resources.h"
00015 #include "tao/Transport.h"
00016 #include "tao/Wait_Strategy.h"
00017 #include "tao/Profile_Transport_Resolver.h"
00018
00019 #include "ace/OS_NS_strings.h"
00020 #include "ace/Strategies_T.h"
00021
00022
00023 ACE_RCSID (TAO,
00024 SCIOP_Connector,
00025 "$Id: SCIOP_Connector.cpp 79388 2007-08-17 16:05:00Z wilsond $")
00026
00027
00028 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00029
00030 TAO_SCIOP_Connector::TAO_SCIOP_Connector (void)
00031 : TAO_Connector (TAO_TAG_SCIOP_PROFILE),
00032 connect_strategy_ (),
00033 base_connector_ ()
00034 {
00035 }
00036
00037 TAO_SCIOP_Connector::~TAO_SCIOP_Connector (void)
00038 {
00039 }
00040
00041 int
00042 TAO_SCIOP_Connector::open (TAO_ORB_Core *orb_core)
00043 {
00044
00045
00046
00047
00048
00049 this->orb_core (orb_core);
00050
00051
00052 if (this->create_connect_strategy () == -1)
00053 return -1;
00054
00055
00056 TAO_SCIOP_CONNECT_CREATION_STRATEGY *connect_creation_strategy = 0;
00057
00058 ACE_NEW_RETURN (connect_creation_strategy,
00059 TAO_SCIOP_CONNECT_CREATION_STRATEGY
00060 (orb_core->thr_mgr (),
00061 orb_core),
00062 -1);
00063
00064
00065 TAO_SCIOP_CONNECT_CONCURRENCY_STRATEGY *concurrency_strategy = 0;
00066
00067 ACE_NEW_RETURN (concurrency_strategy,
00068 TAO_SCIOP_CONNECT_CONCURRENCY_STRATEGY (orb_core),
00069 -1);
00070
00071 return this->base_connector_.open (this->orb_core ()->reactor (),
00072 connect_creation_strategy,
00073 &this->connect_strategy_,
00074 concurrency_strategy);
00075 }
00076
00077 int
00078 TAO_SCIOP_Connector::close (void)
00079 {
00080 delete this->base_connector_.concurrency_strategy ();
00081 delete this->base_connector_.creation_strategy ();
00082 return this->base_connector_.close ();
00083 }
00084
00085 int
00086 TAO_SCIOP_Connector::set_validate_endpoint (TAO_Endpoint *endpoint)
00087 {
00088 TAO_SCIOP_Endpoint *sciop_endpoint =
00089 this->remote_endpoint (endpoint);
00090
00091 if (sciop_endpoint == 0)
00092 return -1;
00093
00094 const ACE_INET_Addr &remote_address =
00095 sciop_endpoint->object_addr ();
00096
00097
00098
00099
00100 if (remote_address.get_type () != AF_INET)
00101 {
00102 if (TAO_debug_level > 0)
00103 {
00104 ACE_DEBUG ((LM_DEBUG,
00105 ACE_TEXT ("TAO (%P|%t) SCIOP connection failed.\n")
00106 ACE_TEXT ("TAO (%P|%t) This is most likely ")
00107 ACE_TEXT ("due to a hostname lookup ")
00108 ACE_TEXT ("failure.\n")));
00109 }
00110
00111 return -1;
00112 }
00113
00114 return 0;
00115 }
00116
00117 TAO_Transport *
00118 TAO_SCIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r,
00119 TAO_Transport_Descriptor_Interface &desc,
00120 ACE_Time_Value *timeout)
00121 {
00122 TAO_Endpoint *tao_endpoint = desc.endpoint ();
00123
00124 TAO_Transport *transport = 0;
00125
00126
00127
00128
00129 while (tao_endpoint != 0)
00130 {
00131 TAO_SCIOP_Endpoint *sciop_endpoint = this->remote_endpoint (tao_endpoint);
00132
00133 if (sciop_endpoint != 0)
00134 {
00135 transport =
00136 this->make_connection_i (r, desc, timeout, sciop_endpoint);
00137 if (transport)
00138 {
00139 break;
00140 }
00141 }
00142 tao_endpoint = tao_endpoint->next();
00143 }
00144
00145 return transport;
00146 }
00147
00148
00149 TAO_Transport *
00150 TAO_SCIOP_Connector::make_connection_i (TAO::Profile_Transport_Resolver *r,
00151 TAO_Transport_Descriptor_Interface &desc,
00152 ACE_Time_Value *timeout,
00153 TAO_SCIOP_Endpoint *sciop_endpoint)
00154 {
00155 const ACE_INET_Addr &remote_address =
00156 sciop_endpoint->object_addr ();
00157
00158 if (TAO_debug_level > 2)
00159 ACE_DEBUG ((LM_DEBUG,
00160 "TAO (%P|%t) - SCIOP_Connector::make_connection_i, "
00161 "to <%s:%d> which should %s\n",
00162 ACE_TEXT_CHAR_TO_TCHAR(sciop_endpoint->host()),
00163 sciop_endpoint->port(),
00164 r->blocked_connect () ? ACE_TEXT("block") : ACE_TEXT("nonblock")));
00165
00166
00167 ACE_Synch_Options synch_options;
00168
00169 this->active_connect_strategy_->synch_options (timeout, synch_options);
00170
00171
00172
00173
00174
00175 TAO_SCIOP_Connection_Handler *svc_handler = 0;
00176
00177
00178 ACE_Multihomed_INET_Addr multihomed;
00179 if (multihomed.set(remote_address.get_port_number(),
00180 remote_address.get_ip_address()))
00181 return 0;
00182
00183 ACE_Multihomed_INET_Addr local_address;
00184
00185 bool pn =
00186 sciop_endpoint->is_preferred_network ();
00187
00188 if (pn)
00189 local_address.set ((u_short) 0,
00190 sciop_endpoint->preferred_network ());
00191
00192 int result =
00193 this->base_connector_.connect (svc_handler,
00194 multihomed,
00195 synch_options,
00196 local_address);
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 ACE_Event_Handler_var svc_handler_auto_ptr (svc_handler);
00217
00218 TAO_Transport *transport = svc_handler->transport ();
00219
00220 if (result == -1)
00221 {
00222
00223 if (errno == EWOULDBLOCK)
00224 {
00225
00226
00227
00228 if (!this->wait_for_connection_completion (r,
00229 transport,
00230 timeout))
00231 {
00232 if (TAO_debug_level > 2)
00233 ACE_ERROR ((LM_ERROR, "TAO (%P|%t) - SCIOP_Connector::"
00234 "make_connection_i, "
00235 "wait for completion failed\n"));
00236 }
00237 }
00238 else
00239 {
00240
00241 transport = 0;
00242 }
00243 }
00244
00245
00246 if (transport == 0)
00247 {
00248
00249 if (TAO_debug_level)
00250 {
00251 ACE_ERROR ((LM_ERROR,
00252 "TAO (%P|%t) - SCIOP_Connector::make_connection_i, "
00253 "connection to <%s:%d> failed (%p)\n",
00254 sciop_endpoint->host (), sciop_endpoint->port (),
00255 "errno"));
00256 }
00257
00258 return 0;
00259 }
00260
00261 if (svc_handler->keep_waiting ())
00262 {
00263 svc_handler->connection_pending ();
00264 }
00265
00266 if (svc_handler->error_detected ())
00267 {
00268 svc_handler->cancel_pending_connection ();
00269 return 0;
00270 }
00271
00272
00273
00274 if (TAO_debug_level > 2)
00275 ACE_DEBUG ((LM_DEBUG,
00276 "TAO (%P|%t) - SCIOP_Connector::make_connection_i, "
00277 "new %s connection to <%s:%d> on Transport[%d]\n",
00278 transport->is_connected() ? "connected" : "not connected",
00279 sciop_endpoint->host (), sciop_endpoint->port (),
00280 svc_handler->peer ().get_handle ()));
00281
00282
00283 int retval =
00284 this->orb_core ()->lane_resources ().transport_cache ().cache_transport (&desc,
00285 transport);
00286
00287
00288 if (retval != 0)
00289 {
00290
00291 svc_handler->close ();
00292
00293 if (TAO_debug_level > 0)
00294 {
00295 ACE_ERROR ((LM_ERROR,
00296 "TAO (%P|%t) - SCIOP_Connector::make_connection_i, "
00297 "could not add the new connection to cache\n"));
00298 }
00299
00300 return 0;
00301 }
00302
00303 if (svc_handler->error_detected ())
00304 {
00305 svc_handler->cancel_pending_connection ();
00306 transport->purge_entry();
00307 return 0;
00308 }
00309
00310 if (transport->is_connected () &&
00311 transport->wait_strategy ()->register_handler () != 0)
00312 {
00313
00314
00315
00316
00317 (void) transport->purge_entry ();
00318
00319
00320 (void) transport->close_connection ();
00321
00322 if (TAO_debug_level > 0)
00323 ACE_ERROR ((LM_ERROR,
00324 "TAO (%P|%t) - SCIOP_Connector [%d]::make_connection_i, "
00325 "could not register the transport "
00326 "in the reactor.\n",
00327 transport->id ()));
00328
00329 return 0;
00330 }
00331
00332 return transport;
00333 }
00334
00335 TAO_Profile *
00336 TAO_SCIOP_Connector::create_profile (TAO_InputCDR& cdr)
00337 {
00338 TAO_Profile *pfile = 0;
00339 ACE_NEW_RETURN (pfile,
00340 TAO_SCIOP_Profile (this->orb_core ()),
00341 0);
00342
00343 int const r = pfile->decode (cdr);
00344 if (r == -1)
00345 {
00346 pfile->_decr_refcnt ();
00347 pfile = 0;
00348 }
00349
00350 return pfile;
00351 }
00352
00353 TAO_Profile *
00354 TAO_SCIOP_Connector::make_profile (void)
00355 {
00356
00357
00358
00359
00360
00361 TAO_Profile *profile = 0;
00362 ACE_NEW_THROW_EX (profile,
00363 TAO_SCIOP_Profile (this->orb_core ()),
00364 CORBA::NO_MEMORY (
00365 CORBA::SystemException::_tao_minor_code (
00366 TAO::VMCID,
00367 ENOMEM),
00368 CORBA::COMPLETED_NO));
00369
00370 return profile;
00371 }
00372
00373 int
00374 TAO_SCIOP_Connector::check_prefix (const char *endpoint)
00375 {
00376
00377 if (!endpoint || !*endpoint)
00378 return -1;
00379
00380 const char *protocol[] = { "sciop", "scioploc" };
00381
00382 size_t slot = ACE_OS::strchr (endpoint, ':') - endpoint;
00383
00384 size_t len0 = ACE_OS::strlen (protocol[0]);
00385 size_t len1 = ACE_OS::strlen (protocol[1]);
00386
00387
00388
00389 if (slot == len0
00390 && ACE_OS::strncasecmp (endpoint, protocol[0], len0) == 0)
00391 return 0;
00392 else if (slot == len1
00393 && ACE_OS::strncasecmp (endpoint, protocol[1], len1) == 0)
00394 return 0;
00395
00396 return -1;
00397
00398
00399 }
00400
00401 char
00402 TAO_SCIOP_Connector::object_key_delimiter (void) const
00403 {
00404 return TAO_SCIOP_Profile::object_key_delimiter_;
00405 }
00406
00407 TAO_SCIOP_Endpoint *
00408 TAO_SCIOP_Connector::remote_endpoint (TAO_Endpoint *endpoint)
00409 {
00410 if (endpoint->tag () != TAO_TAG_SCIOP_PROFILE)
00411 return 0;
00412
00413 TAO_SCIOP_Endpoint *sciop_endpoint =
00414 dynamic_cast<TAO_SCIOP_Endpoint *> (endpoint );
00415 if (sciop_endpoint == 0)
00416 return 0;
00417
00418 return sciop_endpoint;
00419 }
00420
00421 int
00422 TAO_SCIOP_Connector::cancel_svc_handler (
00423 TAO_Connection_Handler * svc_handler)
00424 {
00425 TAO_SCIOP_Connection_Handler* handler=
00426 dynamic_cast<TAO_SCIOP_Connection_Handler*>(svc_handler);
00427
00428 if (handler)
00429
00430 return this->base_connector_.cancel (handler);
00431
00432 return -1;
00433 }
00434
00435 TAO_END_VERSIONED_NAMESPACE_DECL
00436
00437 #endif