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 79267 2007-08-08 15:51:45Z mesnier_p $")
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 (
00104 protocol_properties);
00105 }
00106 else
00107 {
00108 tph->server_protocol_properties_at_orb_level (
00109 protocol_properties);
00110 }
00111 }
00112 catch (const CORBA::Exception&)
00113 {
00114 return -1;
00115 }
00116 }
00117
00118 if (this->set_socket_option (this->peer (),
00119 protocol_properties.send_buffer_size_,
00120 protocol_properties.recv_buffer_size_) == -1)
00121 return -1;
00122
00123 #if !defined (ACE_LACKS_TCP_NODELAY)
00124 if (this->peer ().set_option (ACE_IPPROTO_TCP,
00125 TCP_NODELAY,
00126 (void *) &protocol_properties.no_delay_,
00127 sizeof (protocol_properties.no_delay_)) == -1)
00128 return -1;
00129 #endif
00130
00131 if (this->transport ()->wait_strategy ()->non_blocking ())
00132 {
00133 if (this->peer ().enable (ACE_NONBLOCK) == -1)
00134 return -1;
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 (void) ::SSL_set_mode (this->peer ().ssl (),
00157 SSL_MODE_ENABLE_PARTIAL_WRITE);
00158 (void) ::SSL_set_mode (this->peer ().ssl (),
00159 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
00160 }
00161
00162
00163
00164 ACE_INET_Addr remote_addr;
00165 if (this->peer ().get_remote_addr (remote_addr) == -1)
00166 return -1;
00167
00168 ACE_INET_Addr local_addr;
00169 if (this->peer ().get_local_addr (local_addr) == -1)
00170 return -1;
00171
00172 if (local_addr == remote_addr)
00173 {
00174 if (TAO_debug_level > 0)
00175 {
00176 char remote_as_string[MAXHOSTNAMELEN + 16];
00177 char local_as_string[MAXHOSTNAMELEN + 16];
00178
00179 (void) remote_addr.addr_to_string (remote_as_string,
00180 sizeof (remote_as_string));
00181 (void) local_addr.addr_to_string (local_as_string,
00182 sizeof (local_as_string));
00183 ACE_ERROR ((LM_ERROR,
00184 "TAO(%P|%t) - TAO::SSLIOP::Connection_Handler::open, "
00185 "Holy Cow! The remote addr and "
00186 "local addr are identical (%s == %s)\n",
00187 remote_as_string, local_as_string));
00188 }
00189
00190 return -1;
00191 }
00192
00193 if (TAO_debug_level > 0)
00194 {
00195 char client[MAXHOSTNAMELEN + 16];
00196
00197
00198 if (remote_addr.addr_to_string (client,
00199 sizeof (client)) == -1)
00200 {
00201 ACE_OS::strcpy (client, "*unable to obtain*");
00202 }
00203
00204 ACE_DEBUG ((LM_DEBUG,
00205 ACE_TEXT ("TAO (%P|%t) SSLIOP connection from ")
00206 ACE_TEXT ("client <%s> on [%d]\n"),
00207 client,
00208 this->peer ().get_handle ()));
00209
00210
00211 if (local_addr.addr_to_string (client,
00212 sizeof (client)) == -1)
00213 {
00214 ACE_OS::strcpy (client, "*unable to obtain*");
00215 }
00216
00217 ACE_DEBUG ((LM_DEBUG,
00218 ACE_TEXT ("TAO (%P|%t) SSLIOP connection accepted from ")
00219 ACE_TEXT ("server <%s> on [%d]\n"),
00220 client,
00221 this->get_handle ()));
00222 }
00223
00224
00225
00226
00227 if (!this->transport ()->post_open ((size_t) this->get_handle ()))
00228 return -1;
00229
00230
00231 this->state_changed (TAO_LF_Event::LFS_SUCCESS,
00232 this->orb_core ()->leader_follower ());
00233
00234 return 0;
00235 }
00236
00237 int
00238 TAO::SSLIOP::Connection_Handler::resume_handler (void)
00239 {
00240 return ACE_Event_Handler::ACE_APPLICATION_RESUMES_HANDLER;
00241 }
00242
00243 int
00244 TAO::SSLIOP::Connection_Handler::close_connection (void)
00245 {
00246 return this->close_connection_eh (this);
00247 }
00248
00249 int
00250 TAO::SSLIOP::Connection_Handler::handle_input (ACE_HANDLE h)
00251 {
00252 return this->handle_input_eh (h, this);
00253 }
00254
00255 int
00256 TAO::SSLIOP::Connection_Handler::handle_output (ACE_HANDLE handle)
00257 {
00258 const int result =
00259 this->handle_output_eh (handle, this);
00260
00261 if (result == -1)
00262 {
00263 this->close_connection ();
00264 return 0;
00265 }
00266
00267 return result;
00268 }
00269
00270 int
00271 TAO::SSLIOP::Connection_Handler::handle_timeout (const ACE_Time_Value &,
00272 const void *)
00273 {
00274
00275
00276
00277
00278
00279
00280 TAO_Auto_Reference<TAO::SSLIOP::Connection_Handler> safeguard (*this);
00281
00282
00283
00284
00285
00286
00287
00288 int ret = this->close ();
00289 this->reset_state (TAO_LF_Event::LFS_TIMEOUT);
00290 return ret;
00291 }
00292
00293 int
00294 TAO::SSLIOP::Connection_Handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask)
00295 {
00296 ACE_ASSERT (0);
00297 return 0;
00298 }
00299
00300 int
00301 TAO::SSLIOP::Connection_Handler::close (u_long)
00302 {
00303 return this->close_handler ();
00304 }
00305
00306 int
00307 TAO::SSLIOP::Connection_Handler::release_os_resources (void)
00308 {
00309 return this->peer().close ();
00310 }
00311
00312 void
00313 TAO::SSLIOP::Connection_Handler::pos_io_hook (int & return_value)
00314 {
00315 if (return_value == 0 && ::SSL_pending (this->peer ().ssl ()))
00316 return_value = 1;
00317 }
00318
00319 int
00320 TAO::SSLIOP::Connection_Handler::add_transport_to_cache (void)
00321 {
00322 ACE_INET_Addr addr;
00323
00324
00325
00326
00327
00328 if (this->peer ().get_remote_addr (addr) == -1)
00329 return -1;
00330
00331
00332 TAO_IIOP_Endpoint tmpoint (
00333 addr,
00334 this->orb_core()->orb_params()->use_dotted_decimal_addresses());
00335
00336
00337
00338
00339 const ::SSLIOP::SSL ssl =
00340 {
00341 0,
00342 0,
00343 addr.get_port_number ()
00344 };
00345
00346 TAO_SSLIOP_Endpoint endpoint (&ssl,
00347 &tmpoint);
00348
00349
00350 TAO_Base_Transport_Property prop (&endpoint);
00351
00352 TAO::Transport_Cache_Manager &cache =
00353 this->orb_core ()->lane_resources ().transport_cache ();
00354
00355
00356 return cache.cache_idle_transport (&prop, this->transport ());
00357 }
00358
00359 int
00360 TAO::SSLIOP::Connection_Handler::process_listen_point_list (
00361 IIOP::ListenPointList &listen_list)
00362 {
00363
00364 const CORBA::ULong len = listen_list.length ();
00365
00366 for (CORBA::ULong i = 0; i < len; ++i)
00367 {
00368 IIOP::ListenPoint listen_point = listen_list[i];
00369 ACE_INET_Addr addr (listen_point.port,
00370 listen_point.host.in ());
00371
00372
00373 if (TAO_debug_level > 0)
00374 {
00375 ACE_DEBUG ((LM_DEBUG,
00376 "(%P|%t) Listening port [%d] on [%s]\n",
00377 listen_point.port,
00378 listen_point.host.in ()));
00379 }
00380
00381
00382
00383
00384
00385
00386
00387
00388 TAO_IIOP_Endpoint tmpoint (listen_point.host.in (),
00389 listen_point.port,
00390 addr);
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 TAO_SSLIOP_Synthetic_Endpoint endpoint (&tmpoint);
00402
00403
00404 TAO_Base_Transport_Property prop (&endpoint);
00405
00406
00407 prop.set_bidir_flag (1);
00408
00409
00410
00411 const int retval = this->transport ()->recache_transport (&prop);
00412 if (retval == -1)
00413 return retval;
00414
00415
00416 this->transport ()->make_idle ();
00417 }
00418
00419 return 0;
00420 }
00421
00422 int
00423 TAO::SSLIOP::Connection_Handler::setup_ssl_state (
00424 TAO::SSLIOP::Current_Impl *&previous_current_impl,
00425 TAO::SSLIOP::Current_Impl *new_current_impl,
00426 bool &setup_done)
00427 {
00428
00429
00430 new_current_impl->ssl (this->peer ().ssl ());
00431
00432
00433 this->current_->setup (previous_current_impl,
00434 new_current_impl,
00435 setup_done);
00436
00437 return 0;
00438 }
00439
00440 void
00441 TAO::SSLIOP::Connection_Handler::teardown_ssl_state (
00442 TAO::SSLIOP::Current_Impl *previous_current_impl,
00443 bool &setup_done)
00444 {
00445 this->current_->teardown (previous_current_impl, setup_done);
00446 }
00447
00448 TAO_END_VERSIONED_NAMESPACE_DECL