From 3fd6f45051220ed8d912d2ee0fe6ac061ebdc47f Mon Sep 17 00:00:00 2001 From: Natale Patriciello Date: Fri, 16 Oct 2015 10:38:30 -0700 Subject: [PATCH] Introduction of the ACK state machine This commits contains only the definition (in other words, the interface) of the ACK state machine, where the design is taken from Linux v4.0. The state machine allows to define congestion situations avoiding the use of boolean state variables. --- src/internet/model/tcp-socket-base.cc | 17 ++++++++-- src/internet/model/tcp-socket-base.h | 46 +++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/internet/model/tcp-socket-base.cc b/src/internet/model/tcp-socket-base.cc index 66a49b9fd..b72dfc32c 100644 --- a/src/internet/model/tcp-socket-base.cc +++ b/src/internet/model/tcp-socket-base.cc @@ -138,6 +138,10 @@ TcpSocketBase::GetTypeId (void) "TCP state", MakeTraceSourceAccessor (&TcpSocketBase::m_state), "ns3::TcpStatesTracedValueCallback") + .AddTraceSource ("AckState", + "TCP ACK machine state", + MakeTraceSourceAccessor (&TcpSocketBase::m_ackState), + "ns3::TcpAckStatesTracedValueCallback") .AddTraceSource ("RWND", "Remote side's flow control window", MakeTraceSourceAccessor (&TcpSocketBase::m_rWnd), @@ -190,7 +194,8 @@ TcpSocketBase::TcpSocketBase (void) m_sndScaleFactor (0), m_rcvScaleFactor (0), m_timestampEnabled (true), - m_timestampToEcho (0) + m_timestampToEcho (0), + m_ackState (OPEN) { NS_LOG_FUNCTION (this); @@ -237,7 +242,8 @@ TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock) m_sndScaleFactor (sock.m_sndScaleFactor), m_rcvScaleFactor (sock.m_rcvScaleFactor), m_timestampEnabled (sock.m_timestampEnabled), - m_timestampToEcho (sock.m_timestampToEcho) + m_timestampToEcho (sock.m_timestampToEcho), + m_ackState (sock.m_ackState) { NS_LOG_FUNCTION (this); @@ -2784,6 +2790,13 @@ TcpSocketBase::GetRxBuffer (void) const return m_rxBuffer; } +const char* const +TcpSocketBase::TcpAckStateName[TcpSocketBase::LAST_ACKSTATE] = +{ + "OPEN", "DISORDER", "CWR", "RECOVERY", + "LOSS" +}; + //RttHistory methods RttHistory::RttHistory (SequenceNumber32 s, uint32_t c, Time t) diff --git a/src/internet/model/tcp-socket-base.h b/src/internet/model/tcp-socket-base.h index 20627d55d..6566aa163 100644 --- a/src/internet/model/tcp-socket-base.h +++ b/src/internet/model/tcp-socket-base.h @@ -166,6 +166,40 @@ public: */ Ptr GetRxBuffer (void) const; + /** + * \brief Definition of the ACK state machine + * + * The design of this state machine is taken from Linux v4.0, but it has been + * maintained in the Linux mainline from ages. It basically avoids to maintain + * a lot of boolean variables, and it allows to check the transitions from + * different algorithm in a cleaner way. + * + * These states represent the situation from a congestion control point of view: + * in fact, apart the OPEN state, the other states represent a situation in + * which there is a congestion, and different actions should be taken, + * depending on the case. + * + * \see ReceivedAck + * \see Retransmit + */ + typedef enum + { + OPEN, /**< Normal state, no dubious events */ + DISORDER, /**< In all the respects it is "Open", + * but requires a bit more attention. It is entered when + * we see some SACKs or dupacks. It is split of "Open" */ + CWR, /**< cWnd was reduced due to some Congestion Notification event. + * It can be ECN, ICMP source quench, local device congestion. + * Not used in NS-3 right now. */ + RECOVERY, /**< CWND was reduced, we are fast-retransmitting. */ + LOSS, /**< CWND was reduced due to RTO timeout or SACK reneging. */ + LAST_ACKSTATE /**< Used only in debug messages */ + } TcpAckState_t; + + /** + * \brief Literal names of TCP states for use in log messages + */ + static const char* const TcpAckStateName[TcpSocketBase::LAST_ACKSTATE]; // Necessary implementations of null functions from ns3::Socket virtual enum SocketErrno GetErrno (void) const; // returns m_errno @@ -774,8 +808,20 @@ protected: uint32_t m_timestampToEcho; //!< Timestamp to echo EventId m_sendPendingDataEvent; //!< micro-delay event to send pending data + + TracedValue m_ackState; //!< State in the ACK state machine }; +/** + * \ingroup tcp + * TracedValue Callback signature for TcpAckState_t + * + * \param [in] oldValue original value of the traced variable + * \param [in] newValue new value of the traced variable + */ +typedef void (* TcpAckStatesTracedValueCallback)(const TcpSocketBase::TcpAckState_t oldValue, + const TcpSocketBase::TcpAckState_t newValue); + } // namespace ns3 #endif /* TCP_SOCKET_BASE_H */