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