00001 #include "orbsvcs/SSLIOP/SSLIOP_Connection_Handler.h"
00002 #include "orbsvcs/SSLIOP/SSLIOP_Endpoint.h"
00003 #include "orbsvcs/SSLIOP/SSLIOP_Util.h"
00004
00005 #include "tao/debug.h"
00006 #include "tao/Base_Transport_Property.h"
00007 #include "tao/ORB_Core.h"
00008 #include "tao/IIOP_Endpoint.h"
00009 #include "tao/IIOP_Connection_Handler.h"
00010 #include "tao/Transport_Cache_Manager.h"
00011 #include "tao/Thread_Lane_Resources.h"
00012 #include "tao/Wait_Strategy.h"
00013 #include "tao/Protocols_Hooks.h"
00014 #include "ace/os_include/netinet/os_tcp.h"
00015 #include "ace/os_include/os_netdb.h"
00016
00017 #if !defined (__ACE_INLINE__)
00018 # include "orbsvcs/SSLIOP/SSLIOP_Connection_Handler.inl"
00019 #endif
00020
00021 ACE_RCSID (SSLIOP,
00022 SSLIOP_Connection_Handler,
00023 "$Id: SSLIOP_Connection_Handler.cpp 80431 2008-01-15 19:06:41Z johnnyw $")
00024
00025
00026
00027 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00028
00029 TAO::SSLIOP::Connection_Handler::Connection_Handler (
00030 ACE_Thread_Manager *t)
00031 : SVC_HANDLER (t, 0 , 0),
00032 TAO_Connection_Handler (0),
00033 current_ ()
00034 {
00035
00036
00037
00038
00039
00040 ACE_ASSERT (0);
00041 }
00042
00043 TAO::SSLIOP::Connection_Handler::Connection_Handler (TAO_ORB_Core *orb_core)
00044 : SVC_HANDLER (orb_core->thr_mgr (), 0, 0),
00045 TAO_Connection_Handler (orb_core),
00046 current_ ()
00047 {
00048 this->current_ = TAO::SSLIOP::Util::current (orb_core);
00049
00050 TAO::SSLIOP::Transport* specific_transport = 0;
00051 ACE_NEW (specific_transport,
00052 TAO::SSLIOP::Transport (this, orb_core));
00053
00054
00055 this->transport (specific_transport);
00056 }
00057
00058 TAO::SSLIOP::Connection_Handler::~Connection_Handler (void)
00059 {
00060 delete this->transport ();
00061 int const result =
00062 this->release_os_resources ();
00063
00064 if (result == -1 && TAO_debug_level)
00065 {
00066 ACE_ERROR ((LM_ERROR,
00067 ACE_TEXT("TAO (%P|%t) - SSLIOP_Connection_Handler::")
00068 ACE_TEXT("~SSLIOP_Connection_Handler, ")
00069 ACE_TEXT("release_os_resources() failed %m\n")));
00070 }
00071 }
00072
00073 int
00074 TAO::SSLIOP::Connection_Handler::open_handler (void *v)
00075 {
00076 return this->open (v);
00077 }
00078
00079 int
00080 TAO::SSLIOP::Connection_Handler::open (void *)
00081 {
00082 if (this->shared_open() == -1)
00083 return -1;
00084
00085 TAO_IIOP_Protocol_Properties protocol_properties;
00086
00087
00088 protocol_properties.send_buffer_size_ =
00089 this->orb_core ()->orb_params ()->sock_sndbuf_size ();
00090 protocol_properties.recv_buffer_size_ =
00091 this->orb_core ()->orb_params ()->sock_rcvbuf_size ();
00092 protocol_properties.no_delay_ =
00093 this->orb_core ()->orb_params ()->nodelay ();
00094
00095 TAO_Protocols_Hooks *tph = this->orb_core ()->get_protocols_hooks ();
00096
00097 if (tph != 0)
00098 {
00099 try
00100 {
00101 if (this->transport ()->opened_as () == TAO::TAO_CLIENT_ROLE)
00102 {
00103 tph->client_protocol_properties_at_orb_level (protocol_properties);
00104 }
00105 else
00106 {
00107 tph->server_protocol_properties_at_orb_level (protocol_properties);
00108 }
00109 }
00110 catch (const CORBA::Exception&)
00111 {
00112 return -1;
00113 }
00114 }
00115
00116 if (this->set_socket_option (this->peer (),
00117 protocol_properties.send_buffer_size_,
00118 protocol_properties.recv_buffer_size_) == -1)
00119 return -1;
00120
00121 #if !defined (ACE_LACKS_TCP_NODELAY)
00122 if (this->peer ().set_option (ACE_IPPROTO_TCP,
00123 TCP_NODELAY,
00124 (void *) &protocol_properties.no_delay_,
00125 sizeof (protocol_properties.no_delay_)) == -1)
00126 return -1;
00127 #endif
00128
00129 if (this->transport ()->wait_strategy ()->non_blocking ())
00130 {
00131 if (this->peer ().enable (ACE_NONBLOCK) == -1)
00132 return -1;
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 (void) ::SSL_set_mode (this->peer ().ssl (),
00155 SSL_MODE_ENABLE_PARTIAL_WRITE);
00156 (void) ::SSL_set_mode (this->peer ().ssl (),
00157 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
00158 }
00159
00160
00161
00162 ACE_INET_Addr remote_addr;
00163 if (this->peer ().get_remote_addr (remote_addr) == -1)
00164 return -1;
00165
00166 ACE_INET_Addr local_addr;
00167 if (this->peer ().get_local_addr (local_addr) == -1)
00168 return -1;
00169
00170 if (local_addr == remote_addr)
00171 {
00172 if (TAO_debug_level > 0)
00173 {
00174 char remote_as_string[MAXHOSTNAMELEN + 16];
00175 char local_as_string[MAXHOSTNAMELEN + 16];
00176
00177 (void) remote_addr.addr_to_string (remote_as_string,
00178 sizeof (remote_as_string));
00179 (void) local_addr.addr_to_string (local_as_string,
00180 sizeof (local_as_string));
00181 ACE_ERROR ((LM_ERROR,
00182 "TAO(%P|%t) - TAO::SSLIOP::Connection_Handler::open, "
00183 "Holy Cow! The remote addr and "
00184 "local addr are identical (%s == %s)\n",
00185 remote_as_string, local_as_string));
00186 }
00187
00188 return -1;
00189 }
00190
00191 if (TAO_debug_level > 0)
00192 {
00193 char client[MAXHOSTNAMELEN + 16];
00194
00195
00196 if (remote_addr.addr_to_string (client,
00197 sizeof (client)) == -1)
00198 {
00199 ACE_OS::strcpy (client, "*unable to obtain*");
00200 }
00201
00202 ACE_DEBUG ((LM_DEBUG,
00203 ACE_TEXT ("TAO (%P|%t) SSLIOP connection from ")
00204 ACE_TEXT ("client <%s> on [%d]\n"),
00205 client,
00206 this->peer ().get_handle ()));
00207
00208
00209 if (local_addr.addr_to_string (client,
00210 sizeof (client)) == -1)
00211 {
00212 ACE_OS::strcpy (client, "*unable to obtain*");
00213 }
00214
00215 ACE_DEBUG ((LM_DEBUG,
00216 ACE_TEXT ("TAO (%P|%t) SSLIOP connection accepted from ")
00217 ACE_TEXT ("server <%s> on [%d]\n"),
00218 client,
00219 this->get_handle ()));
00220 }
00221
00222
00223
00224
00225 if (!this->transport ()->post_open ((size_t) this->get_handle ()))
00226 return -1;
00227
00228
00229 this->state_changed (TAO_LF_Event::LFS_SUCCESS,
00230 this->orb_core ()->leader_follower ());
00231
00232 return 0;
00233 }
00234
00235 int
00236 TAO::SSLIOP::Connection_Handler::resume_handler (void)
00237 {
00238 return ACE_Event_Handler::ACE_APPLICATION_RESUMES_HANDLER;
00239 }
00240
00241 int
00242 TAO::SSLIOP::Connection_Handler::close_connection (void)
00243 {
00244 return this->close_connection_eh (this);
00245 }
00246
00247 int
00248 TAO::SSLIOP::Connection_Handler::handle_input (ACE_HANDLE h)
00249 {
00250 return this->handle_input_eh (h, this);
00251 }
00252
00253 int
00254 TAO::SSLIOP::Connection_Handler::handle_output (ACE_HANDLE handle)
00255 {
00256 int const result = this->handle_output_eh (handle, this);
00257
00258 if (result == -1)
00259 {
00260 this->close_connection ();
00261 return 0;
00262 }
00263
00264 return result;
00265 }
00266
00267 int
00268 TAO::SSLIOP::Connection_Handler::handle_timeout (const ACE_Time_Value &,
00269 const void *)
00270 {
00271
00272
00273
00274
00275
00276
00277 TAO_Auto_Reference<TAO::SSLIOP::Connection_Handler> safeguard (*this);
00278
00279
00280
00281
00282
00283
00284
00285 int const ret = this->close ();
00286 this->reset_state (TAO_LF_Event::LFS_TIMEOUT);
00287 return ret;
00288 }
00289
00290 int
00291 TAO::SSLIOP::Connection_Handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask)
00292 {
00293 ACE_ASSERT (0);
00294 return 0;
00295 }
00296
00297 int
00298 TAO::SSLIOP::Connection_Handler::close (u_long)
00299 {
00300 return this->close_handler ();
00301 }
00302
00303 int
00304 TAO::SSLIOP::Connection_Handler::release_os_resources (void)
00305 {
00306 return this->peer().close ();
00307 }
00308
00309 void
00310 TAO::SSLIOP::Connection_Handler::pos_io_hook (int & return_value)
00311 {
00312 if (return_value == 0 && ::SSL_pending (this->peer ().ssl ()))
00313 return_value = 1;
00314 }
00315
00316 int
00317 TAO::SSLIOP::Connection_Handler::add_transport_to_cache (void)
00318 {
00319 ACE_INET_Addr addr;
00320
00321
00322
00323
00324
00325 if (this->peer ().get_remote_addr (addr) == -1)
00326 return -1;
00327
00328
00329 TAO_IIOP_Endpoint tmpoint (
00330 addr,
00331 this->orb_core()->orb_params()->use_dotted_decimal_addresses());
00332
00333
00334
00335
00336 const ::SSLIOP::SSL ssl =
00337 {
00338 0,
00339 0,
00340 addr.get_port_number ()
00341 };
00342
00343 TAO_SSLIOP_Endpoint endpoint (&ssl, &tmpoint);
00344
00345
00346 TAO_Base_Transport_Property prop (&endpoint);
00347
00348 TAO::Transport_Cache_Manager &cache =
00349 this->orb_core ()->lane_resources ().transport_cache ();
00350
00351
00352 return cache.cache_idle_transport (&prop, this->transport ());
00353 }
00354
00355 int
00356 TAO::SSLIOP::Connection_Handler::process_listen_point_list (
00357 IIOP::ListenPointList &listen_list)
00358 {
00359
00360 CORBA::ULong const len = listen_list.length ();
00361
00362 for (CORBA::ULong i = 0; i < len; ++i)
00363 {
00364 IIOP::ListenPoint listen_point = listen_list[i];
00365 ACE_INET_Addr addr (listen_point.port,
00366 listen_point.host.in ());
00367
00368
00369 if (TAO_debug_level > 0)
00370 {
00371 ACE_DEBUG ((LM_DEBUG,
00372 "(%P|%t) Listening port [%d] on [%s]\n",
00373 listen_point.port,
00374 listen_point.host.in ()));
00375 }
00376
00377
00378
00379
00380
00381
00382
00383
00384 TAO_IIOP_Endpoint tmpoint (listen_point.host.in (),
00385 listen_point.port,
00386 addr);
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397 TAO_SSLIOP_Synthetic_Endpoint endpoint (&tmpoint);
00398
00399
00400 TAO_Base_Transport_Property prop (&endpoint);
00401
00402
00403 prop.set_bidir_flag (1);
00404
00405
00406
00407 if (this->transport ()->recache_transport (&prop) == -1)
00408 return -1;
00409
00410
00411 this->transport ()->make_idle ();
00412 }
00413
00414 return 0;
00415 }
00416
00417 int
00418 TAO::SSLIOP::Connection_Handler::setup_ssl_state (
00419 TAO::SSLIOP::Current_Impl *&previous_current_impl,
00420 TAO::SSLIOP::Current_Impl *new_current_impl,
00421 bool &setup_done)
00422 {
00423
00424
00425 new_current_impl->ssl (this->peer ().ssl ());
00426
00427
00428 this->current_->setup (previous_current_impl,
00429 new_current_impl,
00430 setup_done);
00431
00432 return 0;
00433 }
00434
00435 void
00436 TAO::SSLIOP::Connection_Handler::teardown_ssl_state (
00437 TAO::SSLIOP::Current_Impl *previous_current_impl,
00438 bool &setup_done)
00439 {
00440 this->current_->teardown (previous_current_impl, setup_done);
00441 }
00442
00443 TAO_END_VERSIONED_NAMESPACE_DECL