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            "$Id: SCIOP_Connection_Handler.cpp 78950 2007-07-19 11:53:18Z johnnyw $")
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   : TAO_SCIOP_SVC_HANDLER (orb_core->thr_mgr (), 0, 0),
00053     TAO_Connection_Handler (orb_core),
00054     dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
00055 {
00056   TAO_SCIOP_Transport* specific_transport = 0;
00057   ACE_NEW (specific_transport,
00058            TAO_SCIOP_Transport (this, orb_core));
00059 
00060   // store this pointer (indirectly increment ref count)
00061   this->transport (specific_transport);
00062 }
00063 
00064 TAO_SCIOP_Connection_Handler::~TAO_SCIOP_Connection_Handler (void)
00065 {
00066   delete this->transport ();
00067   int const result =
00068     this->release_os_resources ();
00069 
00070   if (result == -1 && TAO_debug_level)
00071     {
00072       ACE_ERROR ((LM_ERROR,
00073                   ACE_TEXT("TAO (%P|%t) - SCIOP_Connection_Handler::")
00074                   ACE_TEXT("~scIOP_Connection_Handler, ")
00075                   ACE_TEXT("release_os_resources() failed %m\n")));
00076     }
00077 }
00078 
00079 int
00080 TAO_SCIOP_Connection_Handler::open_handler (void *v)
00081 {
00082   return this->open (v);
00083 }
00084 
00085 int
00086 TAO_SCIOP_Connection_Handler::open (void*)
00087 {
00088   if (this->shared_open() == -1)
00089     return -1;
00090 
00091   TAO_SCIOP_Protocol_Properties protocol_properties;
00092 
00093   // Initialize values from ORB params.
00094   protocol_properties.send_buffer_size_ =
00095     this->orb_core ()->orb_params ()->sock_sndbuf_size ();
00096   protocol_properties.recv_buffer_size_ =
00097     this->orb_core ()->orb_params ()->sock_rcvbuf_size ();
00098   protocol_properties.no_delay_ =
00099     this->orb_core ()->orb_params ()->nodelay ();
00100 
00101   TAO_Protocols_Hooks *tph = this->orb_core ()->get_protocols_hooks ();
00102 
00103   if (tph != 0)
00104     {
00105       try
00106         {
00107           if (this->transport ()->opened_as () == TAO::TAO_CLIENT_ROLE)
00108             {
00109               tph->client_protocol_properties_at_orb_level (protocol_properties);
00110             }
00111           else
00112             {
00113               tph->server_protocol_properties_at_orb_level (protocol_properties);
00114             }
00115         }
00116       catch (const ::CORBA::Exception& ex)
00117         {
00118           return -1;
00119         }
00120     }
00121 
00122   if (this->set_socket_option (this->peer (),
00123                                protocol_properties.send_buffer_size_,
00124                                protocol_properties.recv_buffer_size_) == -1)
00125     return -1;
00126 
00127 #if !defined (ACE_LACKS_TCP_NODELAY)
00128   if (this->peer ().set_option (IPPROTO_SCTP,
00129                                 SCTP_NODELAY,
00130                                 (void *) &protocol_properties.no_delay_,
00131                                 sizeof (protocol_properties.no_delay_)) == -1)
00132     return -1;
00133 #endif /* ! ACE_LACKS_TCP_NODELAY */
00134 
00135   if (this->transport ()->wait_strategy ()->non_blocking ())
00136     {
00137       if (this->peer ().enable (ACE_NONBLOCK) == -1)
00138         return -1;
00139     }
00140 
00141   // Called by the <Strategy_Acceptor> when the handler is
00142   // completely connected.
00143 
00144   ACE_INET_Addr remote_addr;
00145   if (this->peer ().get_remote_addr (remote_addr) == -1)
00146     return -1;
00147 
00148   ACE_INET_Addr local_addr;
00149   if (this->peer ().get_local_addr (local_addr) == -1)
00150     return -1;
00151 
00152   if (TAO_debug_level > 2)
00153     ACE_DEBUG ((LM_DEBUG,
00154                 ACE_TEXT("TAO(%P|%t) - SCIOP_Connection_Handler::open, ")
00155                 ACE_TEXT("The local addr is (%s) \n"),
00156                 local_addr. get_host_addr ()));
00157 
00158   if (local_addr.get_ip_address () == remote_addr.get_ip_address ()
00159       && local_addr.get_port_number () == remote_addr.get_port_number ())
00160     {
00161       if (TAO_debug_level > 0)
00162         {
00163           ACE_TCHAR remote_as_string[MAXHOSTNAMELEN + 16];
00164           ACE_TCHAR local_as_string[MAXHOSTNAMELEN + 16];
00165 
00166           (void) remote_addr.addr_to_string (remote_as_string,
00167                                              sizeof(remote_as_string));
00168           (void) local_addr.addr_to_string (local_as_string,
00169                                             sizeof(local_as_string));
00170           ACE_ERROR ((LM_ERROR,
00171                       ACE_TEXT("TAO(%P|%t) - TAO_SCIOP_Connection_Handler::open, ")
00172                       ACE_TEXT("Holy Cow! The remote addr and ")
00173                       ACE_TEXT("local addr are identical (%s == %s)\n"),
00174                       remote_as_string, local_as_string));
00175         }
00176       return -1;
00177     }
00178 
00179   if (TAO_debug_level > 0)
00180     {
00181       ACE_TCHAR client[MAXHOSTNAMELEN + 16];
00182 
00183       // Verify that we can resolve the peer hostname.
00184       if (remote_addr.addr_to_string (client, sizeof (client)) == -1)
00185         return -1;
00186 
00187       ACE_DEBUG ((LM_DEBUG,
00188                   ACE_TEXT ("TAO (%P|%t) - SCIOP_Connection_Handler::open, SCIOP ")
00189                   ACE_TEXT ("connection to peer <%s> on %d\n"),
00190                   client, this->peer ().get_handle ()));
00191     }
00192 
00193   // Set that the transport is now connected, if fails we return -1
00194   // Use C-style cast b/c otherwise we get warnings on lots of
00195   // compilers
00196   if (!this->transport ()->post_open ((size_t) this->get_handle ()))
00197     return -1;
00198 
00199   this->state_changed (TAO_LF_Event::LFS_SUCCESS,
00200                        this->orb_core ()->leader_follower ());
00201 
00202   return 0;
00203 }
00204 
00205 int
00206 TAO_SCIOP_Connection_Handler::resume_handler (void)
00207 {
00208   return ACE_Event_Handler::ACE_APPLICATION_RESUMES_HANDLER;
00209 }
00210 
00211 int
00212 TAO_SCIOP_Connection_Handler::close_connection (void)
00213 {
00214   return this->close_connection_eh (this);
00215 }
00216 
00217 int
00218 TAO_SCIOP_Connection_Handler::handle_input (ACE_HANDLE h)
00219 {
00220   return this->handle_input_eh (h, this);
00221 }
00222 
00223 int
00224 TAO_SCIOP_Connection_Handler::handle_output (ACE_HANDLE handle)
00225 {
00226   int const result =
00227     this->handle_output_eh (handle, this);
00228 
00229   if (result == -1)
00230     {
00231       this->close_connection ();
00232       return 0;
00233     }
00234 
00235   return result;
00236 }
00237 
00238 int
00239 TAO_SCIOP_Connection_Handler::handle_timeout (const ACE_Time_Value &,
00240                                               const void *)
00241 {
00242   // Using this to ensure this instance will be deleted (if necessary)
00243   // only after reset_state(). Without this, when this refcount==1 -
00244   // the call to close() will cause a call to remove_reference() which
00245   // will delete this. At that point this->reset_state() is in no
00246   // man's territory and that causes SEGV on some platforms (Windows!)
00247 
00248   TAO_Auto_Reference<TAO_SCIOP_Connection_Handler> safeguard (*this);
00249 
00250   // NOTE: Perhaps not the best solution, as it feels like the upper
00251   // layers should be responsible for this?
00252 
00253   // We don't use this upcall for I/O.  This is only used by the
00254   // Connector to indicate that the connection timedout.  Therefore,
00255   // we should call close().
00256   int ret = this->close ();
00257   this->reset_state (TAO_LF_Event::LFS_TIMEOUT);
00258   return ret;
00259 }
00260 
00261 int
00262 TAO_SCIOP_Connection_Handler::handle_close (ACE_HANDLE,
00263                                             ACE_Reactor_Mask)
00264 {
00265   ACE_ASSERT (0);
00266   return 0;
00267 }
00268 
00269 int
00270 TAO_SCIOP_Connection_Handler::close (u_long)
00271 {
00272   return this->close_handler ();
00273 }
00274 
00275 int
00276 TAO_SCIOP_Connection_Handler::release_os_resources (void)
00277 {
00278   return this->peer().close ();
00279 }
00280 
00281 int
00282 TAO_SCIOP_Connection_Handler::add_transport_to_cache (void)
00283 {
00284   ACE_INET_Addr addr;
00285 
00286   // Get the peername.
00287   if (this->peer ().get_remote_addr (addr) == -1)
00288     return -1;
00289 
00290   // Construct an  SCIOP_Endpoint object
00291   TAO_SCIOP_Endpoint endpoint (
00292       addr,
00293       this->orb_core()->orb_params()->use_dotted_decimal_addresses ());
00294 
00295   // Construct a property object
00296   TAO_Base_Transport_Property prop (&endpoint);
00297 
00298   TAO::Transport_Cache_Manager &cache =
00299     this->orb_core ()->lane_resources ().transport_cache ();
00300 
00301   // Idle the transport..
00302   return cache.cache_idle_transport (&prop,
00303                                      this->transport ());
00304 
00305 }
00306 
00307 int
00308 TAO_SCIOP_Connection_Handler::process_listen_point_list (
00309     IIOP::ListenPointList &listen_list)
00310 {
00311   // Get the size of the list
00312   CORBA::ULong const len = listen_list.length ();
00313 
00314   for (CORBA::ULong i = 0; i < len; ++ i)
00315     {
00316       IIOP::ListenPoint listen_point = listen_list[i];
00317       ACE_INET_Addr addr (listen_point.port,
00318                           listen_point.host.in ());
00319 
00320       if (TAO_debug_level > 0)
00321         {
00322           ACE_DEBUG ((LM_DEBUG,
00323                       ACE_TEXT("(%P|%t) Listening port [%d] on [%s]\n"),
00324                       listen_point.port,
00325                       ACE_TEXT_CHAR_TO_TCHAR(listen_point.host.in ())));
00326         }
00327 
00328       // Construct an  SCIOP_Endpoint object
00329       TAO_SCIOP_Endpoint endpoint (addr,
00330         this->orb_core()->orb_params()->use_dotted_decimal_addresses ());
00331 
00332       // Construct a property object
00333       TAO_Base_Transport_Property prop (&endpoint);
00334 
00335       // Mark the connection as bidirectional
00336       prop.set_bidir_flag (1);
00337 
00338       // The property for this handler has changed. Recache the
00339       // handler with this property
00340       int const retval = this->transport ()->recache_transport (&prop);
00341       if (retval == -1)
00342         return retval;
00343 
00344       // Make the handler idle and ready for use
00345       this->transport ()->make_idle ();
00346     }
00347 
00348   return 0;
00349 }
00350 
00351 int
00352 TAO_SCIOP_Connection_Handler::set_tos (int tos)
00353 {
00354   if (tos != this->dscp_codepoint_)
00355     {
00356       int const result = this->peer ().set_option (IPPROTO_IP,
00357                                                    IP_TOS,
00358                                                    (int *) &tos ,
00359                                                    (int) sizeof (tos));
00360 
00361       if (TAO_debug_level)
00362         {
00363           ACE_DEBUG ((LM_DEBUG,
00364                       "TAO (%P|%t) - SCIOP_Connection_Handler::"
00365                       "set_dscp_codepoint -> dscp: %x; result: %d; %s\n",
00366                       tos,
00367                       result,
00368                       result == -1 ? "try running as superuser" : ""));
00369         }
00370 
00371       // On successful setting of TOS field.
00372       if (result == 0)
00373         this->dscp_codepoint_ = tos;
00374 
00375     }
00376 
00377   return 0;
00378 }
00379 
00380 int
00381 TAO_SCIOP_Connection_Handler::set_dscp_codepoint (CORBA::Long dscp)
00382 {
00383   int tos = IPDSFIELD_DSCP_DEFAULT << 2;
00384   tos = (int)(dscp) << 2;
00385   this->set_tos (tos);
00386   return 0;
00387 }
00388 
00389 int
00390 TAO_SCIOP_Connection_Handler::set_dscp_codepoint (CORBA::Boolean set_network_priority)
00391 {
00392   int tos = IPDSFIELD_DSCP_DEFAULT << 2;
00393 
00394   if (set_network_priority)
00395     {
00396       TAO_Protocols_Hooks *tph = this->orb_core ()->get_protocols_hooks ();
00397 
00398       if (tph != 0)
00399         {
00400           CORBA::Long codepoint = tph->get_dscp_codepoint ();
00401           tos = (int)(codepoint) << 2;
00402           this->set_tos (tos);
00403         }
00404     }
00405 
00406   return 0;
00407 }
00408 
00409 TAO_END_VERSIONED_NAMESPACE_DECL
00410 
00411 #endif /* TAO_HAS_SCIOP == 1 */

Generated on Tue Feb 2 17:47:18 2010 for TAO_Strategies by  doxygen 1.4.7