tcp: Added CongControl API in TcpCongestionOps

This commit is contained in:
Vivek Jain
2018-06-19 22:36:47 +02:00
committed by Tom Henderson
parent ed743b2cfe
commit cfa918b74e
3 changed files with 106 additions and 26 deletions

View File

@@ -48,6 +48,48 @@ TcpCongestionOps::~TcpCongestionOps ()
{
}
void
TcpCongestionOps::IncreaseWindow (Ptr<TcpSocketState> tcb, uint32_t segmentsAcked)
{
NS_LOG_FUNCTION (this << tcb << segmentsAcked);
}
void
TcpCongestionOps::PktsAcked (Ptr<TcpSocketState> tcb, uint32_t segmentsAcked,
const Time& rtt)
{
NS_LOG_FUNCTION (this << tcb << segmentsAcked << rtt);
}
void
TcpCongestionOps::CongestionStateSet (Ptr<TcpSocketState> tcb,
const TcpSocketState::TcpCongState_t newState)
{
NS_LOG_FUNCTION (this << tcb << newState);
}
void
TcpCongestionOps::CwndEvent (Ptr<TcpSocketState> tcb,
const TcpSocketState::TcpCAEvent_t event)
{
NS_LOG_FUNCTION (this << tcb << event);
}
bool
TcpCongestionOps::HasCongControl () const
{
return false;
}
void
TcpCongestionOps::CongControl (Ptr<TcpSocketState> tcb,
const TcpRateOps::TcpRateConnection &rc,
const TcpRateOps::TcpRateSample &rs)
{
NS_LOG_FUNCTION (this << tcb);
NS_UNUSED (rc);
NS_UNUSED (rs);
}
// RENO

View File

@@ -20,6 +20,7 @@
#define TCPCONGESTIONOPS_H
#include "ns3/tcp-socket-state.h"
#include "ns3/tcp-rate-ops.h"
namespace ns3 {
@@ -101,7 +102,7 @@ public:
* \param tcb internal congestion state
* \param segmentsAcked count of segments acked
*/
virtual void IncreaseWindow (Ptr<TcpSocketState> tcb, uint32_t segmentsAcked) = 0;
virtual void IncreaseWindow (Ptr<TcpSocketState> tcb, uint32_t segmentsAcked);
/**
* \brief Timing information on received ACK
@@ -116,12 +117,7 @@ public:
* \param rtt last rtt
*/
virtual void PktsAcked (Ptr<TcpSocketState> tcb, uint32_t segmentsAcked,
const Time& rtt)
{
NS_UNUSED (tcb);
NS_UNUSED (segmentsAcked);
NS_UNUSED (rtt);
}
const Time& rtt);
/**
* \brief Trigger events/calculations specific to a congestion state
@@ -140,11 +136,7 @@ public:
* \param newState new congestion state to which the TCP is going to switch
*/
virtual void CongestionStateSet (Ptr<TcpSocketState> tcb,
const TcpSocketState::TcpCongState_t newState)
{
NS_UNUSED (tcb);
NS_UNUSED (newState);
}
const TcpSocketState::TcpCongState_t newState);
/**
* \brief Trigger events/calculations on occurrence of congestion window event
@@ -156,11 +148,36 @@ public:
* \param event the event which triggered this function
*/
virtual void CwndEvent (Ptr<TcpSocketState> tcb,
const TcpSocketState::TcpCAEvent_t event)
{
NS_UNUSED (tcb);
NS_UNUSED (event);
}
const TcpSocketState::TcpCAEvent_t event);
/**
* \brief Returns true when Congestion Control Algorithm implements CongControl
*
* \return true if CC implements CongControl function
*
* This function is the equivalent in C++ of the C checks that are used
* in the Linux kernel to see if an optional function has been defined.
* Since CongControl is optional, not all congestion controls have it. But,
* from the perspective of TcpSocketBase, the behavior is different if
* CongControl is present. Therefore, this check should return true for any
* congestion controls that implements the CongControl optional function.
*/
virtual bool HasCongControl () const;
/**
* \brief Called when packets are delivered to update cwnd and pacing rate
*
* This function mimics the function cong_control in Linux. It is allowed to
* change directly cWnd and pacing rate.
*
* \param tcb internal congestion state
* \param rc Rate information for the connection
* \param rs Rate sample (over a period of time) information
*/
virtual void CongControl (Ptr<TcpSocketState> tcb,
const TcpRateOps::TcpRateConnection &rc,
const TcpRateOps::TcpRateSample &rs);
// Present in Linux but not in ns-3 yet:
/* call when ack arrives (optional) */
// void (*in_ack_event)(struct sock *sk, u32 flags);

View File

@@ -1576,12 +1576,16 @@ 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 (), currentDelivered);
NS_LOG_INFO (m_dupAckCount << " dupack. Enter fast recovery mode." <<
"Reset cwnd to " << m_tcb->m_cWnd << ", ssthresh to " <<
m_tcb->m_ssThresh << " at fast recovery seqnum " << m_recover <<
" calculated in flight: " << bytesInFlight);
if (!m_congestionControl->HasCongControl ())
{
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 " <<
m_tcb->m_ssThresh << " at fast recovery seqnum " << m_recover <<
" calculated in flight: " << bytesInFlight);
}
// (4.3) Retransmit the first data segment presumed dropped
DoRetransmit ();
@@ -1634,9 +1638,12 @@ 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, currentDelivered);
NS_LOG_INFO (m_dupAckCount << " Dupack received in fast recovery mode."
"Increase cwnd to " << m_tcb->m_cWnd);
if (!m_congestionControl->HasCongControl ())
{
m_recoveryOps->DoRecovery (m_tcb, currentDelivered);
NS_LOG_INFO (m_dupAckCount << " Dupack received in fast recovery mode."
"Increase cwnd to " << m_tcb->m_cWnd);
}
}
else if (m_tcb->m_congState == TcpSocketState::CA_DISORDER)
{
@@ -1718,6 +1725,20 @@ TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
// are inside the function ProcessAck
ProcessAck (ackNumber, (bytesSacked > 0), currentDelivered, oldHeadSequence);
if (m_congestionControl->HasCongControl ())
{
uint32_t previousLost = m_txBuffer->GetLost ();
uint32_t priorInFlight = m_tcb->m_bytesInFlight.Get ();
uint32_t currentLost = m_txBuffer->GetLost ();
uint32_t lost = (currentLost > previousLost) ?
currentLost - previousLost :
previousLost - currentLost;
auto rateSample = m_rateOps->GenerateSample (currentDelivered, lost,
false, priorInFlight, m_tcb->m_minRtt);
auto rateConn = m_rateOps->GetConnectionRate ();
m_congestionControl->CongControl(m_tcb, rateConn, rateSample);
}
// If there is any data piggybacked, store it into m_rxBuffer
if (packet->GetSize () > 0)
{
@@ -1856,7 +1877,7 @@ TcpSocketBase::ProcessAck(const SequenceNumber32 &ackNumber, bool scoreboardUpda
}
DoRetransmit (); // Assume the next seq is lost. Retransmit lost packet
m_tcb->m_cWndInfl = SafeSubtraction (m_tcb->m_cWndInfl, bytesAcked);
if (segsAcked >= 1)
if (!m_congestionControl->HasCongControl () && segsAcked >= 1)
{
m_recoveryOps->DoRecovery (m_tcb, currentDelivered);
}