Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/internet/doc/tcp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,34 @@ ExitRecovery is called just prior to exiting recovery phase in order to perform
required congestion window ajustments. UpdateBytesSent is used to keep track of
bytes sent and is called whenever a data packet is sent during recovery phase.

Delivery Rate Estimation
++++++++++++++++++++++++
Current TCP implementation measures the approximate value of the delivery rate of
inflight data based on Delivery Rate Estimation.

As high level idea, keep in mind that the algorithm keeps track of 2 variables:

1. `delivered`: Total amount of data delivered so far.

2. `deliveredStamp`: Last time `delivered` was updated.

When a packet is transmitted, the value of `delivered (d0)` and `deliveredStamp (t0)`
is stored in its respective TcpTxItem.

When an acknowledgement comes for this packet, the value of `delivered` and `deliveredStamp`
is updated to `d1` and `t1` in the same TcpTxItem.

After processing the acknowledgement, the rate sample is calculated and then passed
to a congestion avoidance algorithm:

.. math:: delivery_rate = (d1 - d0)/(t1 - t0)


The implementation to estimate delivery rate is a joint work between TcpTxBuffer and TcpRateOps.
For more information, please take a look at their doxygen documentation.

The implementation follows the RFC (Delivery Rate Estimation): https://tools.ietf.org/html/draft-cheng-iccrg-delivery-rate-estimation-00

Current limitations
+++++++++++++++++++

Expand Down
37 changes: 36 additions & 1 deletion src/internet/model/tcp-congestion-ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#define TCPCONGESTIONOPS_H

#include "ns3/tcp-socket-state.h"
#include "ns3/tcp-rate-ops.h"

namespace ns3 {

Expand Down Expand Up @@ -101,7 +102,11 @@ class TcpCongestionOps : public Object
* \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)
{
NS_UNUSED (tcb);
NS_UNUSED (segmentsAcked);
}

/**
* \brief Timing information on received ACK
Expand Down Expand Up @@ -154,6 +159,36 @@ class TcpCongestionOps : public Object
NS_UNUSED (tcb);
NS_UNUSED (event);
}

/**
* \brief Returns true when Congestion Control Algorithm implements CongControl
*
* \return true if CC implements CongControl function
*/
virtual bool HasCongControl () const
{
return false;
}

/**
* \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)
{
NS_UNUSED (tcb);
NS_UNUSED (rc);
NS_UNUSED (rs);
}

// Present in Linux but not in ns-3 yet:
/* call when ack arrives (optional) */
// void (*in_ack_event)(struct sock *sk, u32 flags);
Expand Down
22 changes: 7 additions & 15 deletions src/internet/model/tcp-prr-recovery.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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);
Expand All @@ -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)
Expand All @@ -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));
}
Expand Down
6 changes: 2 additions & 4 deletions src/internet/model/tcp-prr-recovery.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,9 @@ class TcpPrrRecovery : public TcpClassicRecovery
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;

Expand All @@ -87,7 +86,6 @@ class TcpPrrRecovery : public TcpClassicRecovery
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
Expand Down
Loading