tcp: RecoveryOps gets delivered information from RateOps

(incorporating comments from Natale P.)
This commit is contained in:
Vivek Jain
2018-06-19 22:31:33 +02:00
committed by Tom Henderson
parent 3024805d16
commit ed743b2cfe
7 changed files with 37 additions and 56 deletions

View File

@@ -22,7 +22,6 @@
*/
#include "tcp-prr-recovery.h"
#include "ns3/tcp-socket-base.h"
#include "ns3/tcp-congestion-ops.h"
#include "ns3/log.h"
@@ -58,7 +57,6 @@ TcpPrrRecovery::TcpPrrRecovery (const TcpPrrRecovery& recovery)
m_prrDelivered (recovery.m_prrDelivered),
m_prrOut (recovery.m_prrOut),
m_recoveryFlightSize (recovery.m_recoveryFlightSize),
m_previousSackedBytes (recovery.m_previousSackedBytes),
m_reductionBoundMode (recovery.m_reductionBoundMode)
{
NS_LOG_FUNCTION (this);
@@ -71,29 +69,23 @@ TcpPrrRecovery::~TcpPrrRecovery (void)
void
TcpPrrRecovery::EnterRecovery (Ptr<TcpSocketState> tcb, uint32_t dupAckCount,
uint32_t unAckDataCount, uint32_t lastSackedBytes)
uint32_t unAckDataCount, uint32_t deliveredBytes)
{
NS_LOG_FUNCTION (this << tcb << dupAckCount << unAckDataCount << lastSackedBytes);
NS_LOG_FUNCTION (this << tcb << dupAckCount << unAckDataCount);
NS_UNUSED (dupAckCount);
m_prrOut = 0;
m_prrDelivered = 0;
m_recoveryFlightSize = unAckDataCount;
m_previousSackedBytes = lastSackedBytes;
DoRecovery (tcb, 0, lastSackedBytes);
DoRecovery (tcb, deliveredBytes);
}
void
TcpPrrRecovery::DoRecovery (Ptr<TcpSocketState> tcb, uint32_t lastAckedBytes,
uint32_t lastSackedBytes)
TcpPrrRecovery::DoRecovery (Ptr<TcpSocketState> tcb, uint32_t deliveredBytes)
{
NS_LOG_FUNCTION (this << tcb << lastAckedBytes << lastSackedBytes);
uint32_t lastDeliveredBytes;
int changeInSackedBytes = int (lastSackedBytes - m_previousSackedBytes);
lastDeliveredBytes = lastAckedBytes + changeInSackedBytes > 0 ? lastAckedBytes + changeInSackedBytes : 0;
m_previousSackedBytes = lastSackedBytes;
m_prrDelivered += lastDeliveredBytes;
NS_LOG_FUNCTION (this << tcb << deliveredBytes);
m_prrDelivered += deliveredBytes;
int sendCount;
if (tcb->m_bytesInFlight > tcb->m_ssThresh)
@@ -109,7 +101,7 @@ TcpPrrRecovery::DoRecovery (Ptr<TcpSocketState> tcb, uint32_t lastAckedBytes,
}
else if (m_reductionBoundMode == SSRB)
{
limit = std::max (m_prrDelivered - m_prrOut, lastDeliveredBytes) + tcb->m_segmentSize;
limit = std::max (m_prrDelivered - m_prrOut, deliveredBytes) + tcb->m_segmentSize;
}
sendCount = std::min (limit, static_cast<int> (tcb->m_ssThresh - tcb->m_bytesInFlight));
}

View File

@@ -72,10 +72,9 @@ public:
std::string GetName () const override;
virtual void EnterRecovery (Ptr<TcpSocketState> tcb, uint32_t dupAckCount,
uint32_t unAckDataCount, uint32_t lastSackedBytes) override;
uint32_t unAckDataCount, uint32_t deliveredBytes) override;
virtual void DoRecovery (Ptr<TcpSocketState> tcb, uint32_t lastAckedBytes,
uint32_t lastSackedBytes) override;
virtual void DoRecovery (Ptr<TcpSocketState> tcb, uint32_t deliveredBytes) override;
virtual void ExitRecovery (Ptr<TcpSocketState> tcb) override;
@@ -87,7 +86,6 @@ private:
uint32_t m_prrDelivered {0}; //!< total bytes delivered during recovery phase
uint32_t m_prrOut {0}; //!< total bytes sent during recovery phase
uint32_t m_recoveryFlightSize {0}; //!< value of bytesInFlight at the start of recovery phase
uint32_t m_previousSackedBytes {0}; //!< total bytes SACKed by the previous ACK
ReductionBound_t m_reductionBoundMode {SSRB}; //!< mode of Reduction Bound to be used
};
} // namespace ns3

View File

