SCIOP_Connection_Handler.cpp

Go to the documentation of this file.
00001 #include "tao/Strategies/SCIOP_Connection_Handler.h"
00002 
00003 #if TAO_HAS_SCIOP == 1
00004 
00005 // jcohen@atl.lmco.com: The purpose of this is to allow RH9 to build
00006 // SCIOR Profile support even without a functioning SCTP implementation
00007 
00008 #ifndef IPPROTO_SCTP
00009 #  include "netinet/sctp.h"
00010 #else // !IPPROTO_SCTP
00011 #  ifndef SCTP_NODELAY
00012 #    define SCTP_NODELAY 1
00013 #  endif // !SCTP_NODELAY
00014 #endif
00015 
00016 #include "tao/Timeprobe.h"
00017 #include "tao/debug.h"
00018 #include "tao/ORB_Core.h"
00019 #include "tao/ORB.h"
00020 #include "tao/CDR.h"
00021 #include "tao/Server_Strategy_Factory.h"
00022 #include "tao/Strategies/SCIOP_Transport.h"
00023 #include "tao/Strategies/SCIOP_Endpoint.h"
00024 #include "tao/Transport_Cache_Manager.h"
00025 #include "tao/Thread_Lane_Resources.h"
00026 #include "tao/Base_Transport_Property.h"
00027 #include "tao/Resume_Handle.h"
00028 #include "tao/Protocols_Hooks.h"
00029 #include "tao/Wait_Strategy.h"
00030 
00031 ACE_RCSID (tao,
00032            SCIOP_Connection_Handler,
00033            "SCIOP_Connection_Handler.cpp,v 1.23 2006/04/19 11:38:50 jwillemsen Exp")
00034 
00035 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00036 
00037 TAO_SCIOP_Connection_Handler::TAO_SCIOP_Connection_Handler (ACE_Thread_Manager *t)
00038   : TAO_SCIOP_SVC_HANDLER (t, 0 , 0),
00039     TAO_Connection_Handler (0),
00040     dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
00041 {
00042   // This constructor should *never* get called, it is just here to
00043   // make the compiler happy: the default implementation of the
00044   // Creation_Strategy requires a constructor with that signature, we
00045   // don't use that implementation, but some (most?) compilers
00046   // instantiate it anyway.
00047   ACE_ASSERT (0);
00048 }
00049 
00050 
00051 TAO_SCIOP_Connection_Handler::TAO_SCIOP_Connection_Handler (TAO_ORB_Core *orb_core,
00052                                                             CORBA::Boolean flag)
00053   : TAO_SCIOP_SVC_HANDLER (orb_core->thr_mgr (), 0, 0),
00054     TAO_Connection_Handler (orb_core),
00055     dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
00056 {
00057   TAO_SCIOP_Transport* specific_transport = 0;
00058   ACE_NEW (specific_transport,
00059            TAO_SCIOP_Transport (this, orb_core, flag));
00060 
00061   // store this pointer (indirectly increment ref count)
00062   this->transport (specific_transport);
00063 }
00064 
00065 TAO_SCIOP_Connection_Handler::TAO_SCIOP_Connection_Handler (TAO_ORB_Core *orb_core)
00066   : TAO_SCIOP_SVC_HANDLER (orb_core->thr_mgr (), 0, 0),
00067     TAO_Connection_Handler (orb_core),
00068     dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
00069 {
00070 }
00071 
00072 
00073 TAO_SCIOP_Connection_Handler::~TAO_SCIOP_Connection_Handler (void)
00074 {
00075   delete this->transport ();
00076 }
00077 
00078 int
00079 TAO_SCIOP_Connection_Handler::open_handler (void *v)
00080 {
00081   return this->open (v);
00082 }
00083 
00084 int
00085 TAO_SCIOP_Connection_Handler::open (void*)
00086 {
00087   TAO_SCIOP_Protocol_Properties protocol_properties;
00088 
00089   // Initialize values from ORB params.
00090   protocol_properties.send_buffer_size_ =
00091     this->orb_core ()->orb_params ()->sock_sndbuf_size ();
00092   protocol_properties.recv_buffer_size_ =
00093     this->orb_core ()->orb_params ()->sock_rcvbuf_size ();
00094   protocol_properties.no_delay_ =
00095     this->orb_core ()->orb_params ()->nodelay ();
00096 
00097   TAO_Protocols_Hooks *tph =
00098     this->orb_core ()->get_protocols_hooks ();
00099 
00100   bool client =
00101     this->transport ()->opened_as () == TAO::TAO_CLIENT_ROLE;;
00102 
00103   ACE_DECLARE_NEW_CORBA_ENV;
00104 
00105   ACE_TRY
00106     {
00107       if (client)
00108         {
00109           tph->client_protocol_properties_at_orb_level (
00110             protocol_properties
00111             ACE_ENV_ARG_PARAMETER);
00112           ACE_TRY_CHECK;
00113         }
00114       else
00115         {
00116           tph->server_protocol_properties_at_orb_level (
00117             protocol_properties
00118             ACE_ENV_ARG_PARAMETER);
00119           ACE_TRY_CHECK;
00120         }
00121     }
00122   ACE_CATCHANY
00123     {
00124       return -1;
00125     }
00126   ACE_ENDTRY;
00127   ACE_CHECK_RETURN (-1);
00128 
00129   if (this->set_socket_option (this->peer (),
00130                                protocol_properties.send_buffer_size_,
00131                                protocol_properties.recv_buffer_size_) == -1)
00132     return -1;
00133 
00134 #if !defined (ACE_LACKS_TCP_NODELAY)
00135   if (this->peer ().set_option (IPPROTO_SCTP,
00136                                 SCTP_NODELAY,
00137                                 (void *) &protocol_properties.no_delay_,
00138                                 sizeof (protocol_properties.no_delay_)) == -1)
00139     return -1;
00140 #endif /* ! ACE_LACKS_TCP_NODELAY */
00141 
00142   if (this->transport ()->wait_strategy ()->non_blocking ())
00143     {
00144       if (this->peer ().enable (ACE_NONBLOCK) == -1)
00145         return -1;
00146     }
00147 
00148   // Called by the <Strategy_Acceptor> when the handler is
00149   // completely connected.
00150 
00151   ACE_INET_Addr remote_addr;
00152   if (this->peer ().get_remote_addr (remote_addr) == -1)
00153     return -1;
00154 
00155   ACE_INET_Addr local_addr;
00156   if (this->peer ().get_local_addr (local_addr) == -1)
00157     return -1;
00158 
00159 
00160   if (TAO_debug_level > 2)
00161     ACE_DEBUG ((LM_DEBUG,
00162                 ACE_TEXT("TAO(%P|%t) - SCIOP_Connection_Handler::open, ")
00163                 ACE_TEXT("The local addr is (%s) \n"),
00164                 local_addr. get_host_addr ()));
00165 
00166   if (local_addr.get_ip_address () == remote_addr.get_ip_address ()
00167       && local_addr.get_port_number () == remote_addr.get_port_number ())
00168     {
00169       if (TAO_debug_level > 0)
00170         {
00171           ACE_TCHAR remote_as_string[MAXHOSTNAMELEN + 16];
00172           ACE_TCHAR local_as_string[MAXHOSTNAMELEN + 16];
00173 
00174           (void) remote_addr.addr_to_string (remote_as_string,
00175                                              sizeof(remote_as_string));
00176           (void) local_addr.addr_to_string (local_as_string,
00177                                             sizeof(local_as_string));
00178           ACE_ERROR ((LM_ERROR,
00179                       ACE_TEXT("TAO(%P|%t) - TAO_SCIOP_Connection_Handler::open, ")
00180                       ACE_TEXT("Holy Cow! The remote addr and ")
00181                       ACE_TEXT("local addr are identical (%s == %s)\n"),
00182                       remote_as_string, local_as_string));
00183         }
00184       return -1;
00185     }
00186 
00187   if (TAO_debug_level > 0)
00188     {
00189       ACE_TCHAR client[MAXHOSTNAMELEN + 16];
00190 
00191       // Verify that we can resolve the peer hostname.
00192       if (remote_addr.addr_to_string (client, sizeof (client)) == -1)
00193         return -1;
00194 
00195       ACE_DEBUG ((LM_DEBUG,
00196                   ACE_TEXT ("TAO (%P|%t) - SCIOP_Connection_Handler::open, SCIOP ")
00197                   ACE_TEXT ("connection to peer <%s> on %d\n"),
00198                   client, this->peer ().get_handle ()));
00199     }
00200 
00201   // Set that the transport is now connected, if fails we return -1
00202   // Use C-style cast b/c otherwise we get warnings on lots of
00203   // compilers
00204   if (!this->transport ()->post_open ((size_t) this->get_handle ()))
00205     return -1;
00206 
00207   this->state_changed (TAO_LF_Event::LFS_SUCCESS,
00208                        this->orb_core ()->leader_follower ());
00209 
00210   return 0;
00211 }
00212 
00213 int
00214 TAO_SCIOP_Connection_Handler::resume_handler (void)
00215 {
00216   return ACE_Event_Handler::ACE_APPLICATION_RESUMES_HANDLER;
00217 }
00218 
00219 int
00220 TAO_SCIOP_Connection_Handler::close_connection (void)
00221 {
00222   return this->close_connection_eh (this);
00223 }
00224 
00225 int
00226 TAO_SCIOP_Connection_Handler::handle_input (ACE_HANDLE h)
00227 {
00228   return this->handle_input_eh (h, this);
00229 }
00230 
00231 int
00232 TAO_SCIOP_Connection_Handler::handle_output (ACE_HANDLE handle)
00233 {
00234   int const result =
00235     this->handle_output_eh (handle, this);
00236 
00237   if (result == -1)
00238     {
00239       this->close_connection ();
00240       return 0;
00241     }
00242 
00243   return result;
00244 }
00245 
00246 int
00247 TAO_SCIOP_Connection_Handler::handle_timeout (const ACE_Time_Value &,
00248                                               const void *)
00249 {
00250   // We don't use this upcall for I/O.  This is only used by the
00251   // Connector to indicate that the connection timedout.  Therefore,
00252   // we should call close().
00253   return this->close ();
00254 }
00255 
00256 int
00257 TAO_SCIOP_Connection_Handler::handle_close (ACE_HANDLE,
00258                                             ACE_Reactor_Mask)
00259 {
00260   ACE_ASSERT (0);
00261   return 0;
00262 }
00263 
00264 int
00265 TAO_SCIOP_Connection_Handler::close (u_long)
00266 {
00267   return this->close_handler ();
00268 }
00269 
00270 int
00271 TAO_SCIOP_Connection_Handler::release_os_resources (void)
00272 {
00273   return this->peer().close ();
00274 }
00275 
00276 int
00277 TAO_SCIOP_Connection_Handler::add_transport_to_cache (void)
00278 {
00279   ACE_INET_Addr addr;
00280 
00281   // Get the peername.
00282   if (this->peer ().get_remote_addr (addr) == -1)
00283     return -1;
00284 
00285   // Construct an  SCIOP_Endpoint object
00286   TAO_SCIOP_Endpoint endpoint (
00287       addr,
00288       this->orb_core()->orb_params()->use_dotted_decimal_addresses ());
00289 
00290   // Construct a property object
00291   TAO_Base_Transport_Property prop (&endpoint);
00292 
00293   TAO::Transport_Cache_Manager &cache =
00294     this->orb_core ()->lane_resources ().transport_cache ();
00295 
00296   // Idle the transport..
00297   return cache.cache_idle_transport (&prop,
00298                                      this->transport ());
00299 
00300 }
00301 
00302 int
00303 TAO_SCIOP_Connection_Handler::process_listen_point_list (
00304     IIOP::ListenPointList &listen_list)
00305 {
00306   // Get the size of the list
00307   CORBA::ULong const len = listen_list.length ();
00308 
00309   for (CORBA::ULong i = 0; i < len; ++ i)
00310     {
00311       IIOP::ListenPoint listen_point = listen_list[i];
00312       ACE_INET_Addr addr (listen_point.port,
00313                           listen_point.host.in ());
00314 
00315       if (TAO_debug_level > 0)
00316         {
00317           ACE_DEBUG ((LM_DEBUG,
00318                       ACE_TEXT("(%P|%t) Listening port [%d] on [%s]\n"),
00319                       listen_point.port,
00320                       ACE_TEXT_CHAR_TO_TCHAR(listen_point.host.in ())));
00321         }
00322 
00323       // Construct an  SCIOP_Endpoint object
00324       TAO_SCIOP_Endpoint endpoint (addr,
00325         this->orb_core()->orb_params()->use_dotted_decimal_addresses ());
00326 
00327       // Construct a property object
00328       TAO_Base_Transport_Property prop (&endpoint);
00329 
00330       // Mark the connection as bidirectional
00331       prop.set_bidir_flag (1);
00332 
00333       // The property for this handler has changed. Recache the
00334       // handler with this property
00335       int const retval = this->transport ()->recache_transport (&prop);
00336       if (retval == -1)
00337         return retval;
00338 
00339       // Make the handler idle and ready for use
00340       this->transport ()->make_idle ();
00341     }
00342 
00343   return 0;
00344 }
00345 
00346 int
00347 TAO_SCIOP_Connection_Handler::set_dscp_codepoint (CORBA::Boolean set_network_priority)
00348 {
00349   int tos = IPDSFIELD_DSCP_DEFAULT << 2;
00350 
00351   if (set_network_priority)
00352     {
00353       TAO_Protocols_Hooks *tph =
00354         this->orb_core ()->get_protocols_hooks ();
00355 
00356       CORBA::Long codepoint =
00357         tph->get_dscp_codepoint ();
00358 
00359       tos = (int)(codepoint) << 2;
00360     }
00361 
00362   if (tos != this->dscp_codepoint_)
00363     {
00364       int const result = this->peer ().set_option (IPPROTO_IP,
00365                                                    IP_TOS,
00366                                                    (int *) &tos ,
00367                                                    (int) sizeof (tos));
00368 
00369       if (TAO_debug_level)
00370         {
00371           ACE_DEBUG ((LM_DEBUG,
00372                       "TAO (%P|%t) - SCIOP_Connection_Handler::"
00373                       "set_dscp_codepoint -> dscp: %x; result: %d; %s\n",
00374                       tos,
00375                       result,
00376                       result == -1 ? "try running as superuser" : ""));
00377         }
00378 
00379       // On successful setting of TOS field.
00380       if (result == 0)
00381         this->dscp_codepoint_ = tos;
00382 
00383     }
00384 
00385   return 0;
00386 }
00387 
00388 TAO_END_VERSIONED_NAMESPACE_DECL
00389 
00390 #endif /* TAO_HAS_SCIOP == 1 */

Generated on Thu Nov 9 13:39:29 2006 for TAO_Strategies by doxygen 1.3.6