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.i"
00019 #endif
00020
00021 ACE_RCSID (SSLIOP,
00022 SSLIOP_Connection_Handler,
00023 "SSLIOP_Connection_Handler.cpp,v 1.84 2006/03/14 06:14:35 jtc Exp")
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 (
00044 TAO_ORB_Core *orb_core,
00045 CORBA::Boolean )
00046 : SVC_HANDLER (orb_core->thr_mgr (), 0, 0),
00047 TAO_Connection_Handler (orb_core),
00048 current_ ()
00049 {
00050 this->current_ =
00051 TAO::SSLIOP::Util::current (orb_core);
00052
00053 TAO::SSLIOP::Transport* specific_transport = 0;
00054 ACE_NEW (specific_transport,
00055 TAO::SSLIOP::Transport (this, orb_core, 0));
00056
00057
00058 this->transport (specific_transport);
00059 }
00060
00061 TAO::SSLIOP::Connection_Handler::~Connection_Handler (void)
00062 {
00063 delete this->transport ();
00064 }
00065
00066 int
00067 TAO::SSLIOP::Connection_Handler::open_handler (void *v)
00068 {
00069 return this->open (v);
00070 }
00071
00072 int
00073 TAO::SSLIOP::Connection_Handler::open (void *)
00074 {
00075 TAO_IIOP_Protocol_Properties protocol_properties;
00076
00077
00078 protocol_properties.send_buffer_size_ =
00079 this->orb_core ()->orb_params ()->sock_sndbuf_size ();
00080 protocol_properties.recv_buffer_size_ =
00081 this->orb_core ()->orb_params ()->sock_rcvbuf_size ();
00082 protocol_properties.no_delay_ =
00083 this->orb_core ()->orb_params ()->nodelay ();
00084
00085 TAO_Protocols_Hooks *tph =
00086 this->orb_core ()->get_protocols_hooks ();
00087
00088 int client =
00089 this->transport ()->opened_as () == TAO::TAO_CLIENT_ROLE;;
00090
00091 ACE_DECLARE_NEW_CORBA_ENV;
00092
00093 ACE_TRY
00094 {
00095 if (client)
00096 {
00097 tph->client_protocol_properties_at_orb_level (
00098 protocol_properties
00099 ACE_ENV_ARG_PARAMETER);
00100 ACE_TRY_CHECK;
00101 }
00102 else
00103 {
00104 tph->server_protocol_properties_at_orb_level (
00105 protocol_properties
00106 ACE_ENV_ARG_PARAMETER);
00107 ACE_TRY_CHECK;
00108 }
00109 }
00110 ACE_CATCHANY
00111 {
00112 return -1;
00113 }
00114 ACE_ENDTRY;
00115 ACE_CHECK_RETURN (-1);
00116
00117 if (this->set_socket_option (this->peer (),
00118 protocol_properties.send_buffer_size_,
00119 protocol_properties.recv_buffer_size_) == -1)
00120 return -1;
00121
00122 #if !defined (ACE_LACKS_TCP_NODELAY)
00123 if (this->peer ().set_option (ACE_IPPROTO_TCP,
00124 TCP_NODELAY,
00125 (void *) &protocol_properties.no_delay_,
00126 sizeof (protocol_properties.no_delay_)) == -1)
00127 return -1;
00128 #endif
00129
00130 if (this->transport ()->wait_strategy ()->non_blocking ())
00131 {
00132 if (this->peer ().enable (ACE_NONBLOCK) == -1)
00133 return -1;
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 (void) ::SSL_set_mode (this->peer ().ssl (),
00156 SSL_MODE_ENABLE_PARTIAL_WRITE);
00157 (void) ::SSL_set_mode (this->peer ().ssl (),
00158 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
00159 }
00160
00161
00162
00163 ACE_INET_Addr remote_addr;
00164 if (this->peer ().get_remote_addr (remote_addr) == -1)
00165 return -1;
00166
00167 ACE_INET_Addr local_addr;
00168 if (this->peer ().get_local_addr (local_addr) == -1)
00169 return -1;
00170
00171 int use_dotted_decimal_addresses =
00172 this->orb_core ()->orb_params ()->use_dotted_decimal_addresses ();
00173
00174 if (local_addr.get_ip_address () == remote_addr.get_ip_address ()
00175 && local_addr.get_port_number () == remote_addr.get_port_number ())
00176 {
00177 if (TAO_debug_level > 0)
00178 {
00179 char remote_as_string[MAXHOSTNAMELEN + 16];
00180 char local_as_string[MAXHOSTNAMELEN + 16];
00181
00182 (void) remote_addr.addr_to_string (remote_as_string,
00183 sizeof (remote_as_string),
00184 use_dotted_decimal_addresses);
00185 (void) local_addr.addr_to_string (local_as_string,
00186 sizeof (local_as_string),
00187 use_dotted_decimal_addresses);
00188 ACE_ERROR ((LM_ERROR,
00189 "TAO(%P|%t) - TAO::SSLIOP::Connection_Handler::open, "
00190 "Holy Cow! The remote addr and "
00191 "local addr are identical (%s == %s)\n",
00192 remote_as_string, local_as_string));
00193 }
00194
00195 return -1;
00196 }
00197
00198 if (TAO_debug_level > 0)
00199 {
00200 char client[MAXHOSTNAMELEN + 16];
00201
00202
00203 if (remote_addr.addr_to_string (client,
00204 sizeof (client),
00205 use_dotted_decimal_addresses) == -1)
00206 {
00207 ACE_OS::strcpy (client, "*unable to obtain*");
00208 }
00209
00210 ACE_DEBUG ((LM_DEBUG,
00211 ACE_TEXT ("TAO (%P|%t) SSLIOP connection from ")
00212 ACE_TEXT ("client <%s> on [%d]\n"),
00213 client,
00214 this->peer ().get_handle ()));
00215
00216
00217 if (local_addr.addr_to_string (client,
00218 sizeof (client),
00219 use_dotted_decimal_addresses) == -1)
00220 {
00221 ACE_OS::strcpy (client, "*unable to obtain*");
00222 }
00223
00224 ACE_DEBUG ((LM_DEBUG,
00225 ACE_TEXT ("TAO (%P|%t) SSLIOP connection accepted from ")
00226 ACE_TEXT ("server <%s> on [%d]\n"),
00227 client,
00228 this->get_handle ()));
00229 }
00230
00231
00232
00233
00234 if (!this->transport ()->post_open ((size_t) this->get_handle ()))
00235 return -1;
00236
00237
00238 this->state_changed (TAO_LF_Event::LFS_SUCCESS,
00239 this->orb_core ()->leader_follower ());
00240
00241 return 0;
00242 }
00243
00244 int
00245 TAO::SSLIOP::Connection_Handler::resume_handler (void)
00246 {
00247 return ACE_Event_Handler::ACE_APPLICATION_RESUMES_HANDLER;
00248 }
00249
00250 int
00251 TAO::SSLIOP::Connection_Handler::close_connection (void)
00252 {
00253 return this->close_connection_eh (this);
00254 }
00255
00256 int
00257 TAO::SSLIOP::Connection_Handler::handle_input (ACE_HANDLE h)
00258 {
00259 return this->handle_input_eh (h, this);
00260 }
00261
00262 int
00263 TAO::SSLIOP::Connection_Handler::handle_output (ACE_HANDLE handle)
00264 {
00265 const int result =
00266 this->handle_output_eh (handle, this);
00267
00268 if (result == -1)
00269 {
00270 this->close_connection ();
00271 return 0;
00272 }
00273
00274 return result;
00275 }
00276
00277 int
00278 TAO::SSLIOP::Connection_Handler::handle_timeout (const ACE_Time_Value &,
00279 const void *)
00280 {
00281
00282
00283
00284 return this->close ();
00285 }
00286
00287 int
00288 TAO::SSLIOP::Connection_Handler::handle_close (ACE_HANDLE,
00289 ACE_Reactor_Mask)
00290 {
00291 ACE_ASSERT (0);
00292 return 0;
00293 }
00294
00295 int
00296 TAO::SSLIOP::Connection_Handler::close (u_long)
00297 {
00298 return this->close_handler ();
00299 }
00300
00301 int
00302 TAO::SSLIOP::Connection_Handler::release_os_resources (void)
00303 {
00304 return this->peer().close ();
00305 }
00306
00307 void
00308 TAO::SSLIOP::Connection_Handler::pos_io_hook (int & return_value)
00309 {
00310 if (return_value == 0 && ::SSL_pending (this->peer ().ssl ()))
00311 return_value = 1;
00312 }
00313
00314 int
00315 TAO::SSLIOP::Connection_Handler::add_transport_to_cache (void)
00316 {
00317 ACE_INET_Addr addr;
00318
00319
00320
00321
00322
00323 if (this->peer ().get_remote_addr (addr) == -1)
00324 return -1;
00325
00326
00327 TAO_IIOP_Endpoint tmpoint (
00328 addr,
00329 this->orb_core()->orb_params()->use_dotted_decimal_addresses());
00330
00331
00332
00333
00334 const ::SSLIOP::SSL ssl =
00335 {
00336 0,
00337 0,
00338 addr.get_port_number ()
00339 };
00340
00341 TAO_SSLIOP_Endpoint endpoint (&ssl,
00342 &tmpoint);
00343
00344
00345 TAO_Base_Transport_Property prop (&endpoint);
00346
00347 TAO::Transport_Cache_Manager &cache =
00348 this->orb_core ()->lane_resources ().transport_cache ();
00349
00350
00351 return cache.cache_idle_transport (&prop,
00352 this->transport ());
00353 }
00354
00355 int
00356 TAO::SSLIOP::Connection_Handler::process_listen_point_list (
00357 IIOP::ListenPointList &listen_list)
00358 {
00359
00360 const CORBA::ULong 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 const int retval = this->transport ()->recache_transport (&prop);
00408 if (retval == -1)
00409 return retval;
00410
00411
00412 this->transport ()->make_idle ();
00413 }
00414
00415 return 0;
00416 }
00417
00418 int
00419 TAO::SSLIOP::Connection_Handler::setup_ssl_state (
00420 TAO::SSLIOP::Current_Impl *&previous_current_impl,
00421 TAO::SSLIOP::Current_Impl *new_current_impl,
00422 bool &setup_done)
00423 {
00424
00425
00426 new_current_impl->ssl (this->peer ().ssl ());
00427
00428
00429 this->current_->setup (previous_current_impl,
00430 new_current_impl,
00431 setup_done);
00432
00433 return 0;
00434 }
00435
00436 void
00437 TAO::SSLIOP::Connection_Handler::teardown_ssl_state (
00438 TAO::SSLIOP::Current_Impl *previous_current_impl,
00439 bool &setup_done)
00440 {
00441 this->current_->teardown (previous_current_impl,
00442 setup_done);
00443 }
00444
00445 TAO_END_VERSIONED_NAMESPACE_DECL