@@ -55,6 +55,11 @@ TcpRecoveryOps::~TcpRecoveryOps ()
NS_LOG_FUNCTION (this);
}
void
TcpRecoveryOps::UpdateBytesSent (uint32_t bytesSent)
{
NS_LOG_FUNCTION (this << bytesSent);
}
// Classic recovery
@@ -89,22 +94,20 @@ TcpClassicRecovery::~TcpClassicRecovery (void)
void
TcpClassicRecovery::EnterRecovery (Ptr<TcpSocketState> tcb, uint32_t dupAckCount,
uint32_t unAckDataCount, uint32_t lastSackedBytes)
uint32_t unAckDataCount, uint32_t deliveredBytes)
{
NS_LOG_FUNCTION (this << tcb << dupAckCount << unAckDataCount << lastSackedBytes);
NS_LOG_FUNCTION (this << tcb << dupAckCount << unAckDataCount);
NS_UNUSED (unAckDataCount);
NS_UNUSED (lastSackedBytes);
NS_UNUSED (deliveredBytes);
tcb->m_cWnd = tcb->m_ssThresh;
tcb->m_cWndInfl = tcb->m_ssThresh + (dupAckCount * tcb->m_segmentSize);
}
void
TcpClassicRecovery::DoRecovery (Ptr<TcpSocketState> tcb, uint32_t lastAckedBytes,
uint32_t lastSackedBytes)
TcpClassicRecovery::DoRecovery (Ptr<TcpSocketState> tcb, uint32_t deliveredBytes)
{
NS_LOG_FUNCTION (this << tcb << lastAckedBytes << lastSackedBytes);
NS_UNUSED (lastAckedBytes);
NS_UNUSED (lastSackedBytes);
NS_LOG_FUNCTION (this << tcb << deliveredBytes);
NS_UNUSED (deliveredBytes);
tcb->m_cWndInfl += tcb->m_segmentSize;
}

View File

