DIOP_Connection_Handler.cpp

Go to the documentation of this file.
00001 // $Id: DIOP_Connection_Handler.cpp 78975 2007-07-20 15:17:19Z vridosh $
00002 
00003 #include "tao/Strategies/DIOP_Connection_Handler.h"
00004 
00005 #if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
00006 
00007 #include "tao/Timeprobe.h"
00008 #include "tao/debug.h"
00009 #include "tao/ORB_Core.h"
00010 #include "tao/ORB.h"
00011 #include "tao/CDR.h"
00012 #include "tao/Server_Strategy_Factory.h"
00013 #include "tao/Transport_Cache_Manager.h"
00014 #include "tao/Thread_Lane_Resources.h"
00015 #include "tao/Base_Transport_Property.h"
00016 #include "tao/Protocols_Hooks.h"
00017 #include "tao/Resume_Handle.h"
00018 
00019 #include "tao/Strategies/DIOP_Transport.h"
00020 #include "tao/Strategies/DIOP_Endpoint.h"
00021 
00022 #include "ace/os_include/netinet/os_tcp.h"
00023 #include "ace/os_include/os_netdb.h"
00024 
00025 ACE_RCSID(tao, DIOP_Connect, "$Id: DIOP_Connection_Handler.cpp 78975 2007-07-20 15:17:19Z vridosh $")
00026 
00027 
00028 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00029 
00030 TAO_DIOP_Connection_Handler::TAO_DIOP_Connection_Handler (ACE_Thread_Manager *t)
00031   : TAO_DIOP_SVC_HANDLER (t, 0 , 0),
00032     TAO_Connection_Handler (0),
00033     dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
00034 {
00035   // This constructor should *never* get called, it is just here to
00036   // make the compiler happy: the default implementation of the
00037   // Creation_Strategy requires a constructor with that signature, we
00038   // don't use that implementation, but some (most?) compilers
00039   // instantiate it anyway.
00040   ACE_ASSERT (0);
00041 }
00042 
00043 TAO_DIOP_Connection_Handler::TAO_DIOP_Connection_Handler (TAO_ORB_Core *orb_core)
00044   : TAO_DIOP_SVC_HANDLER (orb_core->thr_mgr (), 0, 0),
00045     TAO_Connection_Handler (orb_core),
00046     dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
00047 {
00048   TAO_DIOP_Transport* specific_transport = 0;
00049   ACE_NEW (specific_transport,
00050            TAO_DIOP_Transport (this, orb_core));
00051 
00052   // store this pointer (indirectly increment ref count)
00053   this->transport (specific_transport);
00054 }
00055 
00056 TAO_DIOP_Connection_Handler::~TAO_DIOP_Connection_Handler (void)
00057 {
00058   delete this->transport ();
00059   int const result =
00060     this->release_os_resources ();
00061 
00062   if (result == -1 && TAO_debug_level)
00063     {
00064       ACE_ERROR ((LM_ERROR,
00065                   ACE_TEXT ("TAO (%P|%t) - DIOP_Connection_Handler::")
00066                   ACE_TEXT ("~DIOP_Connection_Handler, ")
00067                   ACE_TEXT ("release_os_resources() failed %m\n")));
00068     }
00069 }
00070 
00071 // DIOP Additions - Begin
00072 const ACE_INET_Addr &
00073 TAO_DIOP_Connection_Handler::addr (void)
00074 {
00075   return this->addr_;
00076 }
00077 
00078 void
00079 TAO_DIOP_Connection_Handler::addr (const ACE_INET_Addr &addr)
00080 {
00081   this->addr_ = addr;
00082 }
00083 
00084 const ACE_INET_Addr &
00085 TAO_DIOP_Connection_Handler::local_addr (void)
00086 {
00087   return this->local_addr_;
00088 }
00089 
00090 void
00091 TAO_DIOP_Connection_Handler::local_addr (const ACE_INET_Addr &addr)
00092 {
00093   this->local_addr_ = addr;
00094 }
00095 // DIOP Additions - End
00096 
00097 int
00098 TAO_DIOP_Connection_Handler::open_handler (void *v)
00099 {
00100   return this->open (v);
00101 }
00102 
00103 int
00104 TAO_DIOP_Connection_Handler::open (void*)
00105 {
00106   TAO_DIOP_Protocol_Properties protocol_properties;
00107 
00108   // Initialize values from ORB params.
00109   protocol_properties.send_buffer_size_ =
00110     this->orb_core ()->orb_params ()->sock_sndbuf_size ();
00111   protocol_properties.recv_buffer_size_ =
00112     this->orb_core ()->orb_params ()->sock_rcvbuf_size ();
00113 
00114   TAO_Protocols_Hooks *tph = this->orb_core ()->get_protocols_hooks ();
00115 
00116   if (tph != 0)
00117     {
00118       try
00119         {
00120           if (this->transport ()->opened_as () == TAO::TAO_CLIENT_ROLE)
00121             {
00122               tph->client_protocol_properties_at_orb_level (protocol_properties);
00123             }
00124           else
00125             {
00126               tph->server_protocol_properties_at_orb_level (protocol_properties);
00127             }
00128         }
00129       catch (const ::CORBA::Exception&)
00130         {
00131           return -1;
00132         }
00133     }
00134 
00135   this->peer ().open (this->local_addr_);
00136 
00137   if (this->set_socket_option (this->peer (),
00138                                protocol_properties.send_buffer_size_,
00139                                protocol_properties.recv_buffer_size_) == -1)
00140     return -1;
00141 
00142   if (TAO_debug_level > 5)
00143   {
00144      ACE_DEBUG ((LM_DEBUG,
00145                  ACE_TEXT("TAO (%P|%t) - DIOP_Connection_Handler::open, ")
00146                  ACE_TEXT("listening on: <%s:%u>\n"),
00147                  ACE_TEXT_CHAR_TO_TCHAR (this->local_addr_.get_host_name ()),
00148                  this->local_addr_.get_port_number ()));
00149   }
00150 
00151   // Set that the transport is now connected, if fails we return -1
00152   // Use C-style cast b/c otherwise we get warnings on lots of
00153   // compilers
00154   if (!this->transport ()->post_open ((size_t) this->peer ().get_handle ()))
00155     return -1;
00156 
00157   this->state_changed (TAO_LF_Event::LFS_SUCCESS,
00158                        this->orb_core ()->leader_follower ());
00159 
00160   return 0;
00161 }
00162 
00163 int
00164 TAO_DIOP_Connection_Handler::open_server (void)
00165 {
00166   TAO_DIOP_Protocol_Properties protocol_properties;
00167 
00168   // Initialize values from ORB params.
00169   protocol_properties.send_buffer_size_ =
00170     this->orb_core ()->orb_params ()->sock_sndbuf_size ();
00171   protocol_properties.recv_buffer_size_ =
00172     this->orb_core ()->orb_params ()->sock_rcvbuf_size ();
00173 
00174   TAO_Protocols_Hooks *tph = this->orb_core ()->get_protocols_hooks ();
00175 
00176   if (tph != 0)
00177     {
00178       try
00179         {
00180           if (this->transport ()->opened_as () == TAO::TAO_CLIENT_ROLE)
00181             {
00182               tph->client_protocol_properties_at_orb_level (protocol_properties);
00183             }
00184           else
00185             {
00186               tph->server_protocol_properties_at_orb_level (protocol_properties);
00187             }
00188         }
00189       catch (const ::CORBA::Exception&)
00190         {
00191           return -1;
00192         }
00193     }
00194 
00195   this->peer ().open (this->local_addr_);
00196 
00197   if (this->set_socket_option (this->peer (),
00198                                protocol_properties.send_buffer_size_,
00199                                protocol_properties.recv_buffer_size_) == -1)
00200     return -1;
00201 
00202   if (TAO_debug_level > 5)
00203     {
00204       ACE_DEBUG ((LM_DEBUG,
00205                   ACE_TEXT("TAO (%P|%t) - DIOP_Connection_Handler::open_server, ")
00206                   ACE_TEXT("listening on %s:%d\n"),
00207                   ACE_TEXT_CHAR_TO_TCHAR (this->local_addr_.get_host_name ()),
00208                   this->local_addr_.get_port_number ()
00209                 ));
00210     }
00211 
00212   this->transport ()->id ((size_t) this->peer ().get_handle ());
00213 
00214   return 0;
00215 }
00216 
00217 int
00218 TAO_DIOP_Connection_Handler::resume_handler (void)
00219 {
00220   return ACE_Event_Handler::ACE_APPLICATION_RESUMES_HANDLER;
00221 }
00222 
00223 int
00224 TAO_DIOP_Connection_Handler::close_connection (void)
00225 {
00226   return this->close_connection_eh (this);
00227 }
00228 
00229 int
00230 TAO_DIOP_Connection_Handler::handle_input (ACE_HANDLE h)
00231 {
00232   return this->handle_input_eh (h, this);
00233 }
00234 
00235 int
00236 TAO_DIOP_Connection_Handler::handle_output (ACE_HANDLE handle)
00237 {
00238   int result =
00239     this->handle_output_eh (handle, this);
00240 
00241   if (result == -1)
00242     {
00243       this->close_connection ();
00244       return 0;
00245     }
00246 
00247   return result;
00248 }
00249 
00250 int
00251 TAO_DIOP_Connection_Handler::handle_timeout (const ACE_Time_Value &,
00252                                              const void *)
00253 {
00254   // We don't use this upcall from the Reactor.  However, we should
00255   // override this since the base class returns -1 which will result
00256   // in handle_close() getting called.
00257   return 0;
00258 }
00259 
00260 int
00261 TAO_DIOP_Connection_Handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask)
00262 {
00263   // No asserts here since the handler is registered with the Reactor
00264   // and the handler ownership is given to the Reactor.  When the
00265   // Reactor closes, it will call handle_close() on the handler.  It
00266   // is however important to overwrite handle_close() to do nothing
00267   // since the base class does too much.
00268   return 0;
00269 }
00270 
00271 int
00272 TAO_DIOP_Connection_Handler::close (u_long)
00273 {
00274   return this->close_handler ();
00275 }
00276 
00277 int
00278 TAO_DIOP_Connection_Handler::release_os_resources (void)
00279 {
00280   return this->peer ().close ();
00281 }
00282 
00283 int
00284 TAO_DIOP_Connection_Handler::add_transport_to_cache (void)
00285 {
00286   ACE_INET_Addr addr;
00287 
00288   // This function is called by the acceptor to add this
00289   // transport to the transport cache.  This is really
00290   // important for proper shutdown.  The address used
00291   // is irrelevent, since DIOP is connectionless.
00292 
00293   // Construct a DIOP_Endpoint object.
00294   TAO_DIOP_Endpoint endpoint (
00295       addr,
00296       this->orb_core ()->orb_params ()->cache_incoming_by_dotted_decimal_address ());
00297 
00298   // Construct a property object
00299   TAO_Base_Transport_Property prop (&endpoint);
00300 
00301   // Add the handler to Cache
00302   return this->orb_core ()->lane_resources ()
00303     .transport_cache ().cache_transport (&prop, this->transport ());
00304 }
00305 
00306 int
00307 TAO_DIOP_Connection_Handler::set_tos (int tos)
00308 {
00309   if (tos != this->dscp_codepoint_)
00310     {
00311       int result = 0;
00312 #if defined (ACE_HAS_IPV6)
00313       ACE_INET_Addr local_addr;
00314       if (this->peer ().get_local_addr (local_addr) == -1)
00315         return -1;
00316       else if (local_addr.get_type () == AF_INET6)
00317 # if !defined (IPV6_TCLASS)
00318         // IPv6 defines option IPV6_TCLASS for specifying traffic class/priority
00319         // but not many implementations yet (very new;-).
00320         {
00321           if (TAO_debug_level)
00322             {
00323               ACE_DEBUG ((LM_DEBUG,
00324                           "TAO (%P|%t) - DIOP_Connection_Handler::"
00325                           "set_dscp_codepoint -> IPV6_TCLASS not supported yet\n"));
00326             }
00327           return 0;
00328         }
00329 # else /* !IPV6_TCLASS */
00330         result = this->peer ().set_option (IPPROTO_IPV6,
00331                                            IPV6_TCLASS,
00332                                            (int *) &tos ,
00333                                            (int) sizeof (tos));
00334       else
00335 # endif /* IPV6_TCLASS */
00336 #endif /* ACE_HAS_IPV6 */
00337       result = this->peer ().set_option (IPPROTO_IP,
00338                                          IP_TOS,
00339                                          (int *) &tos ,
00340                                          (int) sizeof (tos));
00341 
00342       if (TAO_debug_level)
00343         {
00344           ACE_DEBUG ((LM_DEBUG,
00345                       "TAO (%P|%t) - DIOP_Connection_Handler::"
00346                       "set_dscp_codepoint, dscp: %x; result: %d; %s\n",
00347                       tos,
00348                       result,
00349                       result == -1 ? "try running as superuser" : ""));
00350         }
00351 
00352       // On successful setting of TOS field.
00353       if (result == 0)
00354         this->dscp_codepoint_ = tos;
00355     }
00356   return 0;
00357 }
00358 
00359 int
00360 TAO_DIOP_Connection_Handler::set_dscp_codepoint (CORBA::Long dscp)
00361 {
00362   int tos = IPDSFIELD_DSCP_DEFAULT << 2;
00363   tos = (int)(dscp) << 2;
00364   this->set_tos (tos);
00365   return 0;
00366 }
00367 
00368 int
00369 TAO_DIOP_Connection_Handler::set_dscp_codepoint (CORBA::Boolean set_network_priority)
00370 {
00371   int tos = IPDSFIELD_DSCP_DEFAULT << 2;
00372 
00373   if (set_network_priority)
00374     {
00375       TAO_Protocols_Hooks *tph = this->orb_core ()->get_protocols_hooks ();
00376 
00377       if (tph != 0)
00378         {
00379           CORBA::Long codepoint = tph->get_dscp_codepoint ();
00380 
00381           tos = (int)(codepoint) << 2;
00382           this->set_tos (tos);
00383         }
00384     }
00385   return 0;
00386 }
00387 
00388 TAO_END_VERSIONED_NAMESPACE_DECL
00389 
00390 #endif /* TAO_HAS_DIOP && TAO_HAS_DIOP != 0 */

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