tcp: Move m_rxBuffer in TcpSocketState and add SendEmptyPacket callback

This commit is contained in:
Vivek Jain
2018-05-31 15:57:40 +05:30
committed by Tom Henderson
parent 7281bff876
commit c3265b7d44
6 changed files with 99 additions and 67 deletions

View File

@@ -241,14 +241,17 @@ TcpSocketBase::TcpSocketBase (void)
: TcpSocket ()
{
NS_LOG_FUNCTION (this);
m_rxBuffer = CreateObject<TcpRxBuffer> ();
m_txBuffer = CreateObject<TcpTxBuffer> ();
m_tcb = CreateObject<TcpSocketState> ();
m_rateOps = CreateObject <TcpRateLinux> ();
m_tcb->m_rxBuffer = CreateObject<TcpRxBuffer> ();
m_tcb->m_currentPacingRate = m_tcb->m_maxPacingRate;
m_pacingTimer.SetFunction (&TcpSocketBase::NotifyPacingPerformed, this);
m_tcb->m_sendEmptyPacketCallback = MakeCallback (&TcpSocketBase::SendEmptyPacket, this);
bool ok;
ok = m_tcb->TraceConnectWithoutContext ("CongestionWindow",
@@ -356,8 +359,8 @@ TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock)
SetSendCallback (vPSUI);
SetRecvCallback (vPS);
m_txBuffer = CopyObject (sock.m_txBuffer);
m_rxBuffer = CopyObject (sock.m_rxBuffer);
m_tcb = CopyObject (sock.m_tcb);
m_tcb->m_rxBuffer = CopyObject (sock.m_tcb->m_rxBuffer);
m_tcb->m_currentPacingRate = m_tcb->m_maxPacingRate;
m_pacingTimer.SetFunction (&TcpSocketBase::NotifyPacingPerformed, this);
@@ -373,6 +376,10 @@ TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock)
}
m_rateOps = CreateObject <TcpRateLinux> ();
if (m_tcb->m_sendEmptyPacketCallback.IsNull ())
{
m_tcb->m_sendEmptyPacketCallback = MakeCallback (&TcpSocketBase::SendEmptyPacket, this);
}
bool ok;
@@ -722,7 +729,7 @@ TcpSocketBase::Close (void)
/// \internal
/// First we check to see if there is any unread rx data.
/// \bugid{426} claims we should send reset in this case.
if (m_rxBuffer->Size () != 0)
if (m_tcb->m_rxBuffer->Size () != 0)
{
NS_LOG_WARN ("Socket " << this << " << unread rx data during close. Sending reset." <<
"This is probably due to a bad sink application; check its code");
@@ -846,11 +853,11 @@ TcpSocketBase::Recv (uint32_t maxSize, uint32_t flags)
{
NS_LOG_FUNCTION (this);
NS_ABORT_MSG_IF (flags, "use of flags is not supported in TcpSocketBase::Recv()");
if (m_rxBuffer->Size () == 0 && m_state == CLOSE_WAIT)
if (m_tcb->m_rxBuffer->Size () == 0 && m_state == CLOSE_WAIT)
{
return Create<Packet> (); // Send EOF on connection close
}
Ptr<Packet> outPacket = m_rxBuffer->Extract (maxSize);
Ptr<Packet> outPacket = m_tcb->m_rxBuffer->Extract (maxSize);
return outPacket;
}
@@ -892,7 +899,7 @@ uint32_t
TcpSocketBase::GetRxAvailable (void) const
{
NS_LOG_FUNCTION (this);
return m_rxBuffer->Available ();
return m_tcb->m_rxBuffer->Available ();
}
/* Inherit from Socket class: Return local address:port */
@@ -1095,11 +1102,11 @@ TcpSocketBase::OutOfRange (SequenceNumber32 head, SequenceNumber32 tail) const
if (m_state == LAST_ACK || m_state == CLOSING || m_state == CLOSE_WAIT)
{ // In LAST_ACK and CLOSING states, it only wait for an ACK and the
// sequence number must equals to m_rxBuffer->NextRxSequence ()
return (m_rxBuffer->NextRxSequence () != head);
return (m_tcb->m_rxBuffer->NextRxSequence () != head);
}
// In all other cases, check if the sequence number is in range
return (tail < m_rxBuffer->NextRxSequence () || m_rxBuffer->MaxRxSequence () <= head);
return (tail < m_tcb->m_rxBuffer->NextRxSequence () || m_tcb->m_rxBuffer->MaxRxSequence () <= head);
}
/* Function called by the L3 protocol when it received a packet to pass on to
@@ -1226,8 +1233,8 @@ TcpSocketBase::IsValidTcpSegment (const SequenceNumber32 seq, const uint32_t tcp
NS_LOG_WARN ("At state " << TcpStateName[m_state] <<
" received packet of seq [" << seq <<
":" << seq + tcpPayloadSize <<
") out of range [" << m_rxBuffer->NextRxSequence () << ":" <<
m_rxBuffer->MaxRxSequence () << ")");
") out of range [" << m_tcb->m_rxBuffer->NextRxSequence () << ":" <<
m_tcb->m_rxBuffer->MaxRxSequence () << ")");
// Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
SendEmptyPacket (TcpHeader::ACK);
return false;
@@ -1374,7 +1381,7 @@ TcpSocketBase::DoForwardUp (Ptr<Packet> packet, const Address &fromAddress,
Ptr<Packet> p = Create<Packet> ();
h.SetFlags (TcpHeader::RST);
h.SetSequenceNumber (m_tcb->m_nextTxSequence);
h.SetAckNumber (m_rxBuffer->NextRxSequence ());
h.SetAckNumber (m_tcb->m_rxBuffer->NextRxSequence ());
h.SetSourcePort (tcpHeader.GetDestinationPort ());
h.SetDestinationPort (tcpHeader.GetSourcePort ());
h.SetWindowSize (AdvertisedWindowSize ());
@@ -1478,7 +1485,7 @@ TcpSocketBase::ProcessEstablished (Ptr<Packet> packet, const TcpHeader& tcpHeade
else if (tcpflags == 0)
{ // No flags means there is only data
ReceivedData (packet, tcpHeader);
if (m_rxBuffer->Finished ())
if (m_tcb->m_rxBuffer->Finished ())
{
PeerClose (packet, tcpHeader);
}
@@ -2080,8 +2087,8 @@ TcpSocketBase::ProcessSynSent (Ptr<Packet> packet, const TcpHeader& tcpHeader)
NS_LOG_DEBUG ("SYN_SENT -> SYN_RCVD");
m_state = SYN_RCVD;
m_synCount = m_synRetries;
m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1));
/* Check if we received an ECN SYN packet. Change the ECN state of receiver to ECN_IDLE if the traffic is ECN capable and
m_tcb->m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1));
/* Check if we recieved an ECN SYN packet. Change the ECN state of receiver to ECN_IDLE if the traffic is ECN capable and
* sender has sent ECN SYN packet
*/
if (m_ecnMode == EcnMode_t::ClassicEcn && (tcpflags & (TcpHeader::CWR | TcpHeader::ECE)) == (TcpHeader::CWR | TcpHeader::ECE))
@@ -2106,7 +2113,7 @@ TcpSocketBase::ProcessSynSent (Ptr<Packet> packet, const TcpHeader& tcpHeader)
m_state = ESTABLISHED;
m_connected = true;
m_retxEvent.Cancel ();
m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1));
m_tcb->m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1));
m_tcb->m_highTxMark = ++m_tcb->m_nextTxSequence;
m_txBuffer->SetHeadSequence (m_tcb->m_nextTxSequence);
SendEmptyPacket (TcpHeader::ACK);
@@ -2190,7 +2197,7 @@ TcpSocketBase::ProcessSynRcvd (Ptr<Packet> packet, const TcpHeader& tcpHeader,
}
else if (tcpflags == TcpHeader::SYN)
{ // Probably the peer lost my SYN+ACK
m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1));
m_tcb->m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1));
/* Check if we received an ECN SYN packet. Change the ECN state of receiver to ECN_IDLE if sender has sent an ECN SYN
* packet and the traffic is ECN Capable
*/
@@ -2209,7 +2216,7 @@ TcpSocketBase::ProcessSynRcvd (Ptr<Packet> packet, const TcpHeader& tcpHeader,
}
else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
{
if (tcpHeader.GetSequenceNumber () == m_rxBuffer->NextRxSequence ())
if (tcpHeader.GetSequenceNumber () == m_tcb->m_rxBuffer->NextRxSequence ())
{ // In-sequence FIN before connection complete. Set up connection and close.
m_connected = true;
m_retxEvent.Cancel ();
@@ -2280,7 +2287,7 @@ TcpSocketBase::ProcessWait (Ptr<Packet> packet, const TcpHeader& tcpHeader)
{ // Process the ACK first
ReceivedAck (packet, tcpHeader);
}
m_rxBuffer->SetFinSequence (tcpHeader.GetSequenceNumber ());
m_tcb->m_rxBuffer->SetFinSequence (tcpHeader.GetSequenceNumber ());
}
else if (tcpflags == TcpHeader::SYN || tcpflags == (TcpHeader::SYN | TcpHeader::ACK))
{ // Duplicated SYN or SYN+ACK, possibly due to spurious retransmission
@@ -2299,7 +2306,7 @@ TcpSocketBase::ProcessWait (Ptr<Packet> packet, const TcpHeader& tcpHeader)
}
// Check if the close responder sent an in-sequence FIN, if so, respond ACK
if ((m_state == FIN_WAIT_1 || m_state == FIN_WAIT_2) && m_rxBuffer->Finished ())
if ((m_state == FIN_WAIT_1 || m_state == FIN_WAIT_2) && m_tcb->m_rxBuffer->Finished ())
{
if (m_state == FIN_WAIT_1)
{
@@ -2334,7 +2341,7 @@ TcpSocketBase::ProcessClosing (Ptr<Packet> packet, const TcpHeader& tcpHeader)
if (tcpflags == TcpHeader::ACK)
{
if (tcpHeader.GetSequenceNumber () == m_rxBuffer->NextRxSequence ())
if (tcpHeader.GetSequenceNumber () == m_tcb->m_rxBuffer->NextRxSequence ())
{ // This ACK corresponds to the FIN sent
TimeWait ();
}
@@ -2370,7 +2377,7 @@ TcpSocketBase::ProcessLastAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
}
else if (tcpflags == TcpHeader::ACK)
{
if (tcpHeader.GetSequenceNumber () == m_rxBuffer->NextRxSequence ())
if (tcpHeader.GetSequenceNumber () == m_tcb->m_rxBuffer->NextRxSequence ())
{ // This ACK corresponds to the FIN sent. This socket closed peacefully.
CloseAndNotify ();
}
@@ -2398,13 +2405,13 @@ TcpSocketBase::PeerClose (Ptr<Packet> p, const TcpHeader& tcpHeader)
NS_LOG_FUNCTION (this << tcpHeader);
// Ignore all out of range packets
if (tcpHeader.GetSequenceNumber () < m_rxBuffer->NextRxSequence ()
|| tcpHeader.GetSequenceNumber () > m_rxBuffer->MaxRxSequence ())
if (tcpHeader.GetSequenceNumber () < m_tcb->m_rxBuffer->NextRxSequence ()
|| tcpHeader.GetSequenceNumber () > m_tcb->m_rxBuffer->MaxRxSequence ())
{
return;
}
// For any case, remember the FIN position in rx buffer first
m_rxBuffer->SetFinSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (p->GetSize ()));
m_tcb->m_rxBuffer->SetFinSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (p->GetSize ()));
NS_LOG_LOGIC ("Accepted FIN at seq " << tcpHeader.GetSequenceNumber () + SequenceNumber32 (p->GetSize ()));
// If there is any piggybacked data, process it
if (p->GetSize ())
@@ -2412,7 +2419,7 @@ TcpSocketBase::PeerClose (Ptr<Packet> p, const TcpHeader& tcpHeader)
ReceivedData (p, tcpHeader);
}
// Return if FIN is out of sequence, otherwise move to CLOSE_WAIT state by DoPeerClose
if (!m_rxBuffer->Finished ())
if (!m_tcb->m_rxBuffer->Finished ())
{
return;
}
@@ -2528,7 +2535,7 @@ TcpSocketBase::SendEmptyPacket (uint8_t flags)
header.SetFlags (flags);
header.SetSequenceNumber (s);
header.SetAckNumber (m_rxBuffer->NextRxSequence ());
header.SetAckNumber (m_tcb->m_rxBuffer->NextRxSequence ());
if (m_endPoint != nullptr)
{
header.SetSourcePort (m_endPoint->GetLocalPort ());
@@ -2595,11 +2602,11 @@ TcpSocketBase::SendEmptyPacket (uint8_t flags)
{
m_highTxAck = header.GetAckNumber ();
}
if (m_sackEnabled && m_rxBuffer->GetSackListSize () > 0)
if (m_sackEnabled && m_tcb->m_rxBuffer->GetSackListSize () > 0)
{
AddOptionSack (header);
}
NS_LOG_INFO ("Sending a pure ACK, acking seq " << m_rxBuffer->NextRxSequence ());
NS_LOG_INFO ("Sending a pure ACK, acking seq " << m_tcb->m_rxBuffer->NextRxSequence ());
}
m_txTrace (p, header, this);
@@ -2755,7 +2762,7 @@ TcpSocketBase::CompleteFork (Ptr<Packet> p, const TcpHeader& h,
m_dataRetrCount = m_dataRetries;
SetupCallback ();
// Set the sequence number and send SYN+ACK
m_rxBuffer->SetNextRxSequence (h.GetSequenceNumber () + SequenceNumber32 (1));
m_tcb->m_rxBuffer->SetNextRxSequence (h.GetSequenceNumber () + SequenceNumber32 (1));
/* Check if we received an ECN SYN packet. Change the ECN state of receiver to ECN_IDLE if sender has sent an ECN SYN
* packet and the traffic is ECN Capable
@@ -2948,7 +2955,7 @@ TcpSocketBase::SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool with
TcpHeader header;
header.SetFlags (flags);
header.SetSequenceNumber (seq);
header.SetAckNumber (m_rxBuffer->NextRxSequence ());
header.SetAckNumber (m_tcb->m_rxBuffer->NextRxSequence ());
if (m_endPoint)
{
header.SetSourcePort (m_endPoint->GetLocalPort ());
@@ -3235,15 +3242,15 @@ TcpSocketBase::AdvertisedWindowSize (bool scale) const
// We don't want to advertise 0 after a FIN is received. So, we just use
// the previous value of the advWnd.
if (m_rxBuffer->GotFin ())
if (m_tcb->m_rxBuffer->GotFin ())
{
w = m_advWnd;
}
else
{
NS_ASSERT_MSG (m_rxBuffer->MaxRxSequence () - m_rxBuffer->NextRxSequence () >= 0,
NS_ASSERT_MSG (m_tcb->m_rxBuffer->MaxRxSequence () - m_tcb->m_rxBuffer->NextRxSequence () >= 0,
"Unexpected sequence number values");
w = static_cast<uint32_t> (m_rxBuffer->MaxRxSequence () - m_rxBuffer->NextRxSequence ());
w = static_cast<uint32_t> (m_tcb->m_rxBuffer->MaxRxSequence () - m_tcb->m_rxBuffer->NextRxSequence ());
}
// Ugly, but we are not modifying the state, that variable
@@ -3274,8 +3281,8 @@ TcpSocketBase::ReceivedData (Ptr<Packet> p, const TcpHeader& tcpHeader)
" pkt size=" << p->GetSize () );
// Put into Rx buffer
SequenceNumber32 expectedSeq = m_rxBuffer->NextRxSequence ();
if (!m_rxBuffer->Add (p, tcpHeader))
SequenceNumber32 expectedSeq = m_tcb->m_rxBuffer->NextRxSequence ();
if (!m_tcb->m_rxBuffer->Add (p, tcpHeader))
{ // Insert failed: No data or RX buffer full
if (m_tcb->m_ecnState == TcpSocketState::ECN_CE_RCVD || m_tcb->m_ecnState == TcpSocketState::ECN_SENDING_ECE)
{
@@ -3290,7 +3297,7 @@ TcpSocketBase::ReceivedData (Ptr<Packet> p, const TcpHeader& tcpHeader)
return;
}
// Notify app to receive if necessary
if (expectedSeq < m_rxBuffer->NextRxSequence ())
if (expectedSeq < m_tcb->m_rxBuffer->NextRxSequence ())
{ // NextRxSeq advanced, we have something to send to the app
if (!m_shutdownRecv)
{
@@ -3303,14 +3310,14 @@ TcpSocketBase::ReceivedData (Ptr<Packet> p, const TcpHeader& tcpHeader)
}
// If we received FIN before and now completed all "holes" in rx buffer,
// invoke peer close procedure
if (m_rxBuffer->Finished () && (tcpHeader.GetFlags () & TcpHeader::FIN) == 0)
if (m_tcb->m_rxBuffer->Finished () && (tcpHeader.GetFlags () & TcpHeader::FIN) == 0)
{
DoPeerClose ();
return;
}
}
// Now send a new ACK packet acknowledging all received and delivered data
if (m_rxBuffer->Size () > m_rxBuffer->Available () || m_rxBuffer->NextRxSequence () > expectedSeq + p->GetSize ())
if (m_tcb->m_rxBuffer->Size () > m_tcb->m_rxBuffer->Available () || m_tcb->m_rxBuffer->NextRxSequence () > expectedSeq + p->GetSize ())
{ // A gap exists in the buffer, or we filled a gap: Always ACK
m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_NON_DELAYED_ACK);
if (m_tcb->m_ecnState == TcpSocketState::ECN_CE_RCVD || m_tcb->m_ecnState == TcpSocketState::ECN_SENDING_ECE)
@@ -3343,8 +3350,13 @@ TcpSocketBase::ReceivedData (Ptr<Packet> p, const TcpHeader& tcpHeader)
SendEmptyPacket (TcpHeader::ACK);
}
}
else if (!m_delAckEvent.IsExpired ())
{
m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_DELAYED_ACK);
}
else if (m_delAckEvent.IsExpired ())
{
m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_DELAYED_ACK);
m_delAckEvent = Simulator::Schedule (m_delAckTimeout,
&TcpSocketBase::DelAckTimeout, this);
NS_LOG_LOGIC (this << " scheduled delayed ACK at " <<
@@ -3635,7 +3647,7 @@ TcpSocketBase::PersistTimeout ()
m_txBuffer->ResetLastSegmentSent ();
TcpHeader tcpHeader;
tcpHeader.SetSequenceNumber (m_tcb->m_nextTxSequence);
tcpHeader.SetAckNumber (m_rxBuffer->NextRxSequence ());
tcpHeader.SetAckNumber (m_tcb->m_rxBuffer->NextRxSequence ());
tcpHeader.SetWindowSize (AdvertisedWindowSize ());
if (m_endPoint != nullptr)
{
@@ -3652,11 +3664,27 @@ TcpSocketBase::PersistTimeout ()
if (m_tcb->m_ecnState != TcpSocketState::ECN_DISABLED)
{
SocketIpTosTag ipTosTag;
ipTosTag.SetTos (MarkEcnEct0 (0));
//Classic traffic have ECT0 flags whereas L4S have ECT1 flags set
if (m_congestionControl->GetName () == "TcpDctcp")
{
ipTosTag.SetTos (MarkEcnEct1 (0));
}
else
{
ipTosTag.SetTos (MarkEcnEct0 (0));
}
p->AddPacketTag (ipTosTag);
SocketIpv6TclassTag ipTclassTag;
ipTclassTag.SetTclass (MarkEcnEct0 (0));
//Classic traffic have ECT0 flags whereas L4S have ECT1 flags set
if (m_congestionControl->GetName () == "TcpDctcp")
{
ipTclassTag.SetTclass (MarkEcnEct1 (0));
}
else
{
ipTclassTag.SetTclass (MarkEcnEct0 (0));
}
p->AddPacketTag (ipTclassTag);
}
m_txTrace (p, tcpHeader, this);
@@ -3759,7 +3787,7 @@ TcpSocketBase::SetRcvBufSize (uint32_t size)
NS_LOG_FUNCTION (this << size);
uint32_t oldSize = GetRcvBufSize ();
m_rxBuffer->SetMaxBufferSize (size);
m_tcb->m_rxBuffer->SetMaxBufferSize (size);
/* The size has (manually) increased. Actively inform the other end to prevent
* stale zero-window states.
@@ -3782,7 +3810,7 @@ TcpSocketBase::SetRcvBufSize (uint32_t size)
uint32_t
TcpSocketBase::GetRcvBufSize (void) const
{
return m_rxBuffer->MaxBufferSize ();
return m_tcb->m_rxBuffer->MaxBufferSize ();
}
void
@@ -3942,7 +3970,7 @@ uint8_t
TcpSocketBase::CalculateWScale () const
{
NS_LOG_FUNCTION (this);
uint32_t maxSpace = m_rxBuffer->MaxBufferSize ();
uint32_t maxSpace = m_tcb->m_rxBuffer->MaxBufferSize ();
uint8_t scale = 0;
while (maxSpace > m_maxWinSize)
@@ -3958,7 +3986,7 @@ TcpSocketBase::CalculateWScale () const
}
NS_LOG_INFO ("Node " << m_node->GetId () << " calculated wscale factor of " <<
static_cast<int> (scale) << " for buffer size " << m_rxBuffer->MaxBufferSize ());
static_cast<int> (scale) << " for buffer size " << m_tcb->m_rxBuffer->MaxBufferSize ());
return scale;
}
@@ -4022,7 +4050,7 @@ TcpSocketBase::AddOptionSack (TcpHeader& header)
uint8_t optionLenAvail = header.GetMaxOptionLength () - header.GetOptionLength ();
uint8_t allowedSackBlocks = (optionLenAvail - 2) / 8;
TcpOptionSack::SackList sackList = m_rxBuffer->GetSackList ();
TcpOptionSack::SackList sackList = m_tcb->m_rxBuffer->GetSackList ();
if (allowedSackBlocks == 0 || sackList.empty ())
{
NS_LOG_LOGIC ("No space available or sack list empty, not adding sack blocks");
@@ -4061,7 +4089,7 @@ TcpSocketBase::ProcessOptionTimestamp (const Ptr<const TcpOption> option,
m_tcb->m_rcvTimestampValue = ts->GetTimestamp ();
m_tcb->m_rcvTimestampEchoReply = ts->GetEcho ();
if (seq == m_rxBuffer->NextRxSequence () && seq <= m_highTxAck)
if (seq == m_tcb->m_rxBuffer->NextRxSequence () && seq <= m_highTxAck)
{
m_timestampToEcho = ts->GetTimestamp ();
}
@@ -4164,7 +4192,7 @@ TcpSocketBase::GetTxBuffer (void) const
Ptr<TcpRxBuffer>
TcpSocketBase::GetRxBuffer (void) const
{
return m_rxBuffer;
return m_tcb->m_rxBuffer;
}
void

View File

@@ -1217,8 +1217,7 @@ protected:
Ptr<RttEstimator> m_rtt; //!< Round trip time estimator
// Rx and Tx buffer management
Ptr<TcpRxBuffer> m_rxBuffer; //!< Rx buffer (reordering buffer)
// Tx buffer management
Ptr<TcpTxBuffer> m_txBuffer; //!< Tx buffer
// State-related attributes

View File

@@ -21,6 +21,7 @@
#include "ns3/data-rate.h"
#include "ns3/traced-value.h"
#include "ns3/sequence-number.h"
#include "tcp-rx-buffer.h"
namespace ns3 {
@@ -154,6 +155,8 @@ public:
TracedValue<uint32_t> m_bytesInFlight {0}; //!< Bytes in flight
TracedValue<Time> m_lastRtt {Seconds (0.0)}; //!< Last RTT sample collected
Ptr<TcpRxBuffer> m_rxBuffer; //!< Rx buffer (reordering buffer)
/**
* \brief Get cwnd in segments rather than bytes
*
@@ -173,6 +176,8 @@ public:
{
return m_ssThresh / m_segmentSize;
}
Callback <void, uint8_t> m_sendEmptyPacketCallback;
};
namespace TracedValueCallback {

View File

@@ -128,13 +128,13 @@ TcpSocketAdvertisedWindowProxy::AdvertisedWindowSize (bool scale) const
uint16_t newAwnd = TcpSocketMsgBase::AdvertisedWindowSize (scale);
uint16_t oldAwnd = OldAdvertisedWindowSize (scale);
if (!m_rxBuffer->Finished ())
if (!m_tcb->m_rxBuffer->Finished ())
{
// The calculated windows will only be exactly equal if there is no data
// in the receive buffer yet.
if (newAwnd != oldAwnd)
{
uint32_t available = m_rxBuffer->Available ();
uint32_t available = m_tcb->m_rxBuffer->Available ();
// If the values differ, make sure this is only due to the single segment
// the socket just got, which has not yet been read by the application.
// Therefore, the difference should be exactly the size of one segment
@@ -180,13 +180,13 @@ uint16_t
TcpSocketAdvertisedWindowProxy::OldAdvertisedWindowSize (bool scale) const
{
NS_LOG_FUNCTION (this << scale);
//NS_LOG_DEBUG ("MaxRxSequence () = " << m_rxBuffer->MaxRxSequence ());
//NS_LOG_DEBUG ("NextRxSequence () = " << m_rxBuffer->NextRxSequence ());
//NS_LOG_DEBUG ("MaxBufferSize () = " << m_rxBuffer->MaxBufferSize ());
//NS_LOG_DEBUG ("MaxRxSequence () = " << m_tcb->m_rxBuffer->MaxRxSequence ());
//NS_LOG_DEBUG ("NextRxSequence () = " << m_tcb->m_rxBuffer->NextRxSequence ());
//NS_LOG_DEBUG ("MaxBufferSize () = " << m_tcb->m_rxBuffer->MaxBufferSize ());
//NS_LOG_DEBUG ("m_rcvWindShift = " << static_cast<uint16_t> (m_rcvWindShift));
//NS_LOG_DEBUG ("m_maxWinSize = " << m_maxWinSize);
//NS_LOG_DEBUG ("Available () = " << m_rxBuffer->Available ());
uint32_t w = m_rxBuffer->MaxBufferSize ();
//NS_LOG_DEBUG ("Available () = " << m_tcb->m_rxBuffer->Available ());
uint32_t w = m_tcb->m_rxBuffer->MaxBufferSize ();
if (scale)
{
@@ -262,11 +262,11 @@ TcpDropRatioErrorModel::ShouldDrop (const Ipv4Header &ipHeader, const TcpHeader
*
* In TcpSocketBase, the advertised window is now calculated as
*
* m_rxBuffer->MaxRxSequence () - m_rxBuffer->NextRxSequence ()
* m_tcb->m_rxBuffer->MaxRxSequence () - m_tcb->m_rxBuffer->NextRxSequence ()
*
* instead of the previous
*
* m_rxBuffer->MaxBufferSize ()
* m_tcb->m_rxBuffer->MaxBufferSize ()
*
* This change was introduced with regard to situations in which the receiviing
* application does not read from the socket as fast as possible (see bug 2559

View File

@@ -326,7 +326,7 @@ TcpSocketCongestedRouter::SendDataPacket (SequenceNumber32 seq, uint32_t maxSize
TcpHeader header;
header.SetFlags (flags);
header.SetSequenceNumber (seq);
header.SetAckNumber (m_rxBuffer->NextRxSequence ());
header.SetAckNumber (m_tcb->m_rxBuffer->NextRxSequence ());
if (m_endPoint)
{
header.SetSourcePort (m_endPoint->GetLocalPort ());

View File

@@ -870,12 +870,12 @@ TcpGeneralTest::GetRxBuffer (SocketWho who)
{
if (who == SENDER)
{
return DynamicCast<TcpSocketMsgBase> (m_senderSocket)->m_rxBuffer;
return DynamicCast<TcpSocketMsgBase> (m_senderSocket)->m_tcb->m_rxBuffer;
}
else if (who == RECEIVER)
{
return DynamicCast<TcpSocketMsgBase> (m_receiverSocket)->m_rxBuffer;
return DynamicCast<TcpSocketMsgBase> (m_receiverSocket)->m_tcb->m_rxBuffer;
}
else
{
@@ -1173,7 +1173,7 @@ TcpSocketSmallAcks::SendEmptyPacket (uint8_t flags)
// Actual division in small acks.
if (hasSyn || hasFin)
{
header.SetAckNumber (m_rxBuffer->NextRxSequence ());
header.SetAckNumber (m_tcb->m_rxBuffer->NextRxSequence ());
}
else
{
@@ -1181,11 +1181,11 @@ TcpSocketSmallAcks::SendEmptyPacket (uint8_t flags)
ackSeq = m_lastAckedSeq + m_bytesToAck;
if (m_bytesLeftToBeAcked == 0 && m_rxBuffer->NextRxSequence () > m_lastAckedSeq)
if (m_bytesLeftToBeAcked == 0 && m_tcb->m_rxBuffer->NextRxSequence () > m_lastAckedSeq)
{
m_bytesLeftToBeAcked = m_rxBuffer->NextRxSequence ().GetValue () - 1 - m_bytesToAck;
m_bytesLeftToBeAcked = m_tcb->m_rxBuffer->NextRxSequence ().GetValue () - 1 - m_bytesToAck;
}
else if (m_bytesLeftToBeAcked > 0 && m_rxBuffer->NextRxSequence () > m_lastAckedSeq)
else if (m_bytesLeftToBeAcked > 0 && m_tcb->m_rxBuffer->NextRxSequence () > m_lastAckedSeq)
{
m_bytesLeftToBeAcked -= m_bytesToAck;
}
@@ -1257,7 +1257,7 @@ TcpSocketSmallAcks::SendEmptyPacket (uint8_t flags)
}
// send another ACK if bytes remain
if (m_bytesLeftToBeAcked > 0 && m_rxBuffer->NextRxSequence () > m_lastAckedSeq)
if (m_bytesLeftToBeAcked > 0 && m_tcb->m_rxBuffer->NextRxSequence () > m_lastAckedSeq)
{
SendEmptyPacket (flags);
}