diff --git a/src/internet/model/tcp-dctcp.cc b/src/internet/model/tcp-dctcp.cc index 49298c85a..974c39076 100644 --- a/src/internet/model/tcp-dctcp.cc +++ b/src/internet/model/tcp-dctcp.cc @@ -21,7 +21,7 @@ #include "tcp-dctcp.h" #include "ns3/log.h" -#include "math.h" +#include "ns3/abort.h" #include "ns3/tcp-socket-state.h" namespace ns3 { @@ -44,13 +44,17 @@ TypeId TcpDctcp::GetTypeId (void) .AddAttribute ("DctcpAlphaOnInit", "Initial alpha value", DoubleValue (1.0), - MakeDoubleAccessor (&TcpDctcp::SetDctcpAlpha), + MakeDoubleAccessor (&TcpDctcp::InitializeDctcpAlpha), MakeDoubleChecker (0, 1)) .AddAttribute ("UseEct0", "Use ECT(0) for ECN codepoint, if false use ECT(1)", BooleanValue (true), MakeBooleanAccessor (&TcpDctcp::m_useEct0), MakeBooleanChecker ()) + .AddTraceSource ("CongestionEstimate", + "Update sender-side congestion estimate state", + MakeTraceSourceAccessor (&TcpDctcp::m_traceCongestionEstimate), + "ns3::TcpDctcp::CongestionEstimateTracedCallback") ; return tid; } @@ -61,17 +65,18 @@ std::string TcpDctcp::GetName () const } TcpDctcp::TcpDctcp () - : TcpLinuxReno () + : TcpLinuxReno (), + m_ackedBytesEcn (0), + m_ackedBytesTotal (0), + m_priorRcvNxt (SequenceNumber32 (0)), + m_priorRcvNxtFlag (false), + m_nextSeq (SequenceNumber32 (0)), + m_nextSeqFlag (false), + m_ceState (false), + m_delayedAckReserved (false), + m_initialized (false) { NS_LOG_FUNCTION (this); - m_ackedBytesEcn = 0; - m_ackedBytesTotal = 0; - m_priorRcvNxt = SequenceNumber32 (0); - m_priorRcvNxtFlag = false; - m_nextSeq = SequenceNumber32 (0); - m_nextSeqFlag = false; - m_ceState = false; - m_delayedAckReserved = false; } TcpDctcp::TcpDctcp (const TcpDctcp& sock) @@ -86,7 +91,8 @@ TcpDctcp::TcpDctcp (const TcpDctcp& sock) m_ceState (sock.m_ceState), m_delayedAckReserved (sock.m_delayedAckReserved), m_g (sock.m_g), - m_useEct0 (sock.m_useEct0) + m_useEct0 (sock.m_useEct0), + m_initialized (sock.m_initialized) { NS_LOG_FUNCTION (this); } @@ -110,6 +116,7 @@ TcpDctcp::Init (Ptr tcb) tcb->m_useEcn = TcpSocketState::On; tcb->m_ecnMode = TcpSocketState::DctcpEcn; tcb->m_ectCodePoint = m_useEct0 ? TcpSocketState::Ect0 : TcpSocketState::Ect1; + m_initialized = true; } // Step 9, Section 3.3 of RFC 8257. GetSsThresh() is called upon @@ -143,21 +150,23 @@ TcpDctcp::PktsAcked (Ptr tcb, uint32_t segmentsAcked, const Time } if (tcb->m_lastAckedSeq >= m_nextSeq) { - double bytesEcn = 0.0; + double bytesEcn = 0.0; // Corresponds to variable M in RFC 8257 if (m_ackedBytesTotal > 0) { bytesEcn = static_cast (m_ackedBytesEcn * 1.0 / m_ackedBytesTotal); } m_alpha = (1.0 - m_g) * m_alpha + m_g * bytesEcn; + m_traceCongestionEstimate (m_ackedBytesEcn, m_ackedBytesTotal, m_alpha); NS_LOG_INFO (this << "bytesEcn " << bytesEcn << ", m_alpha " << m_alpha); Reset (tcb); } } void -TcpDctcp::SetDctcpAlpha (double alpha) +TcpDctcp::InitializeDctcpAlpha (double alpha) { NS_LOG_FUNCTION (this << alpha); + NS_ABORT_MSG_IF (m_initialized, "DCTCP has already been initialized"); m_alpha = alpha; } diff --git a/src/internet/model/tcp-dctcp.h b/src/internet/model/tcp-dctcp.h index ea82645b8..dc0a36d10 100644 --- a/src/internet/model/tcp-dctcp.h +++ b/src/internet/model/tcp-dctcp.h @@ -24,6 +24,7 @@ #include "ns3/tcp-congestion-ops.h" #include "ns3/tcp-linux-reno.h" +#include "ns3/traced-callback.h" namespace ns3 { @@ -72,6 +73,15 @@ public: */ virtual void Init (Ptr tcb); + /** + * TracedCallback signature for DCTCP update of congestion state + * + * \param [in] bytesAcked Bytes acked in this observation window + * \param [in] bytesMarked Bytes marked in this observation window + * \param [in] alpha New alpha (congestion estimate) value + */ + typedef void (* CongestionEstimateTracedCallback)(uint32_t bytesAcked, uint32_t bytesMarked, double alpha); + // Documented in base class virtual uint32_t GetSsThresh (Ptr tcb, uint32_t bytesInFlight); @@ -113,11 +123,11 @@ private: void Reset (Ptr tcb); /** - * \brief Sets the value of m_alpha + * \brief Initialize the value of m_alpha * * \param alpha DCTCP alpha parameter */ - void SetDctcpAlpha (double alpha); + void InitializeDctcpAlpha (double alpha); uint32_t m_ackedBytesEcn; //!< Number of acked bytes which are marked uint32_t m_ackedBytesTotal; //!< Total number of acked bytes @@ -130,6 +140,11 @@ private: bool m_delayedAckReserved; //!< Delayed Ack state double m_g; //!< Estimation gain bool m_useEct0; //!< Use ECT(0) for ECN codepoint + bool m_initialized; //!< Whether DCTCP has been initialized + /** + * \brief Callback pointer for congestion state update + */ + TracedCallback m_traceCongestionEstimate; }; } // namespace ns3