tcp: Feed RateOps from TcpSocketBase

(incorporating comments from Natale P.)
This commit is contained in:
Vivek Jain
2018-06-18 23:31:09 +02:00
committed by Tom Henderson
parent 3911b5f19f
commit 3024805d16
2 changed files with 44 additions and 21 deletions

View File

@@ -58,6 +58,7 @@
#include "tcp-option-sack.h"
#include "tcp-congestion-ops.h"
#include "tcp-recovery-ops.h"
#include "ns3/tcp-rate-ops.h"
#include <math.h>
#include <algorithm>
@@ -243,6 +244,7 @@ TcpSocketBase::TcpSocketBase (void)
m_rxBuffer = CreateObject<TcpRxBuffer> ();
m_txBuffer = CreateObject<TcpTxBuffer> ();
m_tcb = CreateObject<TcpSocketState> ();
m_rateOps = CreateObject <TcpRateLinux> ();
m_tcb->m_currentPacingRate = m_tcb->m_maxPacingRate;
m_pacingTimer.SetFunction (&TcpSocketBase::NotifyPacingPerformed, this);
@@ -370,6 +372,8 @@ TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock)
m_recoveryOps = sock.m_recoveryOps->Fork ();
}
m_rateOps = CreateObject <TcpRateLinux> ();
bool ok;
ok = m_tcb->TraceConnectWithoutContext ("CongestionWindow",
@@ -801,6 +805,11 @@ TcpSocketBase::Send (Ptr<Packet> p, uint32_t flags)
m_errno = ERROR_SHUTDOWN;
return -1;
}
m_rateOps->CalculateAppLimited(m_tcb->m_cWnd, m_tcb->m_bytesInFlight, m_tcb->m_segmentSize,
m_txBuffer->TailSequence (), m_tcb->m_nextTxSequence,
m_txBuffer->GetLost (), m_txBuffer->GetRetransmitsCount ());
// Submit the data to lower layers
NS_LOG_LOGIC ("txBufSize=" << m_txBuffer->Size () << " state " << TcpStateName[m_state]);
if ((m_state == ESTABLISHED || m_state == CLOSE_WAIT) && AvailableWindow () > 0)
@@ -1529,7 +1538,7 @@ TcpSocketBase::ReadOptions (const TcpHeader &tcpHeader, uint32_t *bytesSacked)
}
void
TcpSocketBase::EnterRecovery ()
TcpSocketBase::EnterRecovery (uint32_t currentDelivered)
{
NS_LOG_FUNCTION (this);
NS_ASSERT (m_tcb->m_congState != TcpSocketState::CA_RECOVERY);
@@ -1582,7 +1591,7 @@ TcpSocketBase::EnterRecovery ()
}
void
TcpSocketBase::DupAck ()
TcpSocketBase::DupAck (uint32_t currentDelivered)
{
NS_LOG_FUNCTION (this);
// NOTE: We do not count the DupAcks received in CA_LOSS, because we
@@ -1636,7 +1645,7 @@ TcpSocketBase::DupAck ()
// (1) If DupAcks >= DupThresh, go to step (4).
if ((m_dupAckCount == m_retxThresh) && (m_highRxAckMark >= m_recover))
{
EnterRecovery ();
EnterRecovery (currentDelivered);
NS_ASSERT (m_tcb->m_congState == TcpSocketState::CA_RECOVERY);
}
// (2) If DupAcks < DupThresh but IsLost (HighACK + 1) returns true
@@ -1645,7 +1654,7 @@ TcpSocketBase::DupAck ()
// go to step (4).
else if (m_txBuffer->IsLost (m_highRxAckMark + m_tcb->m_segmentSize))
{
EnterRecovery ();
EnterRecovery (currentDelivered);
NS_ASSERT (m_tcb->m_congState == TcpSocketState::CA_RECOVERY);
}
else
@@ -1681,11 +1690,14 @@ TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
// Upon the receipt of any ACK containing SACK information, the
// scoreboard MUST be updated via the Update () routine (done in ReadOptions)
uint32_t bytesSacked = 0;
uint64_t previousDelivered = m_rateOps->GetConnectionRate ().m_delivered;
ReadOptions (tcpHeader, &bytesSacked);
SequenceNumber32 ackNumber = tcpHeader.GetAckNumber ();
SequenceNumber32 oldHeadSequence = m_txBuffer->HeadSequence ();
m_txBuffer->DiscardUpTo (ackNumber);
m_txBuffer->DiscardUpTo (ackNumber, MakeCallback (&TcpRateOps::SkbDelivered, m_rateOps));
uint32_t currentDelivered = static_cast<uint32_t> (m_rateOps->GetConnectionRate ().m_delivered - previousDelivered);
if (ackNumber > oldHeadSequence && (m_tcb->m_ecnState != TcpSocketState::ECN_DISABLED) && (tcpHeader.GetFlags () & TcpHeader::ECE))
{
@@ -1704,7 +1716,7 @@ TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
// RFC 6675 Section 5: 2nd, 3rd paragraph and point (A), (B) implementation
// are inside the function ProcessAck
ProcessAck (ackNumber, (bytesSacked > 0), oldHeadSequence);
ProcessAck (ackNumber, (bytesSacked > 0), currentDelivered, oldHeadSequence);
// If there is any data piggybacked, store it into m_rxBuffer
if (packet->GetSize () > 0)
@@ -1718,8 +1730,8 @@ TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
}
void
TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpdated,
const SequenceNumber32 &oldHeadSequence)
TcpSocketBase::ProcessAck(const SequenceNumber32 &ackNumber, bool scoreboardUpdated,
uint32_t currentDelivered, const SequenceNumber32 &oldHeadSequence)
{
NS_LOG_FUNCTION (this << ackNumber << scoreboardUpdated);
// RFC 6675, Section 5, 2nd paragraph:
@@ -1728,6 +1740,7 @@ TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpd
bool exitedFastRecovery = false;
uint32_t oldDupAckCount = m_dupAckCount; // remember the old value
m_tcb->m_lastAckedSeq = ackNumber; // Update lastAckedSeq
uint32_t bytesAcked = 0;
/* In RFC 5681 the definition of duplicate acknowledgment was strict:
*
@@ -1765,7 +1778,7 @@ TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpd
{
// loss recovery check is done inside this function thanks to
// the congestion state machine
DupAck ();
DupAck (currentDelivered);
}
if (ackNumber == oldHeadSequence
@@ -1791,13 +1804,15 @@ TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpd
{
// Please remember that, with SACK, we can enter here even if we
// received a dupack.
uint32_t bytesAcked = ackNumber - oldHeadSequence;
bytesAcked = ackNumber - oldHeadSequence;
uint32_t segsAcked = bytesAcked / m_tcb->m_segmentSize;
m_bytesAckedNotProcessed += bytesAcked % m_tcb->m_segmentSize;
bytesAcked -= bytesAcked % m_tcb->m_segmentSize;
if (m_bytesAckedNotProcessed >= m_tcb->m_segmentSize)
{
segsAcked += 1;
bytesAcked += m_tcb->m_segmentSize;
m_bytesAckedNotProcessed -= m_tcb->m_segmentSize;
}
@@ -2841,13 +2856,13 @@ TcpSocketBase::SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool with
{
NS_LOG_FUNCTION (this << seq << maxSize << withAck);
bool isRetransmission = false;
if (seq != m_tcb->m_highTxMark)
{
isRetransmission = true;
}
bool isStartOfTransmission = BytesInFlight () == 0U;
TcpTxItem *outItem = m_txBuffer->CopyFromSequence (maxSize, seq);
Ptr<Packet> p = m_txBuffer->CopyFromSequence (maxSize, seq)->GetPacketCopy ();
m_rateOps->SkbSent(outItem, isStartOfTransmission);
bool isRetransmission = outItem->IsRetrans ();
Ptr<Packet> p = outItem->GetPacketCopy ();
uint32_t sz = p->GetSize (); // Size of packet
uint8_t flags = withAck ? TcpHeader::ACK : 0;
uint32_t remainingData = m_txBuffer->SizeFromSequence (seq + SequenceNumber32 (sz));
@@ -2964,7 +2979,7 @@ TcpSocketBase::SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool with
}
// Notify the application of the data being sent unless this is a retransmit
if (seq + sz > m_tcb->m_highTxMark)
if (!isRetransmission)
{
Simulator::ScheduleNow (&TcpSocketBase::NotifyDataSent, this,
(seq + sz - m_tcb->m_highTxMark.Get ()));
@@ -3952,7 +3967,7 @@ TcpSocketBase::ProcessOptionSack (const Ptr<const TcpOption> option)
NS_LOG_FUNCTION (this << option);
Ptr<const TcpOptionSack> s = DynamicCast<const TcpOptionSack> (option);
return m_txBuffer->Update (s->GetSackList ());
return m_txBuffer->Update (s->GetSackList (), MakeCallback (&TcpRateOps::SkbDelivered, m_rateOps));
}
void

View File

@@ -49,6 +49,7 @@ class TcpTxBuffer;
class TcpOption;
class Ipv4Interface;
class Ipv6Interface;
class TcpRateOps;
/**
* \ingroup tcp
@@ -965,9 +966,11 @@ protected:
* \param scoreboardUpdated if true indicates that the scoreboard has been
* \param oldHeadSequence value of HeadSequence before ack
* updated with SACK information
* \param currentDelivered The number of bytes (S)ACKed
* \return the number of bytes (newly) acked, or 0 if it was a dupack
*/
virtual void ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpdated,
const SequenceNumber32 &oldHeadSequence);
uint32_t currentDelivered, const SequenceNumber32 &oldHeadSequence);
/**
* \brief Recv of a data, put into buffer, call L7 to get it if necessary
@@ -1002,13 +1005,17 @@ protected:
/**
* \brief Dupack management
*
* \param currentDelivered Current (S)ACKed bytes
*/
void DupAck ();
void DupAck (uint32_t currentDelivered);
/**
* \brief Enter the CA_RECOVERY, and retransmit the head
*
* \param currentDelivered Currently (S)ACKed bytes
*/
void EnterRecovery ();
void EnterRecovery (uint32_t currentDelivered);
/**
* \brief An RTO event happened
@@ -1252,6 +1259,7 @@ protected:
Ptr<TcpSocketState> m_tcb; //!< Congestion control information
Ptr<TcpCongestionOps> m_congestionControl; //!< Congestion control
Ptr<TcpRecoveryOps> m_recoveryOps; //!< Recovery Algorithm
Ptr<TcpRateOps> m_rateOps; //!< Rate operations
// Guesses over the other connection end
bool m_isFirstPartialAck {true}; //!< First partial ACK during RECOVERY