tcp: Feed RateOps from TcpSocketBase
(incorporating comments from Natale P.)
This commit is contained in:
committed by
Tom Henderson
parent
3911b5f19f
commit
3024805d16
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user