TcpConnection.h

Go to the documentation of this file.
00001 /*
00002  *
00003  *
00004  * Distributed under the OpenDDS License.
00005  * See: http://www.opendds.org/license.html
00006  */
00007 
00008 #ifndef OPENDDS_TCPCONNECTION_H
00009 #define OPENDDS_TCPCONNECTION_H
00010 
00011 #include "TcpInst_rch.h"
00012 #ifdef __BORLANDC__
00013 #  include "TcpDataLink.h"
00014 #endif
00015 #include "TcpDataLink_rch.h"
00016 #include "TcpConnection_rch.h"
00017 #include "TcpSendStrategy_rch.h"
00018 #include "TcpReceiveStrategy_rch.h"
00019 #include "TcpReconnectTask.h"
00020 #include "TcpTransport_rch.h"
00021 
00022 #include "dds/DCPS/RcObject.h"
00023 #include "dds/DCPS/PoolAllocator.h"
00024 #include "dds/DCPS/transport/framework/TransportDefs.h"
00025 
00026 #include "ace/SOCK_Stream.h"
00027 #include "ace/Svc_Handler.h"
00028 #include "ace/INET_Addr.h"
00029 #include "ace/Synch_Traits.h"
00030 
00031 OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
00032 
00033 namespace OpenDDS {
00034 namespace DCPS {
00035 
00036 class TcpConnection
00037   : public RcObject
00038   , public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> {
00039 public:
00040 
00041   /// States are used during reconnecting.
00042   enum ReconnectState {
00043     INIT_STATE,
00044     LOST_STATE,
00045     RECONNECTED_STATE,
00046     PASSIVE_WAITING_STATE,
00047     PASSIVE_TIMEOUT_CALLED_STATE
00048   };
00049 
00050   /// Passive side constructor (acceptor)
00051   TcpConnection();
00052 
00053   /// Active side constructor (connector)
00054   TcpConnection(const ACE_INET_Addr& remote_address,
00055                 Priority priority,
00056                 const TcpInst& config);
00057 
00058   virtual ~TcpConnection();
00059 
00060   std::size_t& id();
00061 
00062   /// Protocol setup (handshake) on the active side.
00063   /// The local address is sent to the remote (passive) side to
00064   /// identify ourselves to the remote side.
00065   int active_open();
00066 
00067   /// This will be called by the DataLink (that "owns" us) when
00068   /// the TcpTransport has been told to shutdown(), or when
00069   /// the DataLink finds itself no longer needed, and is
00070   /// "self-releasing".
00071   void disconnect();
00072 
00073   // Note that the acceptor or connector that calls the open() method will pass
00074   // itself in as a void*.
00075   virtual int open(void* arg);
00076 
00077   TcpSendStrategy_rch send_strategy();
00078   TcpReceiveStrategy_rch receive_strategy();
00079 
00080   /// We pass this "event" along to the receive_strategy.
00081   virtual int handle_input(ACE_HANDLE);
00082 
00083   /// Handle back pressure when sending.
00084   virtual int handle_output(ACE_HANDLE);
00085 
00086   virtual int close(u_long);
00087   virtual int handle_close(ACE_HANDLE, ACE_Reactor_Mask);
00088 
00089   void set_sock_options(const TcpInst* tcp_config);
00090 
00091   int reconnect(bool on_new_association = false);
00092 
00093   /// Return true if the object represents the connector side, otherwise
00094   /// it's the acceptor side. The acceptor/connector role is not changed
00095   /// when re-establishing the connection.
00096   bool is_connector() const;
00097 
00098   /// Return true if connection is connected.
00099   bool is_connected() const;
00100 
00101   void transfer(TcpConnection* connection);
00102 
00103   int handle_timeout(const ACE_Time_Value &tv, const void *arg);
00104 
00105   /// Cache the reference to the datalink object for lost connection
00106   /// callbacks.
00107   void set_datalink(const TcpDataLink_rch& link);
00108 
00109   void notify_lost_on_backpressure_timeout();
00110 
00111   ACE_INET_Addr get_remote_address();
00112 
00113   /// Reconnect initiated by send strategy
00114   void relink_from_send(bool do_suspend);
00115 
00116   /// Reconnect initiated by receive strategy
00117   void relink_from_recv(bool do_suspend);
00118 
00119   /// Called by the reconnect task to inform us that the
00120   /// link & any associated data can be torn down.
00121   /// This call is done with no DCPS/transport locks held.
00122   bool tear_link();
00123 
00124   void shutdown();
00125 
00126   /// Access TRANSPORT_PRIORITY.value policy value if set.
00127   Priority& transport_priority();
00128   Priority  transport_priority() const;
00129 
00130   virtual ACE_Event_Handler::Reference_Count add_reference();
00131   virtual ACE_Event_Handler::Reference_Count remove_reference();
00132 
00133   OPENDDS_POOL_ALLOCATION_FWD
00134 
00135 private:
00136 
00137   /// Attempt an active connection establishment to the remote address.
00138   /// The local address is sent to the remote (passive) side to
00139   /// identify ourselves to the remote side.
00140   /// Note this method is not thread protected. The caller need acquire
00141   /// the reconnect_lock_ before calling this function.
00142   int active_establishment(bool initiate_connect = true);
00143 
00144   int active_reconnect_i();
00145   int passive_reconnect_i();
00146   int active_reconnect_on_new_association();
00147 
00148   /// During the connection setup phase, the passive side sets passive_setup_,
00149   /// redirecting handle_input() events here (there is no recv strategy yet).
00150   int handle_setup_input(ACE_HANDLE h);
00151 
00152   const std::string& config_name() const;
00153 
00154   void spawn_reconnect_thread();
00155   static ACE_THR_FUNC_RETURN reconnect_thread_fun(void* conn);
00156 
00157 
00158   typedef ACE_SYNCH_MUTEX     LockType;
00159   typedef ACE_Guard<LockType> GuardType;
00160 
00161   /// Lock to avoid the reconnect() called multiple times when
00162   /// both send() and recv() fail.
00163   LockType  reconnect_lock_;
00164 
00165   /// Flag indicates if connected or disconnected. It's set to true
00166   /// when actively connecting or passively accepting succeeds and set
00167   /// to false whenever the peer stream is closed.
00168   ACE_Atomic_Op<ACE_SYNCH_MUTEX, bool>  connected_;
00169 
00170   /// Flag indicate this connection object is the connector or acceptor.
00171   bool is_connector_;
00172 
00173   /// Remote address.
00174   ACE_INET_Addr remote_address_;
00175 
00176   /// Local address.
00177   ACE_INET_Addr local_address_;
00178 
00179   /// The configuration used by this connection.
00180   const TcpInst* tcp_config_;
00181 
00182   /// Datalink object which is needed for connection lost callback.
00183   TcpDataLink_rch link_;
00184 
00185   /// The id of the scheduled timer. The timer is scheduled to check if the connection
00186   /// is re-established during the passive_reconnect_duration_. This id controls
00187   /// that the timer is just scheduled once when there are multiple threads detect
00188   /// the lost connection.
00189   int passive_reconnect_timer_id_;
00190 
00191   /// The state indicates each step of the reconnecting.
00192   ReconnectState reconnect_state_;
00193 
00194   /// Last time the connection is re-established.
00195   ACE_Time_Value last_reconnect_attempted_;
00196 
00197   /// TRANSPORT_PRIORITY.value policy value.
00198   Priority transport_priority_;
00199 
00200   /// shutdown flag
00201   bool shutdown_;
00202 
00203   bool passive_setup_;
00204   ACE_Message_Block passive_setup_buffer_;
00205   TcpTransport* transport_during_setup_;
00206 
00207   /// Small unique identifying value.
00208   std::size_t id_;
00209   ACE_thread_t reconnect_thread_;
00210 
00211   /// Get name of the current reconnect state as a string.
00212   OPENDDS_STRING reconnect_state_string() const;
00213 };
00214 
00215 } // namespace DCPS
00216 } // namespace OpenDDS
00217 
00218 OPENDDS_END_VERSIONED_NAMESPACE_DECL
00219 
00220 #if defined (__ACE_INLINE__)
00221 #include "TcpConnection.inl"
00222 #endif /* __ACE_INLINE__ */
00223 
00224 #endif  /* OPENDDS_TCPCONNECTION_H */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 10 Aug 2018 for OpenDDS by  doxygen 1.6.1