00001 #include "orbsvcs/SSLIOP/SSLIOP_Connection_Handler.h"
00002 #include "orbsvcs/SSLIOP/SSLIOP_Transport.h"
00003 #include "orbsvcs/SSLIOP/SSLIOP_Profile.h"
00004 #include "orbsvcs/SSLIOP/SSLIOP_Acceptor.h"
00005
00006 #include "tao/debug.h"
00007
00008 #include "tao/Timeprobe.h"
00009 #include "tao/CDR.h"
00010 #include "tao/Transport_Mux_Strategy.h"
00011 #include "tao/Wait_Strategy.h"
00012 #include "tao/Stub.h"
00013 #include "tao/ORB_Core.h"
00014 #include "tao/debug.h"
00015 #include "tao/GIOP_Message_Base.h"
00016 #include "tao/Acceptor_Registry.h"
00017 #include "tao/Thread_Lane_Resources.h"
00018
00019 ACE_RCSID (SSLIOP,
00020 SSLIOP_Transport,
00021 "$Id: SSLIOP_Transport.cpp 80441 2008-01-16 18:13:50Z johnnyw $")
00022
00023
00024 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00025
00026 TAO::SSLIOP::Transport::Transport (
00027 TAO::SSLIOP::Connection_Handler *handler,
00028 TAO_ORB_Core *orb_core)
00029 : TAO_Transport (IOP::TAG_INTERNET_IOP, orb_core),
00030 connection_handler_ (handler)
00031 {
00032 }
00033
00034 TAO::SSLIOP::Transport::~Transport (void)
00035 {
00036 }
00037
00038 ACE_Event_Handler *
00039 TAO::SSLIOP::Transport::event_handler_i (void)
00040 {
00041 return this->connection_handler_;
00042 }
00043
00044 TAO_Connection_Handler *
00045 TAO::SSLIOP::Transport::connection_handler_i (void)
00046 {
00047 return this->connection_handler_;
00048 }
00049
00050 int
00051 TAO::SSLIOP::Transport::handle_input (TAO_Resume_Handle &rh,
00052 ACE_Time_Value *max_wait_time)
00053 {
00054 int result = 0;
00055
00056
00057 TAO::SSLIOP::State_Guard ssl_state_guard (this->connection_handler_, result);
00058
00059 if (result == -1)
00060 return -1;
00061
00062 return TAO_Transport::handle_input (rh, max_wait_time);
00063 }
00064
00065 ssize_t
00066 TAO::SSLIOP::Transport::send (iovec *iov,
00067 int iovcnt,
00068 size_t &bytes_transferred,
00069 const ACE_Time_Value *max_wait_time)
00070 {
00071 ssize_t const retval =
00072 this->connection_handler_->peer ().sendv (iov, iovcnt, max_wait_time);
00073
00074 if (retval > 0)
00075 bytes_transferred = retval;
00076
00077 return retval;
00078 }
00079
00080 ssize_t
00081 TAO::SSLIOP::Transport::recv (char *buf,
00082 size_t len,
00083 const ACE_Time_Value *max_wait_time)
00084 {
00085 ssize_t const n = this->connection_handler_->peer ().recv (buf,
00086 len,
00087 max_wait_time);
00088
00089
00090
00091 if (n == -1 && TAO_debug_level > 4 && errno != ETIME)
00092 {
00093 ACE_DEBUG ((LM_DEBUG,
00094 ACE_TEXT ("TAO (%P|%t) - SSLIOP_Transport[%d]::recv, ")
00095 ACE_TEXT ("read failure - %m errno %d\n"),
00096 this->id (),
00097 errno));
00098 }
00099
00100
00101 if (n == -1)
00102 {
00103 if (errno == EWOULDBLOCK)
00104 return 0;
00105
00106 return -1;
00107 }
00108
00109 else if (n == 0)
00110 {
00111 return -1;
00112 }
00113
00114 return n;
00115 }
00116
00117 int
00118 TAO::SSLIOP::Transport::send_request (TAO_Stub *stub,
00119 TAO_ORB_Core *orb_core,
00120 TAO_OutputCDR &stream,
00121 TAO_Message_Semantics message_semantics,
00122 ACE_Time_Value *max_wait_time)
00123 {
00124 if (this->ws_->sending_request (orb_core, message_semantics) == -1)
00125 return -1;
00126
00127 if (this->send_message (stream,
00128 stub,
00129 message_semantics,
00130 max_wait_time) == -1)
00131
00132 return -1;
00133
00134 return 0;
00135 }
00136
00137 int
00138 TAO::SSLIOP::Transport::send_message (TAO_OutputCDR &stream,
00139 TAO_Stub *stub,
00140 TAO_Message_Semantics message_semantics,
00141 ACE_Time_Value *max_wait_time)
00142 {
00143
00144 if (this->messaging_object_->format_message (stream) != 0)
00145 return -1;
00146
00147
00148
00149
00150
00151
00152 ssize_t const n = this->send_message_shared (stub,
00153 message_semantics,
00154 stream.begin (),
00155 max_wait_time);
00156
00157 if (n == -1)
00158 {
00159 if (TAO_debug_level)
00160 ACE_ERROR ((LM_ERROR,
00161 ACE_TEXT ("TAO (%P|%t) - SSLIOP_Transport::send_message, ")
00162 ACE_TEXT ("closing transport %d after fault %p\n"),
00163 this->id (),
00164 ACE_TEXT ("send_message ()\n")));
00165
00166 return -1;
00167 }
00168
00169 return 1;
00170 }
00171
00172
00173 int
00174 TAO::SSLIOP::Transport::generate_request_header (
00175 TAO_Operation_Details &opdetails,
00176 TAO_Target_Specification &spec,
00177 TAO_OutputCDR &msg)
00178 {
00179
00180
00181
00182
00183 if (this->orb_core ()->bidir_giop_policy ()
00184 && this->messaging_object_->is_ready_for_bidirectional (msg)
00185 && this->bidirectional_flag () < 0)
00186 {
00187 this->set_bidir_context_info (opdetails);
00188
00189
00190 this->bidirectional_flag (1);
00191
00192
00193
00194
00195
00196
00197 opdetails.request_id (this->tms ()->request_id ());
00198 }
00199
00200
00201
00202 return TAO_Transport::generate_request_header (opdetails, spec, msg);
00203 }
00204
00205 int
00206 TAO::SSLIOP::Transport::tear_listen_point_list (TAO_InputCDR &cdr)
00207 {
00208 CORBA::Boolean byte_order;
00209 if ((cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00210 return -1;
00211
00212 cdr.reset_byte_order (static_cast<int> (byte_order));
00213
00214 IIOP::ListenPointList listen_list;
00215 if ((cdr >> listen_list) == 0)
00216 return -1;
00217
00218
00219
00220 this->bidirectional_flag (0);
00221
00222 return this->connection_handler_->process_listen_point_list (listen_list);
00223 }
00224
00225
00226
00227 void
00228 TAO::SSLIOP::Transport::set_bidir_context_info (
00229 TAO_Operation_Details &opdetails)
00230 {
00231
00232 TAO_Acceptor_Registry &ar =
00233 this->orb_core ()->lane_resources ().acceptor_registry ();
00234
00235
00236 TAO_AcceptorSetIterator acceptor = ar.begin ();
00237
00238 IIOP::ListenPointList listen_point_list;
00239
00240 for (;
00241 acceptor != ar.end ();
00242 acceptor++)
00243 {
00244
00245 if ((*acceptor)->tag () == IOP::TAG_INTERNET_IOP)
00246 {
00247 if (this->get_listen_point (listen_point_list, *acceptor) == -1)
00248 {
00249 ACE_ERROR ((LM_ERROR,
00250 "TAO (%P|%t) - SSLIOP_Transport::set_bidir_info, ",
00251 "error getting listen_point \n"));
00252 return;
00253 }
00254 }
00255 }
00256
00257
00258
00259 TAO_OutputCDR cdr;
00260
00261
00262 if ((cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER) == 0)
00263 || (cdr << listen_point_list) == 0)
00264 return;
00265
00266
00267 opdetails.request_service_context ().set_context (IOP::BI_DIR_IIOP, cdr);
00268 return;
00269 }
00270
00271
00272 int
00273 TAO::SSLIOP::Transport::get_listen_point (
00274 IIOP::ListenPointList &listen_point_list,
00275 TAO_Acceptor *acceptor)
00276 {
00277 TAO::SSLIOP::Acceptor *ssliop_acceptor =
00278 dynamic_cast<TAO::SSLIOP::Acceptor *> (acceptor);
00279
00280 if (ssliop_acceptor == 0)
00281 return -1;
00282
00283
00284
00285 const ACE_INET_Addr *endpoint_addr = ssliop_acceptor->endpoints ();
00286
00287
00288 size_t const count = ssliop_acceptor->endpoint_count ();
00289
00290
00291
00292 const ::SSLIOP::SSL &ssl = ssliop_acceptor->ssl_component ();
00293
00294
00295 ACE_INET_Addr local_addr;
00296 {
00297 if (this->connection_handler_->peer ().get_local_addr (local_addr) == -1)
00298 {
00299 ACE_ERROR_RETURN ((LM_ERROR,
00300 ACE_TEXT ("(%P|%t) Could not resolve local host")
00301 ACE_TEXT (" address in get_listen_point()\n")),
00302 -1);
00303 }
00304
00305 }
00306
00307
00308
00309
00310 CORBA::String_var local_interface;
00311
00312
00313 if (ssliop_acceptor->hostname (this->orb_core_,
00314 local_addr,
00315 local_interface.out ()) == -1)
00316 {
00317 ACE_ERROR_RETURN ((LM_ERROR,
00318 ACE_TEXT ("(%P|%t) Could not resolve local host")
00319 ACE_TEXT (" name \n")),
00320 -1);
00321 }
00322
00323 #if defined (ACE_HAS_IPV6)
00324
00325
00326 const char *cp_scope = 0;
00327 if (local_addr.get_type () == PF_INET6 &&
00328 (cp_scope = ACE_OS::strchr (local_interface.in (), '%')) != 0)
00329 {
00330 CORBA::ULong len = cp_scope - local_interface.in ();
00331 local_interface[len] = '\0';
00332 }
00333 #endif
00334
00335 for (size_t index = 0; index < count; ++index)
00336 {
00337
00338
00339 local_addr.set_port_number (endpoint_addr[index].get_port_number ());
00340
00341 if (local_addr == endpoint_addr[index])
00342 {
00343
00344 CORBA::ULong const len = listen_point_list.length ();
00345
00346
00347 listen_point_list.length (len + 1);
00348
00349
00350
00351 IIOP::ListenPoint & point = listen_point_list[len];
00352 point.host = CORBA::string_dup (local_interface.in ());
00353
00354
00355
00356
00357 point.port = ssl.port;
00358 }
00359 }
00360
00361 return 1;
00362 }
00363
00364 TAO_END_VERSIONED_NAMESPACE_DECL