Created TCB: Transmission Control Block

The data structure contains information that should be exchanged between
congestion control and the socket.
This commit is contained in:
Natale Patriciello
2015-10-16 10:42:14 -07:00
parent e8a3391575
commit 2e5a2c1301
4 changed files with 198 additions and 72 deletions

View File

@@ -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<double> (m_segmentSize * m_segmentSize) / m_cWnd.Get ();
double adder = static_cast<double> (m_tcb->m_segmentSize * m_tcb->m_segmentSize) / m_tcb->m_cWnd.Get ();
adder = std::max (1.0, adder);
m_cWnd += static_cast<uint32_t> (adder);
NS_LOG_INFO ("In CongAvoid, updated to cwnd " << m_cWnd << " ssthresh " << m_ssThresh);
m_tcb->m_cWnd += static_cast<uint32_t> (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

View File

@@ -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<Object> ()
.SetGroupName ("Internet")
.AddConstructor <TcpSocketState> ()
.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<TcpRxBuffer> ();
m_txBuffer = CreateObject<TcpTxBuffer> ();
m_tcb = CreateObject<TcpSocketState> ();
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> 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> 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> 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)

View File

@@ -45,6 +45,7 @@ class Node;
class Packet;
class TcpL4Protocol;
class TcpHeader;
class TcpSocketState;
/**
* \ingroup tcp
@@ -104,6 +105,13 @@ typedef std::deque<RttHistory> 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<uint32_t, uint32_t> m_cWndTrace;
/**
* \brief Callback pointer for ssTh trace chaining
*/
TracedCallback<uint32_t, uint32_t> 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<uint32_t> m_rWnd; //!< Receiver window (RCV.WND in RFC793)
TracedValue<SequenceNumber32> m_highRxMark; //!< Highest seqno received
TracedValue<SequenceNumber32> m_highRxAckMark; //!< Highest ack received
// Congestion control
TracedValue<uint32_t> m_cWnd; //!< Congestion window
TracedValue<uint32_t> 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<TcpSocketState> 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<uint32_t> m_cWnd; //!< Congestion window
TracedValue<uint32_t> 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
};
/**

View File

@@ -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<double> (m_segmentSize * m_segmentSize) / m_cWnd.Get();
double adder = static_cast<double> (m_tcb->m_segmentSize * m_tcb->m_segmentSize) / m_tcb->m_cWnd.Get();
adder = std::max(1.0, adder);
m_cWnd += static_cast<uint32_t>(adder);
NS_LOG_INFO ("In CongAvoid, updated to cwnd " << m_cWnd << " ssthresh " << m_ssThresh);
m_tcb->m_cWnd += static_cast<uint32_t>(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<double> (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