From 2e5a2c130194cf5e6d052c8bb305c0f683210ee4 Mon Sep 17 00:00:00 2001 From: Natale Patriciello Date: Fri, 16 Oct 2015 10:42:14 -0700 Subject: [PATCH] Created TCB: Transmission Control Block The data structure contains information that should be exchanged between congestion control and the socket. --- src/internet/model/tcp-newreno.cc | 20 ++-- src/internet/model/tcp-socket-base.cc | 151 ++++++++++++++++++-------- src/internet/model/tcp-socket-base.h | 77 +++++++++++-- src/internet/model/tcp-westwood.cc | 22 ++-- 4 files changed, 198 insertions(+), 72 deletions(-) diff --git a/src/internet/model/tcp-newreno.cc b/src/internet/model/tcp-newreno.cc index f2184f418..c23f99897 100644 --- a/src/internet/model/tcp-newreno.cc +++ b/src/internet/model/tcp-newreno.cc @@ -74,8 +74,8 @@ TcpNewReno::NewAck (const SequenceNumber32& seq) { NS_LOG_FUNCTION (this << seq); NS_LOG_LOGIC ("TcpNewReno received ACK for seq " << seq << - " cwnd " << m_cWnd << - " ssthresh " << m_ssThresh); + " cwnd " << m_tcb->m_cWnd << + " ssthresh " << m_tcb->m_ssThresh); // No cWnd management while recovering if (m_ackState == RECOVERY && seq < m_recover) @@ -85,18 +85,18 @@ TcpNewReno::NewAck (const SequenceNumber32& seq) } // Increase of cwnd based on current phase (slow start or congestion avoidance) - if (m_cWnd < m_ssThresh) - { // Slow start mode, add one segSize to cWnd. Default m_ssThresh is 65535. (RFC2001, sec.1) - m_cWnd += m_segmentSize; - NS_LOG_INFO ("In SlowStart, ACK of seq " << seq << "; update cwnd to " << m_cWnd << "; ssthresh " << m_ssThresh); + if (m_tcb->m_cWnd < m_tcb->m_ssThresh) + { // Slow start mode, add one segSize to cWnd. Default m_tcb->m_ssThresh is 65535. (RFC2001, sec.1) + m_tcb->m_cWnd += m_tcb->m_segmentSize; + NS_LOG_INFO ("In SlowStart, ACK of seq " << seq << "; update cwnd to " << m_tcb->m_cWnd << "; ssthresh " << m_tcb->m_ssThresh); } else { // Congestion avoidance mode, increase by (segSize*segSize)/cwnd. (RFC2581, sec.3.1) // To increase cwnd for one segSize per RTT, it should be (ackBytes*segSize)/cwnd - double adder = static_cast (m_segmentSize * m_segmentSize) / m_cWnd.Get (); + double adder = static_cast (m_tcb->m_segmentSize * m_tcb->m_segmentSize) / m_tcb->m_cWnd.Get (); adder = std::max (1.0, adder); - m_cWnd += static_cast (adder); - NS_LOG_INFO ("In CongAvoid, updated to cwnd " << m_cWnd << " ssthresh " << m_ssThresh); + m_tcb->m_cWnd += static_cast (adder); + NS_LOG_INFO ("In CongAvoid, updated to cwnd " << m_tcb->m_cWnd << " ssthresh " << m_tcb->m_ssThresh); } // Complete newAck processing @@ -106,7 +106,7 @@ TcpNewReno::NewAck (const SequenceNumber32& seq) uint32_t TcpNewReno::GetSsThresh () { - return std::max (2 * m_segmentSize, BytesInFlight () / 2); + return std::max (2 * m_tcb->m_segmentSize, BytesInFlight () / 2); } } // namespace ns3 diff --git a/src/internet/model/tcp-socket-base.cc b/src/internet/model/tcp-socket-base.cc index 94c0f4a65..32ecba18c 100644 --- a/src/internet/model/tcp-socket-base.cc +++ b/src/internet/model/tcp-socket-base.cc @@ -164,16 +164,50 @@ TcpSocketBase::GetTypeId (void) "ns3::SequenceNumber32TracedValueCallback") .AddTraceSource ("CongestionWindow", "The TCP connection's congestion window", - MakeTraceSourceAccessor (&TcpSocketBase::m_cWnd), + MakeTraceSourceAccessor (&TcpSocketBase::m_cWndTrace), "ns3::TracedValueCallback::Uint32") .AddTraceSource ("SlowStartThreshold", "TCP slow start threshold (bytes)", - MakeTraceSourceAccessor (&TcpSocketBase::m_ssThresh), + MakeTraceSourceAccessor (&TcpSocketBase::m_ssThTrace), "ns3::TracedValueCallback::Uint32") ; return tid; } +// TcpSocketState +TypeId +TcpSocketState::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::TcpSocketState") + .SetParent () + .SetGroupName ("Internet") + .AddConstructor () + .AddTraceSource ("CongestionWindow", + "The TCP connection's congestion window", + MakeTraceSourceAccessor (&TcpSocketState::m_cWnd), + "ns3::TracedValue::Uint32Callback") + .AddTraceSource ("SlowStartThreshold", + "TCP slow start threshold (bytes)", + MakeTraceSourceAccessor (&TcpSocketState::m_ssThresh), + "ns3::TracedValue::Uint32Callback") + ; + return tid; +} + +TcpSocketState::TcpSocketState (void) + : Object () +{ +} + +TcpSocketState::TcpSocketState (const TcpSocketState &other) + : m_cWnd (other.m_cWnd), + m_ssThresh (other.m_ssThresh), + m_initialCWnd (other.m_initialCWnd), + m_initialSsThresh (other.m_initialSsThresh), + m_segmentSize (other.m_segmentSize) +{ +} + TcpSocketBase::TcpSocketBase (void) : m_dupAckCount (0), m_delAckCount (0), @@ -194,7 +228,6 @@ TcpSocketBase::TcpSocketBase (void) m_shutdownSend (false), m_shutdownRecv (false), m_connected (false), - m_segmentSize (0), // For attribute initialization consistency (quiet valgrind) m_rWnd (0), m_highRxMark (0), @@ -211,6 +244,17 @@ TcpSocketBase::TcpSocketBase (void) NS_LOG_FUNCTION (this); m_rxBuffer = CreateObject (); m_txBuffer = CreateObject (); + m_tcb = CreateObject (); + + bool ok; + + ok = m_tcb->TraceConnectWithoutContext ("CongestionWindow", + MakeCallback (&TcpSocketBase::UpdateCwnd, this)); + NS_ASSERT (ok == true); + + ok = m_tcb->TraceConnectWithoutContext ("SlowStartThreshold", + MakeCallback (&TcpSocketBase::UpdateSsThresh, this)); + NS_ASSERT (ok == true); } TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock) @@ -239,15 +283,10 @@ TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock) m_shutdownRecv (sock.m_shutdownRecv), m_connected (sock.m_connected), m_msl (sock.m_msl), - m_segmentSize (sock.m_segmentSize), m_maxWinSize (sock.m_maxWinSize), m_rWnd (sock.m_rWnd), m_highRxMark (sock.m_highRxMark), m_highRxAckMark (sock.m_highRxAckMark), - m_cWnd (sock.m_cWnd), - m_ssThresh (sock.m_ssThresh), - m_initialCWnd (sock.m_initialCWnd), - m_initialSsThresh (sock.m_initialSsThresh), m_winScalingEnabled (sock.m_winScalingEnabled), m_sndScaleFactor (sock.m_sndScaleFactor), m_rcvScaleFactor (sock.m_rcvScaleFactor), @@ -255,8 +294,8 @@ TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock) m_timestampToEcho (sock.m_timestampToEcho), m_ackState (sock.m_ackState), m_retxThresh (sock.m_retxThresh), - m_limitedTx (sock.m_limitedTx) - + m_limitedTx (sock.m_limitedTx), + m_tcb (sock.m_tcb) { NS_LOG_FUNCTION (this); NS_LOG_LOGIC ("Invoked the copy constructor"); @@ -275,6 +314,16 @@ TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock) SetRecvCallback (vPS); m_txBuffer = CopyObject (sock.m_txBuffer); m_rxBuffer = CopyObject (sock.m_rxBuffer); + + bool ok; + + ok = m_tcb->TraceConnectWithoutContext ("CongestionWindow", + MakeCallback (&TcpSocketBase::UpdateCwnd, this)); + NS_ASSERT (ok == true); + + ok = m_tcb->TraceConnectWithoutContext ("SlowStartThreshold", + MakeCallback (&TcpSocketBase::UpdateSsThresh, this)); + NS_ASSERT (ok == true); } TcpSocketBase::~TcpSocketBase (void) @@ -457,8 +506,8 @@ TcpSocketBase::Bind (const Address &address) void TcpSocketBase::InitializeCwnd (void) { - m_cWnd = m_initialCWnd * m_segmentSize; - m_ssThresh = m_initialSsThresh; + m_tcb->m_cWnd = m_tcb->m_initialCWnd * m_tcb->m_segmentSize; + m_tcb->m_ssThresh = m_tcb->m_initialSsThresh; } void @@ -467,13 +516,13 @@ TcpSocketBase::SetInitialSSThresh (uint32_t threshold) NS_ABORT_MSG_UNLESS (m_state == CLOSED, "TcpSocketBase::SetSSThresh() cannot change initial ssThresh after connection started."); - m_initialSsThresh = threshold; + m_tcb->m_initialSsThresh = threshold; } uint32_t TcpSocketBase::GetInitialSSThresh (void) const { - return m_initialSsThresh; + return m_tcb->m_initialSsThresh; } void @@ -482,19 +531,19 @@ TcpSocketBase::SetInitialCwnd (uint32_t cwnd) NS_ABORT_MSG_UNLESS (m_state == CLOSED, "TcpSocketBase::SetInitialCwnd() cannot change initial cwnd after connection started."); - m_initialCWnd = cwnd; + m_tcb->m_initialCWnd = cwnd; } uint32_t TcpSocketBase::GetInitialCwnd (void) const { - return m_initialCWnd; + return m_tcb->m_initialCWnd; } void TcpSocketBase::ScaleSsThresh (uint8_t scaleFactor) { - m_ssThresh <<= scaleFactor; + m_tcb->m_ssThresh <<= scaleFactor; } /* Inherit from Socket class: Initiate connection to a remote address:port */ @@ -1227,7 +1276,7 @@ TcpSocketBase::ReceivedAck (Ptr packet, const TcpHeader& tcpHeader) { // RFC3042 Limited transmit: Send a new packet for each duplicated ACK before fast retransmit NS_LOG_INFO ("Limited transmit"); - uint32_t sz = SendDataPacket (m_nextTxSequence, m_segmentSize, true); + uint32_t sz = SendDataPacket (m_nextTxSequence, m_tcb->m_segmentSize, true); m_nextTxSequence += sz; } else if (m_dupAckCount == m_retxThresh) @@ -1236,25 +1285,26 @@ TcpSocketBase::ReceivedAck (Ptr packet, const TcpHeader& tcpHeader) m_recover = m_highTxMark; m_ackState = RECOVERY; - m_ssThresh = GetSsThresh (); - m_cWnd = m_ssThresh + m_dupAckCount * m_segmentSize; + m_tcb->m_ssThresh = GetSsThresh (); + m_tcb->m_cWnd = m_tcb->m_ssThresh + m_dupAckCount * m_tcb->m_segmentSize; NS_LOG_INFO (m_dupAckCount << " dupack. Enter fast recovery mode." << - "Reset cwnd to " << m_cWnd << ", ssthresh to " << - m_ssThresh << " at fast recovery seqnum " << m_recover); + "Reset cwnd to " << m_tcb->m_cWnd << ", ssthresh to " << + m_tcb->m_ssThresh << " at fast recovery seqnum " << m_recover); DoRetransmit (); - NS_LOG_DEBUG ("DISORDER -> RECOVERY"); + NS_LOG_DEBUG (TcpAckStateName[m_ackState] << " -> RECOVERY"); } else { - NS_FATAL_ERROR ("m_dupAckCount > m_retxThresh and we still are in DISORDER state"); + NS_FATAL_ERROR ("m_dupAckCount > m_retxThresh and we still are " + "in DISORDER state"); } } else if (m_ackState == RECOVERY) { // Increase cwnd for every additional dupack (RFC2582, sec.3 bullet #3) - m_cWnd += m_segmentSize; - NS_LOG_INFO ("Dupack in fast recovery mode. Increase cwnd to " << m_cWnd); + m_tcb->m_cWnd += m_tcb->m_segmentSize; + NS_LOG_INFO ("Dupack in fast recovery mode. Increase cwnd to " << m_tcb->m_cWnd); if (!m_sendPendingDataEvent.IsRunning ()) { m_sendPendingDataEvent = Simulator::Schedule (TimeStep (1), &TcpSocketBase::SendPendingData, this, m_connected); @@ -1279,17 +1329,19 @@ TcpSocketBase::ReceivedAck (Ptr packet, const TcpHeader& tcpHeader) { if (tcpHeader.GetAckNumber () < m_recover) { // Partial ACK, partial window deflation (RFC2582 sec.3 bullet #5 paragraph 3) - m_cWnd += m_segmentSize - (tcpHeader.GetAckNumber () - m_txBuffer->HeadSequence ()); - NS_LOG_INFO ("Partial ACK for seq " << tcpHeader.GetAckNumber () << " in fast recovery: cwnd set to " << m_cWnd); + m_tcb->m_cWnd += m_tcb->m_segmentSize - + (tcpHeader.GetAckNumber () - m_txBuffer->HeadSequence ()); + NS_LOG_INFO ("Partial ACK for seq " << tcpHeader.GetAckNumber () << + " in fast recovery: cwnd set to " << m_tcb->m_cWnd); m_txBuffer->DiscardUpTo(tcpHeader.GetAckNumber ()); //Bug 1850: retransmit before newack DoRetransmit (); // Assume the next seq is lost. Retransmit lost packet } else if (tcpHeader.GetAckNumber () >= m_recover) {// Full ACK (RFC2582 sec.3 bullet #5 paragraph 2, option 1) - m_cWnd = std::min (m_ssThresh.Get (), BytesInFlight () + m_segmentSize); + m_tcb->m_cWnd = std::min ( m_tcb->m_ssThresh.Get (), BytesInFlight () + m_tcb->m_segmentSize); m_ackState = OPEN; NS_LOG_INFO ("Received full ACK for seq " << tcpHeader.GetAckNumber () << - ". Leaving fast recovery with cwnd set to " << m_cWnd); + ". Leaving fast recovery with cwnd set to " << m_tcb->m_cWnd); NS_LOG_DEBUG ("RECOVERY -> OPEN"); } } @@ -2170,7 +2222,7 @@ TcpSocketBase::SendPendingData (bool withAck) { uint32_t w = AvailableWindow (); // Get available window size // Stop sending if we need to wait for a larger Tx window (prevent silly window syndrome) - if (w < m_segmentSize && m_txBuffer->SizeFromSequence (m_nextTxSequence) > w) + if (w < m_tcb->m_segmentSize && m_txBuffer->SizeFromSequence (m_nextTxSequence) > w) { NS_LOG_LOGIC ("Preventing Silly Window Syndrome. Wait to send."); break; // No more @@ -2178,7 +2230,7 @@ TcpSocketBase::SendPendingData (bool withAck) // Nagle's algorithm (RFC896): Hold off sending if there is unacked data // in the buffer and the amount of data to send is less than one segment if (!m_noDelay && UnAckDataCount () > 0 - && m_txBuffer->SizeFromSequence (m_nextTxSequence) < m_segmentSize) + && m_txBuffer->SizeFromSequence (m_nextTxSequence) < m_tcb->m_segmentSize) { NS_LOG_LOGIC ("Invoking Nagle's algorithm. Wait to send."); break; @@ -2186,12 +2238,12 @@ TcpSocketBase::SendPendingData (bool withAck) NS_LOG_LOGIC ("TcpSocketBase " << this << " SendPendingData" << " w " << w << " rxwin " << m_rWnd << - " segsize " << m_segmentSize << + " segsize " << m_tcb->m_segmentSize << " nextTxSeq " << m_nextTxSequence << " highestRxAck " << m_txBuffer->HeadSequence () << " pd->Size " << m_txBuffer->Size () << " pd->SFS " << m_txBuffer->SizeFromSequence (m_nextTxSequence)); - uint32_t s = std::min (w, m_segmentSize); // Send no more than window + uint32_t s = std::min (w, m_tcb->m_segmentSize); // Send no more than window uint32_t sz = SendDataPacket (m_nextTxSequence, s, withAck); nPacketsSent++; // Count sent this loop m_nextTxSequence += sz; // Advance next tx sequence @@ -2221,7 +2273,7 @@ uint32_t TcpSocketBase::Window (void) { NS_LOG_FUNCTION (this); - return std::min (m_rWnd.Get (), m_cWnd.Get ()); + return std::min (m_rWnd.Get (), m_tcb->m_cWnd.Get ()); } uint32_t @@ -2532,12 +2584,12 @@ TcpSocketBase::Retransmit () if (m_ackState != LOSS) { m_ackState = LOSS; - m_cWnd = m_segmentSize; - m_ssThresh = GetSsThresh (); + m_tcb->m_ssThresh = GetSsThresh (); + m_tcb->m_cWnd = m_tcb->m_segmentSize; } - NS_LOG_DEBUG ("RTO. Reset cwnd to " << m_cWnd << - ", ssthresh to " << m_ssThresh << ", restart from seqnum " << m_nextTxSequence); + NS_LOG_DEBUG ("RTO. Reset cwnd to " << m_tcb->m_cWnd << ", ssthresh to " << + m_tcb->m_ssThresh << ", restart from seqnum " << m_nextTxSequence); DoRetransmit (); // Retransmit the packet } @@ -2569,7 +2621,7 @@ TcpSocketBase::DoRetransmit () } // Retransmit a data packet: Call SendDataPacket NS_LOG_LOGIC ("TcpSocketBase " << this << " retxing seq " << m_txBuffer->HeadSequence ()); - uint32_t sz = SendDataPacket (m_txBuffer->HeadSequence (), m_segmentSize, true); + uint32_t sz = SendDataPacket (m_txBuffer->HeadSequence (), m_tcb->m_segmentSize, true); // In case of RTO, advance m_nextTxSequence m_nextTxSequence = std::max (m_nextTxSequence.Get (), m_txBuffer->HeadSequence () + sz); @@ -2631,7 +2683,7 @@ void TcpSocketBase::SetSegSize (uint32_t size) { NS_LOG_FUNCTION (this << size); - m_segmentSize = size; + m_tcb->m_segmentSize = size; NS_ABORT_MSG_UNLESS (m_state == CLOSED, "Cannot change segment size dynamically."); } @@ -2639,7 +2691,7 @@ TcpSocketBase::SetSegSize (uint32_t size) uint32_t TcpSocketBase::GetSegSize (void) const { - return m_segmentSize; + return m_tcb->m_segmentSize; } void @@ -2957,10 +3009,21 @@ TcpSocketBase::GetRxBuffer (void) const const char* const TcpSocketBase::TcpAckStateName[TcpSocketBase::LAST_ACKSTATE] = { - "OPEN", "DISORDER", "CWR", "RECOVERY", - "LOSS" + "OPEN", "DISORDER", "CWR", "RECOVERY", "LOSS" }; +void +TcpSocketBase::UpdateCwnd (uint32_t oldValue, uint32_t newValue) +{ + m_cWndTrace (oldValue, newValue); +} + +void +TcpSocketBase::UpdateSsThresh (uint32_t oldValue, uint32_t newValue) +{ + m_ssThTrace (oldValue, newValue); +} + //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 9e25bf280..b4b299914 100644 --- a/src/internet/model/tcp-socket-base.h +++ b/src/internet/model/tcp-socket-base.h @@ -45,6 +45,7 @@ class Node; class Packet; class TcpL4Protocol; class TcpHeader; +class TcpSocketState; /** * \ingroup tcp @@ -104,6 +105,13 @@ typedef std::deque RttHistory_t; * the TcpAckState_t documentation. * * + * Congestion control interface + * --------------------------- + * + * The variables needed to congestion control subclasses have been moved inside + * the TcpSocketState class. It contains information on the congestion window, + * slow start threshold, segment size and the state of the Ack state machine. + * * Fast retransmit * --------------------------- * @@ -244,6 +252,30 @@ public: */ static const char* const TcpAckStateName[TcpSocketBase::LAST_ACKSTATE]; + /** + * \brief Callback pointer for cWnd trace chaining + */ + TracedCallback m_cWndTrace; + + /** + * \brief Callback pointer for ssTh trace chaining + */ + TracedCallback m_ssThTrace; + + /** + * \brief Callback function to hook to TcpSocketState congestion window + * \param oldValue old cWnd value + * \param newValue new cWnd value + */ + void UpdateCwnd (uint32_t oldValue, uint32_t newValue); + + /** + * \brief Callback function to hook to TcpSocketState slow start threshold + * \param oldValue old ssTh value + * \param newValue new ssTh value + */ + void UpdateSsThresh (uint32_t oldValue, uint32_t newValue); + // Necessary implementations of null functions from ns3::Socket virtual enum SocketErrno GetErrno (void) const; // returns m_errno virtual enum SocketType GetSocketType (void) const; // returns socket type @@ -828,18 +860,11 @@ protected: double m_msl; //!< Max segment lifetime // Window management - uint32_t m_segmentSize; //!< Segment size uint16_t m_maxWinSize; //!< Maximum window size to advertise TracedValue m_rWnd; //!< Receiver window (RCV.WND in RFC793) TracedValue m_highRxMark; //!< Highest seqno received TracedValue m_highRxAckMark; //!< Highest ack received - // Congestion control - TracedValue m_cWnd; //!< Congestion window - TracedValue m_ssThresh; //!< Slow start threshold - uint32_t m_initialCWnd; //!< Initial cWnd value - uint32_t m_initialSsThresh; //!< Initial Slow Start Threshold value - // Options bool m_winScalingEnabled; //!< Window Scale option enabled uint8_t m_sndScaleFactor; //!< Sent Window Scale (i.e., the one of the node) @@ -857,6 +882,44 @@ protected: SequenceNumber32 m_recover; //!< Previous highest Tx seqnum for fast recovery uint32_t m_retxThresh; //!< Fast Retransmit threshold bool m_limitedTx; //!< perform limited transmit + + // Transmission Control Block + Ptr m_tcb; //!< Congestion control informations +}; + +/** + * \brief Data structure that records the congestion state of a connection + * + * In this data structure, basic informations that should be passed between + * socket and the congestion control algorithm are saved. Through the code, + * it will be referred as Transmission Control Block (TCB), but there are some + * differencies. In the RFCs, the TCB contains all the variables that defines + * a connection, while we preferred to maintain in this class only the values + * that should be exchanged between socket and other parts, like congestion + * control algorithms. + * + */ +class TcpSocketState : public Object +{ +public: + /** + * Get the type ID. + * \brief Get the type ID. + * \return the object TypeId + */ + static TypeId GetTypeId (void); + + TcpSocketState (); + TcpSocketState (const TcpSocketState &other); + + // Congestion control + TracedValue m_cWnd; //!< Congestion window + TracedValue m_ssThresh; //!< Slow start threshold + uint32_t m_initialCWnd; //!< Initial cWnd value + uint32_t m_initialSsThresh; //!< Initial Slow Start Threshold value + + // Segment + uint32_t m_segmentSize; //!< Segment size }; /** diff --git a/src/internet/model/tcp-westwood.cc b/src/internet/model/tcp-westwood.cc index 58d7298f6..2c9c19e69 100644 --- a/src/internet/model/tcp-westwood.cc +++ b/src/internet/model/tcp-westwood.cc @@ -117,21 +117,21 @@ TcpWestwood::NewAck (const SequenceNumber32& seq) { // Same as Reno NS_LOG_FUNCTION (this << seq); NS_LOG_LOGIC ("TcpWestwood receieved ACK for seq " << seq << - " cwnd " << m_cWnd << - " ssthresh " << m_ssThresh); + " cwnd " << m_tcb->m_cWnd << + " ssthresh " << m_tcb->m_ssThresh); // Increase of cwnd based on current phase (slow start or congestion avoidance) - if (m_cWnd < m_ssThresh) + if (m_tcb->m_cWnd < m_tcb->m_ssThresh) { // Slow start mode, add one segSize to cWnd as in Reno - m_cWnd += m_segmentSize; - NS_LOG_INFO ("In SlowStart, updated to cwnd " << m_cWnd << " ssthresh " << m_ssThresh); + m_tcb->m_cWnd += m_tcb->m_segmentSize; + NS_LOG_INFO ("In SlowStart, updated to cwnd " << m_tcb->m_cWnd << " ssthresh " << m_tcb->m_ssThresh); } else { // Congestion avoidance mode, increase by (segSize*segSize)/cwnd as in Reno - double adder = static_cast (m_segmentSize * m_segmentSize) / m_cWnd.Get(); + double adder = static_cast (m_tcb->m_segmentSize * m_tcb->m_segmentSize) / m_tcb->m_cWnd.Get(); adder = std::max(1.0, adder); - m_cWnd += static_cast(adder); - NS_LOG_INFO ("In CongAvoid, updated to cwnd " << m_cWnd << " ssthresh " << m_ssThresh); + m_tcb->m_cWnd += static_cast(adder); + NS_LOG_INFO ("In CongAvoid, updated to cwnd " << m_tcb->m_cWnd << " ssthresh " << m_tcb->m_ssThresh); } // Complete newAck processing @@ -172,14 +172,14 @@ TcpWestwood::EstimateBW (int acked, const TcpHeader& tcpHeader, Time rtt) // Get the time when the current ACK is received double currentAck = static_cast (Simulator::Now().GetSeconds()); // Calculate the BW - m_currentBW = acked * m_segmentSize / (currentAck - m_lastAck); + m_currentBW = acked * m_tcb->m_segmentSize / (currentAck - m_lastAck); // Update the last ACK time m_lastAck = currentAck; } else if (m_pType == TcpWestwood::WESTWOODPLUS) { // Calculate the BW - m_currentBW = m_ackedSegments * m_segmentSize / rtt.GetSeconds(); + m_currentBW = m_ackedSegments * m_tcb->m_segmentSize / rtt.GetSeconds(); // Reset m_ackedSegments and m_IsCount for the next sampling m_ackedSegments = 0; m_IsCount = false; @@ -195,7 +195,7 @@ TcpWestwood::CountAck (const TcpHeader& tcpHeader) NS_LOG_FUNCTION (this); // Calculate the number of acknowledged segments based on the received ACK number - int cumul_ack = (tcpHeader.GetAckNumber() - m_prevAckNo) / m_segmentSize; + int cumul_ack = (tcpHeader.GetAckNumber() - m_prevAckNo) / m_tcb->m_segmentSize; if (cumul_ack == 0) {// A DUPACK counts for 1 segment delivered successfully