tcp: Added CongControl API in TcpCongestionOps
This commit is contained in:
committed by
Tom Henderson
parent
ed743b2cfe
commit
cfa918b74e
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user