SSLIOP_Transport.cpp

Go to the documentation of this file.
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            "SSLIOP_Transport.cpp,v 1.77 2006/04/20 12:37:17 jwillemsen Exp")
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   CORBA::Boolean /* flag */)
00030   : TAO_Transport (IOP::TAG_INTERNET_IOP, orb_core),
00031     connection_handler_ (handler),
00032     messaging_object_ (0)
00033 {
00034   // Use the normal GIOP object
00035   ACE_NEW (this->messaging_object_,
00036            TAO_GIOP_Message_Base (orb_core, this));
00037 }
00038 
00039 TAO::SSLIOP::Transport::~Transport (void)
00040 {
00041   delete this->messaging_object_;
00042 }
00043 
00044 ACE_Event_Handler *
00045 TAO::SSLIOP::Transport::event_handler_i (void)
00046 {
00047   return this->connection_handler_;
00048 }
00049 
00050 TAO_Connection_Handler *
00051 TAO::SSLIOP::Transport::connection_handler_i (void)
00052 {
00053   return this->connection_handler_;
00054 }
00055 
00056 TAO_Pluggable_Messaging *
00057 TAO::SSLIOP::Transport::messaging_object (void)
00058 {
00059   return this->messaging_object_;
00060 }
00061 
00062 int
00063 TAO::SSLIOP::Transport::handle_input (TAO_Resume_Handle &rh,
00064                                       ACE_Time_Value *max_wait_time,
00065                                       int block)
00066 {
00067   int result = 0;
00068 
00069   // Set up the SSLIOP::Current object.
00070   TAO::SSLIOP::State_Guard ssl_state_guard (this->connection_handler_,
00071                                             result);
00072 
00073   if (result == -1)
00074     return -1;
00075 
00076   return TAO_Transport::handle_input (rh,
00077                                       max_wait_time,
00078                                       block);
00079 }
00080 
00081 ssize_t
00082 TAO::SSLIOP::Transport::send (iovec *iov,
00083                               int iovcnt,
00084                               size_t &bytes_transferred,
00085                               const ACE_Time_Value *max_wait_time)
00086 {
00087   const ssize_t retval =
00088     this->connection_handler_->peer ().sendv (iov, iovcnt, max_wait_time);
00089 
00090   if (retval > 0)
00091     bytes_transferred = retval;
00092 
00093   return retval;
00094 }
00095 
00096 ssize_t
00097 TAO::SSLIOP::Transport::recv (char *buf,
00098                               size_t len,
00099                               const ACE_Time_Value *max_wait_time)
00100 {
00101   const ssize_t n = this->connection_handler_->peer ().recv (buf,
00102                                                              len,
00103                                                              max_wait_time);
00104 
00105   // Most of the errors handling is common for
00106   // Now the message has been read
00107   if (n == -1
00108       && TAO_debug_level > 4
00109       && errno != ETIME)
00110     {
00111       ACE_DEBUG ((LM_DEBUG,
00112                   ACE_TEXT ("TAO (%P|%t) - %p \n"),
00113                   ACE_TEXT ("TAO - read message failure ")
00114                   ACE_TEXT ("recv_i () \n")));
00115     }
00116 
00117   // Error handling
00118   if (n == -1)
00119     {
00120       if (errno == EWOULDBLOCK)
00121         return 0;
00122 
00123       return -1;
00124     }
00125   // @@ What are the other error handling here??
00126   else if (n == 0)
00127     {
00128       return -1;
00129     }
00130 
00131   return n;
00132 }
00133 
00134 int
00135 TAO::SSLIOP::Transport::send_request (TAO_Stub *stub,
00136                                       TAO_ORB_Core *orb_core,
00137                                       TAO_OutputCDR &stream,
00138                                       int message_semantics,
00139                                       ACE_Time_Value *max_wait_time)
00140 {
00141   if (this->ws_->sending_request (orb_core,
00142                                   message_semantics) == -1)
00143     return -1;
00144 
00145   if (this->send_message (stream,
00146                           stub,
00147                           message_semantics,
00148                           max_wait_time) == -1)
00149 
00150     return -1;
00151 
00152   return 0;
00153 }
00154 
00155 int
00156 TAO::SSLIOP::Transport::send_message (TAO_OutputCDR &stream,
00157                                       TAO_Stub *stub,
00158                                       int message_semantics,
00159                                       ACE_Time_Value *max_wait_time)
00160 {
00161   // Format the message in the stream first
00162   if (this->messaging_object_->format_message (stream) != 0)
00163     return -1;
00164 
00165   // Strictly speaking, should not need to loop here because the
00166   // socket never gets set to a nonblocking mode ... some Linux
00167   // versions seem to need it though.  Leaving it costs little.
00168 
00169   // This guarantees to send all data (bytes) or return an error.
00170   const ssize_t n = this->send_message_shared (stub,
00171                                                message_semantics,
00172                                                stream.begin (),
00173                                                max_wait_time);
00174 
00175   if (n == -1)
00176     {
00177       if (TAO_debug_level)
00178         ACE_DEBUG ((LM_DEBUG,
00179                     ACE_TEXT ("TAO: (%P|%t|%N|%l) closing transport ")
00180                     ACE_TEXT ("%d after fault %p\n"),
00181                     this->id (),
00182                     ACE_TEXT ("send_message ()\n")));
00183 
00184       return -1;
00185     }
00186 
00187   return 1;
00188 }
00189 
00190 
00191 int
00192 TAO::SSLIOP::Transport::generate_request_header (
00193   TAO_Operation_Details &opdetails,
00194   TAO_Target_Specification &spec,
00195   TAO_OutputCDR &msg)
00196 {
00197   // Check whether we have a Bi Dir IIOP policy set, whether the
00198   // messaging objects are ready to handle bidirectional connections
00199   // and also make sure that we have not recd. or sent any information
00200   // regarding this before...
00201   if (this->orb_core ()->bidir_giop_policy ()
00202       && this->messaging_object_->is_ready_for_bidirectional (msg)
00203       && this->bidirectional_flag () < 0)
00204     {
00205       this->set_bidir_context_info (opdetails);
00206 
00207       // Set the flag to 1
00208       this->bidirectional_flag (1);
00209 
00210       // At the moment we enable BiDIR giop we have to get a new
00211       // request id to make sure that we follow the even/odd rule
00212       // for request id's. We only need to do this when enabled
00213       // it, after that the Transport Mux Strategy will make sure
00214       // that the rule is followed
00215       opdetails.request_id (this->tms ()->request_id ());
00216     }
00217 
00218   // We are going to pass on this request to the underlying messaging
00219   // layer. It should take care of this request
00220   return TAO_Transport::generate_request_header (opdetails,
00221                                                  spec,
00222                                                  msg);
00223 }
00224 
00225 int
00226 TAO::SSLIOP::Transport::messaging_init (CORBA::Octet major,
00227                                         CORBA::Octet minor)
00228 {
00229   this->messaging_object_->init (major,
00230                                  minor);
00231   return 1;
00232 }
00233 
00234 
00235 int
00236 TAO::SSLIOP::Transport::tear_listen_point_list (TAO_InputCDR &cdr)
00237 {
00238   CORBA::Boolean byte_order;
00239   if ((cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00240     return -1;
00241 
00242   cdr.reset_byte_order (static_cast<int> (byte_order));
00243 
00244   IIOP::ListenPointList listen_list;
00245   if ((cdr >> listen_list) == 0)
00246     return -1;
00247 
00248   // As we have received a bidirectional information, set the flag to
00249   // 0
00250   this->bidirectional_flag (0);
00251 
00252   return this->connection_handler_->process_listen_point_list (listen_list);
00253 }
00254 
00255 
00256 
00257 void
00258 TAO::SSLIOP::Transport::set_bidir_context_info (
00259   TAO_Operation_Details &opdetails)
00260 {
00261   // Get a handle on to the acceptor registry
00262   TAO_Acceptor_Registry &ar =
00263     this->orb_core ()->lane_resources ().acceptor_registry ();
00264 
00265   // Get the first acceptor in the registry
00266   TAO_AcceptorSetIterator acceptor = ar.begin ();
00267 
00268   IIOP::ListenPointList listen_point_list;
00269 
00270   for (;
00271        acceptor != ar.end ();
00272        acceptor++)
00273     {
00274       // Check whether it is a IIOP acceptor
00275       if ((*acceptor)->tag () == IOP::TAG_INTERNET_IOP)
00276         {
00277           if (this->get_listen_point (listen_point_list,
00278                                       *acceptor) == -1)
00279             {
00280               ACE_ERROR ((LM_ERROR,
00281                           "TAO (%P|%t) - SSLIOP_Transport::set_bidir_info, ",
00282                           "error getting listen_point \n"));
00283 
00284               return;
00285             }
00286         }
00287     }
00288 
00289   // We have the ListenPointList at this point. Create a output CDR
00290   // stream at this point
00291   TAO_OutputCDR cdr;
00292 
00293   // Marshall the information into the stream
00294   if ((cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER) == 0)
00295       || (cdr << listen_point_list) == 0)
00296     return;
00297 
00298   // Add this info in to the svc_list
00299   opdetails.request_service_context ().set_context (IOP::BI_DIR_IIOP,
00300                                                     cdr);
00301   return;
00302 }
00303 
00304 
00305 int
00306 TAO::SSLIOP::Transport::get_listen_point (
00307   IIOP::ListenPointList &listen_point_list,
00308   TAO_Acceptor *acceptor)
00309 {
00310   TAO::SSLIOP::Acceptor *ssliop_acceptor =
00311     dynamic_cast<TAO::SSLIOP::Acceptor *> (acceptor);
00312 
00313   if (ssliop_acceptor == 0)
00314     return -1;
00315 
00316   // Get the array of IIOP (not SSLIOP!) endpoints serviced by the
00317   // SSLIOP_Acceptor.
00318   const ACE_INET_Addr *endpoint_addr =
00319     ssliop_acceptor->endpoints ();
00320 
00321   // Get the count
00322   const size_t count =
00323     ssliop_acceptor->endpoint_count ();
00324 
00325   // The SSL port is stored in the SSLIOP::SSL component associated
00326   // with the SSLIOP_Acceptor.
00327   const ::SSLIOP::SSL &ssl = ssliop_acceptor->ssl_component ();
00328 
00329   // Get the local address of the connection
00330   ACE_INET_Addr local_addr;
00331   {
00332     if (this->connection_handler_->peer ().get_local_addr (local_addr)
00333         == -1)
00334       {
00335         ACE_ERROR_RETURN ((LM_ERROR,
00336                            ACE_TEXT ("(%P|%t) Could not resolve local host")
00337                            ACE_TEXT (" address in get_listen_point()\n")),
00338                         -1);
00339     }
00340 
00341   }
00342 
00343   // Note: Looks like there is no point in sending the list of
00344   // endpoints on interfaces on which this connection has not
00345   // been established. If this is wrong, please correct me.
00346   CORBA::String_var local_interface;
00347 
00348   // Get the hostname for the local address
00349   if (ssliop_acceptor->hostname (this->orb_core_,
00350                                  local_addr,
00351                                  local_interface.out ()) == -1)
00352     {
00353       ACE_ERROR_RETURN ((LM_ERROR,
00354                          ACE_TEXT ("(%P|%t) Could not resolve local host")
00355                          ACE_TEXT (" name \n")),
00356                         -1);
00357     }
00358 
00359   for (size_t index = 0; index < count; ++index)
00360     {
00361       if (local_addr.get_ip_address ()
00362           == endpoint_addr[index].get_ip_address ())
00363         {
00364           // Get the count of the number of elements
00365           const CORBA::ULong len = listen_point_list.length ();
00366 
00367           // Increase the length by 1
00368           listen_point_list.length (len + 1);
00369 
00370           // We have the connection and the acceptor endpoint on the
00371           // same interface
00372           IIOP::ListenPoint & point = listen_point_list[len];
00373           point.host = CORBA::string_dup (local_interface.in ());
00374 
00375           // All endpoints, if more than one, serviced by the
00376           // SSLIOP_Acceptor should be listening on the same port (due
00377           // to the bind to the INADDR_ANY address).
00378           point.port = ssl.port;
00379         }
00380     }
00381 
00382   return 1;
00383 }
00384 
00385 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 13:54:15 2006 for TAO_SSLIOP by doxygen 1.3.6