@@ -96,10 +96,10 @@ public:
* \param tcb internal congestion state
* \param dupAckCount duplicate acknowldgement count
* \param unAckDataCount total bytes of data unacknowledged
* \param lastSackedBytes bytes acknowledged via SACK in the last ACK
* \param deliveredBytes bytes (S)ACKed in the last (S)ACK
*/
virtual void EnterRecovery (Ptr<TcpSocketState> tcb, uint32_t dupAckCount,
uint32_t unAckDataCount, uint32_t lastSackedBytes) = 0;
uint32_t unAckDataCount, uint32_t deliveredBytes) = 0;
/**
* \brief Performs recovery based on the recovery algorithm
@@ -108,15 +108,10 @@ public:
* is set to CA_RECOVERY. It performs the necessary cwnd changes
* as per the recovery algorithm.
*
* TODO: lastAckedBytes and lastSackedBytes should be one parameter
* that indicates how much data has been ACKed or SACKed.
*
* \param tcb internal congestion state
* \param lastAckedBytes bytes acknowledged in the last ACK
* \param lastSackedBytes bytes acknowledged via SACK in the last ACK
* \param deliveredBytes bytes (S)ACKed in the last (S)ACK
*/
virtual void DoRecovery (Ptr<TcpSocketState> tcb, uint32_t lastAckedBytes,
uint32_t lastSackedBytes) = 0;
virtual void DoRecovery (Ptr<TcpSocketState> tcb, uint32_t deliveredBytes) = 0;
/**
* \brief Performs cwnd adjustments at the end of recovery
@@ -136,10 +131,7 @@ public:
*
* \param bytesSent bytes sent
*/
virtual void UpdateBytesSent (uint32_t bytesSent)
{
NS_UNUSED (bytesSent);
}
virtual void UpdateBytesSent (uint32_t bytesSent);
/**
* \brief Copy the recovery algorithm across socket
@@ -191,10 +183,9 @@ public:
virtual std::string GetName () const override;
virtual void EnterRecovery (Ptr<TcpSocketState> tcb, uint32_t dupAckCount,
uint32_t unAckDataCount, uint32_t lastSackedBytes) override;
uint32_t unAckDataCount, uint32_t deliveredBytes) override;
virtual void DoRecovery (Ptr<TcpSocketState> tcb, uint32_t lastAckedBytes,
uint32_t lastSackedBytes) override;
virtual void DoRecovery (Ptr<TcpSocketState> tcb, uint32_t deliveredBytes) override;
virtual void ExitRecovery (Ptr<TcpSocketState> tcb) override;

View File

@@ -1576,7 +1576,7 @@ TcpSocketBase::EnterRecovery (uint32_t currentDelivered)
// compatibility with old ns-3 versions
uint32_t bytesInFlight = m_sackEnabled ? BytesInFlight () : BytesInFlight () + m_tcb->m_segmentSize;
m_tcb->m_ssThresh = m_congestionControl->GetSsThresh (m_tcb, bytesInFlight);
m_recoveryOps->EnterRecovery (m_tcb, m_dupAckCount, UnAckDataCount (), m_txBuffer->GetSacked ());
m_recoveryOps->EnterRecovery (m_tcb, m_dupAckCount, UnAckDataCount (), currentDelivered);
NS_LOG_INFO (m_dupAckCount << " dupack. Enter fast recovery mode." <<
"Reset cwnd to " << m_tcb->m_cWnd << ", ssthresh to " <<
@@ -1634,7 +1634,7 @@ TcpSocketBase::DupAck (uint32_t currentDelivered)
// has left the network. This is equivalent to a SACK of one block.
m_txBuffer->AddRenoSack ();
}
m_recoveryOps->DoRecovery (m_tcb, 0, m_txBuffer->GetSacked ());
m_recoveryOps->DoRecovery (m_tcb, currentDelivered);
NS_LOG_INFO (m_dupAckCount << " Dupack received in fast recovery mode."
"Increase cwnd to " << m_tcb->m_cWnd);
}
@@ -1858,7 +1858,7 @@ TcpSocketBase::ProcessAck(const SequenceNumber32 &ackNumber, bool scoreboardUpda
m_tcb->m_cWndInfl = SafeSubtraction (m_tcb->m_cWndInfl, bytesAcked);
if (segsAcked >= 1)
{
m_recoveryOps->DoRecovery (m_tcb, bytesAcked, m_txBuffer->GetSacked ());
m_recoveryOps->DoRecovery (m_tcb, currentDelivered);
}
// This partial ACK acknowledge the fact that one segment has been

View File

@@ -98,7 +98,7 @@ ClassicRecoveryTest::DoRun ()
uint32_t cWndInflPrevious = m_state->m_cWndInfl;
uint32_t cWndPrevious = m_state->m_cWnd;
recovery->DoRecovery (m_state, 0, 500);
recovery->DoRecovery (m_state, 500);
NS_TEST_ASSERT_MSG_EQ (m_state->m_cWndInfl, (cWndInflPrevious + m_state->m_segmentSize),
"m_cWndInfl should be incresed by one segmentSize on calling DoRecovery");
NS_TEST_ASSERT_MSG_EQ (m_state->m_cWnd, cWndPrevious,
@@ -122,9 +122,6 @@ class ClassicRecoveryTestSuite : public TestSuite
public:
ClassicRecoveryTestSuite () : TestSuite ("tcp-classic-recovery-test", UNIT)
{
AddTestCase (new ClassicRecoveryTest (3000, 500, 2500, 3,
"Classic recovery test on cWnd and cWndInfl with 500 bytes segmentSize"),
TestCase::QUICK);
AddTestCase (new ClassicRecoveryTest (3000, 500, 2500, 3, "Classic recovery test with 500 bytes segmentSize"),
TestCase::QUICK);
AddTestCase (new ClassicRecoveryTest (3000, 1000, 2500, 3, "Classic recovery test with 1000 bytes segmentSize"),

View File

@@ -46,7 +46,7 @@ public:
* \param ssThresh Slow Start Threshold.
* \param unAckDataCount Unacknowledged data at the start of recovery.
* \param bytesInFlight Current bytes in flight.
* \para m_lastSackedBytes Bytes SACKed on last acknowledgment.
* \para m_deliveredBytes Bytes SACKed on last acknowledgment.
* \para bytesSent Bytes sent while in recovery phase.
* \para reductionBound Type of reduction bound to be used.
* \param name Test description.
@@ -56,7 +56,7 @@ public:
uint32_t ssThresh,
uint32_t unAckDataCount,
uint32_t bytesInFlight,
uint32_t m_lastSackedBytes,
uint32_t m_deliveredBytes,
uint32_t bytesSent,
const std::string &reductionBound,
const std::string &name);
@@ -69,7 +69,7 @@ private:
uint32_t m_ssThresh; //!< Slow Start Threshold.
uint32_t m_unAckDataCount; //!< Unacknowledged data at the start of recovery.
uint32_t m_bytesInFlight; //!< Current bytes in flight.
uint32_t m_lastSackedBytes; //!< Bytes SACKed on last acknowledgment.
uint32_t m_deliveredBytes; //!< Bytes SACKed on last acknowledgment.
uint32_t m_bytesSent; //!< Bytes sent while in recovery phase.
const std::string m_reductionBound; //!< Type of reduction bound to be used.
@@ -81,7 +81,7 @@ PrrRecoveryTest::PrrRecoveryTest (uint32_t cWnd,
uint32_t ssThresh,
uint32_t unAckDataCount,
uint32_t bytesInFlight,
uint32_t lastSackedBytes,
uint32_t deliveredBytes,
uint32_t bytesSent,
const std::string &reductionBound,
const std::string &name)
@@ -91,7 +91,7 @@ PrrRecoveryTest::PrrRecoveryTest (uint32_t cWnd,
m_ssThresh (ssThresh),
m_unAckDataCount (unAckDataCount),
m_bytesInFlight (bytesInFlight),
m_lastSackedBytes (lastSackedBytes),
m_deliveredBytes (deliveredBytes),
m_bytesSent (bytesSent),
m_reductionBound (reductionBound)
{
@@ -125,7 +125,7 @@ PrrRecoveryTest::DoRun ()
m_bytesInFlight += m_state->m_cWnd.Get () - m_cWnd;
m_state->m_bytesInFlight = m_bytesInFlight;
m_cWnd = m_state->m_cWnd.Get ();
recovery->DoRecovery (m_state, 0, m_lastSackedBytes);
recovery->DoRecovery (m_state, m_deliveredBytes);
if (m_bytesInFlight > m_state->m_ssThresh)
{