internet: added tcp-rtt-estimation test
This commit is contained in:
@@ -164,6 +164,7 @@ TcpGeneralTest::DoRun (void)
|
||||
m_receiverSocket->SetProcessedAckCb (MakeCallback (&TcpGeneralTest::ProcessedAckCb, this));
|
||||
m_receiverSocket->SetRetransmitCb (MakeCallback (&TcpGeneralTest::RtoExpiredCb, this));
|
||||
m_receiverSocket->SetForkCb (MakeCallback (&TcpGeneralTest::ForkCb, this));
|
||||
m_receiverSocket->SetUpdateRttHistoryCb (MakeCallback (&TcpGeneralTest::UpdateRttHistoryCb, this));
|
||||
m_receiverSocket->TraceConnectWithoutContext ("Tx",
|
||||
MakeCallback (&TcpGeneralTest::TxPacketCb, this));
|
||||
m_receiverSocket->TraceConnectWithoutContext ("Rx",
|
||||
@@ -181,6 +182,7 @@ TcpGeneralTest::DoRun (void)
|
||||
m_senderSocket->SetProcessedAckCb (MakeCallback (&TcpGeneralTest::ProcessedAckCb, this));
|
||||
m_senderSocket->SetRetransmitCb (MakeCallback (&TcpGeneralTest::RtoExpiredCb, this));
|
||||
m_senderSocket->SetDataSentCallback (MakeCallback (&TcpGeneralTest::DataSentCb, this));
|
||||
m_senderSocket->SetUpdateRttHistoryCb (MakeCallback (&TcpGeneralTest::UpdateRttHistoryCb, this));
|
||||
m_senderSocket->TraceConnectWithoutContext ("CongestionWindow",
|
||||
MakeCallback (&TcpGeneralTest::CWndTrace, this));
|
||||
m_senderSocket->TraceConnectWithoutContext ("CongState",
|
||||
@@ -334,6 +336,25 @@ TcpGeneralTest::NormalCloseCb (Ptr<Socket> socket)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TcpGeneralTest::UpdateRttHistoryCb (Ptr<const TcpSocketBase> tcp,
|
||||
const SequenceNumber32 & seq, uint32_t sz,
|
||||
bool isRetransmission)
|
||||
{
|
||||
if (tcp->GetNode () == m_receiverSocket->GetNode ())
|
||||
{
|
||||
UpdatedRttHistory (seq, sz, isRetransmission, RECEIVER);
|
||||
}
|
||||
else if (tcp->GetNode () == m_senderSocket->GetNode ())
|
||||
{
|
||||
UpdatedRttHistory (seq, sz, isRetransmission, SENDER);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_FATAL_ERROR ("Closed socket, but not recognized");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TcpGeneralTest::RtoExpiredCb (const Ptr<const TcpSocketState> tcb,
|
||||
const Ptr<const TcpSocketBase> tcp)
|
||||
@@ -775,21 +796,21 @@ TcpSocketMsgBase::Fork (void)
|
||||
}
|
||||
|
||||
void
|
||||
TcpSocketMsgBase::SetRcvAckCb (AckManagementCallback cb)
|
||||
TcpSocketMsgBase::SetRcvAckCb (AckManagementCb cb)
|
||||
{
|
||||
NS_ASSERT (!cb.IsNull ());
|
||||
m_rcvAckCb = cb;
|
||||
}
|
||||
|
||||
void
|
||||
TcpSocketMsgBase::SetProcessedAckCb (AckManagementCallback cb)
|
||||
TcpSocketMsgBase::SetProcessedAckCb (AckManagementCb cb)
|
||||
{
|
||||
NS_ASSERT (!cb.IsNull ());
|
||||
m_processedAckCb = cb;
|
||||
}
|
||||
|
||||
void
|
||||
TcpSocketMsgBase::SetRetransmitCb (RetrCallback cb)
|
||||
TcpSocketMsgBase::SetRetransmitCb (RetrCb cb)
|
||||
{
|
||||
NS_ASSERT (!cb.IsNull ());
|
||||
m_retrCallback = cb;
|
||||
@@ -821,6 +842,24 @@ TcpSocketMsgBase::SetForkCb (Callback<void, Ptr<TcpSocketMsgBase> > cb)
|
||||
m_forkCb = cb;
|
||||
}
|
||||
|
||||
void
|
||||
TcpSocketMsgBase::SetUpdateRttHistoryCb (UpdateRttCallback cb)
|
||||
{
|
||||
NS_ASSERT (!cb.IsNull ());
|
||||
m_updateRttCb = cb;
|
||||
}
|
||||
|
||||
void
|
||||
TcpSocketMsgBase::UpdateRttHistory (const SequenceNumber32 &seq, uint32_t sz,
|
||||
bool isRetransmission)
|
||||
{
|
||||
TcpSocketBase::UpdateRttHistory (seq, sz, isRetransmission);
|
||||
if (!m_updateRttCb.IsNull ())
|
||||
{
|
||||
m_updateRttCb (this, seq, sz, isRetransmission);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TcpSocketMsgBase::CompleteFork (Ptr<Packet> p, const TcpHeader &tcpHeader,
|
||||
const Address &fromAddress, const Address &toAddress)
|
||||
|
||||
@@ -60,9 +60,11 @@ public:
|
||||
}
|
||||
|
||||
typedef Callback<void, Ptr<const Packet>, const TcpHeader&,
|
||||
Ptr<const TcpSocketBase> > AckManagementCallback;
|
||||
Ptr<const TcpSocketBase> > AckManagementCb;
|
||||
typedef Callback<void, Ptr<const TcpSocketState>,
|
||||
Ptr<const TcpSocketBase> > RetrCallback;
|
||||
Ptr<const TcpSocketBase> > RetrCb;
|
||||
typedef Callback<void, Ptr<const TcpSocketBase>, const SequenceNumber32&,
|
||||
uint32_t, bool> UpdateRttCallback;
|
||||
|
||||
/**
|
||||
* \brief Set the callback invoked when an ACK is received (at the beginning
|
||||
@@ -70,7 +72,7 @@ public:
|
||||
*
|
||||
* \param cb callback
|
||||
*/
|
||||
void SetRcvAckCb (AckManagementCallback cb);
|
||||
void SetRcvAckCb (AckManagementCb cb);
|
||||
|
||||
/**
|
||||
* \brief Set the callback invoked when an ACK is received and processed
|
||||
@@ -78,14 +80,14 @@ public:
|
||||
*
|
||||
* \param cb callback
|
||||
*/
|
||||
void SetProcessedAckCb (AckManagementCallback cb);
|
||||
void SetProcessedAckCb (AckManagementCb cb);
|
||||
|
||||
/**
|
||||
* \brief Set the callback invoked after the processing of a retransmit timeout
|
||||
*
|
||||
* \param cb callback
|
||||
*/
|
||||
void SetRetransmitCb (RetrCallback cb);
|
||||
void SetRetransmitCb (RetrCb cb);
|
||||
|
||||
/**
|
||||
* \brief Set the callback invoked after the forking
|
||||
@@ -93,18 +95,28 @@ public:
|
||||
*/
|
||||
void SetForkCb (Callback<void, Ptr<TcpSocketMsgBase> > cb);
|
||||
|
||||
/**
|
||||
* \brief Set the callback invoked when we update rtt history
|
||||
*
|
||||
* \param cb callback
|
||||
*/
|
||||
void SetUpdateRttHistoryCb (UpdateRttCallback cb);
|
||||
|
||||
protected:
|
||||
virtual void ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader);
|
||||
virtual void Retransmit (void);
|
||||
virtual Ptr<TcpSocketBase> Fork (void);
|
||||
virtual void CompleteFork (Ptr<Packet> p, const TcpHeader& tcpHeader,
|
||||
const Address& fromAddress, const Address& toAddress);
|
||||
virtual void UpdateRttHistory (const SequenceNumber32 &seq, uint32_t sz,
|
||||
bool isRetransmission);
|
||||
|
||||
private:
|
||||
AckManagementCallback m_rcvAckCb;
|
||||
AckManagementCallback m_processedAckCb;
|
||||
RetrCallback m_retrCallback;
|
||||
AckManagementCb m_rcvAckCb;
|
||||
AckManagementCb m_processedAckCb;
|
||||
RetrCb m_retrCallback;
|
||||
Callback<void, Ptr<TcpSocketMsgBase> > m_forkCb;
|
||||
UpdateRttCallback m_updateRttCb;
|
||||
};
|
||||
|
||||
|
||||
@@ -129,16 +141,17 @@ public:
|
||||
|
||||
TcpSocketSmallAcks ()
|
||||
: TcpSocketMsgBase (),
|
||||
m_bytesToAck (125),
|
||||
m_bytesLeftToBeAcked (0),
|
||||
m_lastAckedSeq (1)
|
||||
m_bytesToAck (125),
|
||||
m_bytesLeftToBeAcked (0),
|
||||
m_lastAckedSeq (1)
|
||||
{
|
||||
}
|
||||
|
||||
TcpSocketSmallAcks (const TcpSocketSmallAcks &other) : TcpSocketMsgBase (other),
|
||||
m_bytesToAck (other.m_bytesToAck),
|
||||
m_bytesLeftToBeAcked (other.m_bytesLeftToBeAcked),
|
||||
m_lastAckedSeq (other.m_lastAckedSeq)
|
||||
TcpSocketSmallAcks (const TcpSocketSmallAcks &other)
|
||||
: TcpSocketMsgBase (other),
|
||||
m_bytesToAck (other.m_bytesToAck),
|
||||
m_bytesLeftToBeAcked (other.m_bytesLeftToBeAcked),
|
||||
m_lastAckedSeq (other.m_lastAckedSeq)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -464,7 +477,7 @@ protected:
|
||||
* \param newValue new value
|
||||
*/
|
||||
virtual void CongStateTrace (const TcpSocketState::TcpCongState_t oldValue,
|
||||
const TcpSocketState::TcpCongState_t newValue)
|
||||
const TcpSocketState::TcpCongState_t newValue)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -580,6 +593,18 @@ protected:
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Updated the Rtt history
|
||||
* \param seq Sequence inserted
|
||||
* \param sz size
|
||||
* \param isRetransmission self-explanatory
|
||||
* \param who where the rtt history was updated
|
||||
*/
|
||||
virtual void UpdatedRttHistory (const SequenceNumber32 & seq, uint32_t sz,
|
||||
bool isRetransmission, SocketWho who)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Notifying application for sent data
|
||||
*
|
||||
@@ -709,6 +734,8 @@ private:
|
||||
const Ptr<const TcpSocketBase> tcp);
|
||||
void RtoExpiredCb (const Ptr<const TcpSocketState> tcb,
|
||||
const Ptr<const TcpSocketBase> tcp);
|
||||
void UpdateRttHistoryCb (Ptr<const TcpSocketBase> tcp, const SequenceNumber32&seq,
|
||||
uint32_t sz, bool isRetransmission);
|
||||
void DataSentCb (Ptr<Socket> socket, uint32_t size);
|
||||
void ForkCb (Ptr<TcpSocketMsgBase> tcp);
|
||||
void HandleAccept (Ptr<Socket> socket, const Address& from);
|
||||
|
||||
167
src/internet/test/tcp-rtt-estimation.cc
Normal file
167
src/internet/test/tcp-rtt-estimation.cc
Normal file
@@ -0,0 +1,167 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2016 Natale Patriciello <natale.patriciello@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tcp-general-test.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/log.h"
|
||||
#include "tcp-error-model.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("TcpRttEstimationTestSuite");
|
||||
|
||||
/**
|
||||
* \brief Check Rtt calculations
|
||||
*
|
||||
* First check is that, for each ACK, we have a valid estimation of the RTT.
|
||||
* The second check is that, when updating RTT history, we should consider
|
||||
* retransmission only segments which sequence number is lower than the highest
|
||||
* already transmitted.
|
||||
*/
|
||||
class TcpRttEstimationTest : public TcpGeneralTest
|
||||
{
|
||||
public:
|
||||
TcpRttEstimationTest (const std::string &desc, bool enableTs, uint32_t dataPkt);
|
||||
|
||||
protected:
|
||||
virtual Ptr<TcpSocketMsgBase> CreateReceiverSocket (Ptr<Node> node);
|
||||
virtual Ptr<TcpSocketMsgBase> CreateSenderSocket (Ptr<Node> node);
|
||||
|
||||
virtual void Rx (const Ptr<const Packet> p, const TcpHeader&h, SocketWho who);
|
||||
virtual void Tx (const Ptr<const Packet> p, const TcpHeader&h, SocketWho who);
|
||||
virtual void UpdatedRttHistory (const SequenceNumber32 & seq, uint32_t sz,
|
||||
bool isRetransmission, SocketWho who);
|
||||
virtual void RttTrace (Time oldTime, Time newTime);
|
||||
void FinalChecks ();
|
||||
|
||||
private:
|
||||
bool m_enableTs;
|
||||
bool m_rttChanged;
|
||||
SequenceNumber32 m_highestTxSeq;
|
||||
};
|
||||
|
||||
TcpRttEstimationTest::TcpRttEstimationTest (const std::string &desc, bool enableTs, uint32_t dataPkt)
|
||||
: TcpGeneralTest (desc, 500, dataPkt, Seconds (0.01), Seconds (0.05), Seconds (2.0),
|
||||
0xffffffff,1, 500),
|
||||
m_enableTs (enableTs),
|
||||
m_rttChanged (false),
|
||||
m_highestTxSeq (0)
|
||||
{
|
||||
}
|
||||
|
||||
Ptr<TcpSocketMsgBase>
|
||||
TcpRttEstimationTest::CreateReceiverSocket (Ptr<Node> node)
|
||||
{
|
||||
Ptr<TcpSocketMsgBase> s = TcpGeneralTest::CreateReceiverSocket (node);
|
||||
if (!m_enableTs)
|
||||
{
|
||||
s->SetAttribute ("Timestamp", BooleanValue (false));
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
Ptr<TcpSocketMsgBase>
|
||||
TcpRttEstimationTest::CreateSenderSocket (Ptr<Node> node)
|
||||
{
|
||||
Ptr<TcpSocketMsgBase> s = TcpGeneralTest::CreateSenderSocket (node);
|
||||
if (!m_enableTs)
|
||||
{
|
||||
s->SetAttribute ("Timestamp", BooleanValue (false));
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void
|
||||
TcpRttEstimationTest::Tx (const Ptr<const Packet> p, const TcpHeader &h, SocketWho who)
|
||||
{
|
||||
if (who == SENDER && h.GetFlags () != TcpHeader::SYN)
|
||||
{
|
||||
if (m_highestTxSeq < h.GetSequenceNumber ())
|
||||
{
|
||||
m_highestTxSeq = h.GetSequenceNumber ();
|
||||
}
|
||||
|
||||
Ptr<RttEstimator> rttEstimator = GetRttEstimator (SENDER);
|
||||
NS_ASSERT (rttEstimator != 0);
|
||||
NS_LOG_DEBUG ("S Rx: seq=" << h.GetSequenceNumber () << " ack=" << h.GetAckNumber ());
|
||||
NS_TEST_ASSERT_MSG_NE (rttEstimator->GetEstimate (), Seconds (1),
|
||||
"Default Estimate for the RTT");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TcpRttEstimationTest::Rx (const Ptr<const Packet> p, const TcpHeader &h, SocketWho who)
|
||||
{
|
||||
if (who == RECEIVER)
|
||||
{
|
||||
NS_LOG_DEBUG ("R Rx: seq=" << h.GetSequenceNumber () << " ack=" << h.GetAckNumber ());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TcpRttEstimationTest::UpdatedRttHistory (const SequenceNumber32 & seq, uint32_t sz,
|
||||
bool isRetransmission, SocketWho who)
|
||||
{
|
||||
if (seq < m_highestTxSeq)
|
||||
{
|
||||
NS_TEST_ASSERT_MSG_EQ (isRetransmission, true,
|
||||
"A retransmission is not flagged as such");
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_TEST_ASSERT_MSG_EQ (isRetransmission, false,
|
||||
"Incorrectly flagging seq as retransmission");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
TcpRttEstimationTest::RttTrace (Time oldTime, Time newTime)
|
||||
{
|
||||
NS_LOG_DEBUG ("Rtt changed to " << newTime);
|
||||
m_rttChanged = true;
|
||||
}
|
||||
|
||||
void
|
||||
TcpRttEstimationTest::FinalChecks ()
|
||||
{
|
||||
NS_TEST_ASSERT_MSG_EQ (m_rttChanged, true, "Rtt was not updated");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static class TcpRttEstimationTestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
TcpRttEstimationTestSuite () : TestSuite ("tcp-rtt-estimation-test", UNIT)
|
||||
{
|
||||
AddTestCase (new TcpRttEstimationTest ("RTT estimation, ts, no data", true, 0),
|
||||
TestCase::QUICK);
|
||||
AddTestCase (new TcpRttEstimationTest ("RTT estimation, no ts, no data", false, 0),
|
||||
TestCase::QUICK);
|
||||
AddTestCase (new TcpRttEstimationTest ("RTT estimation, ts, some data", true, 10),
|
||||
TestCase::QUICK);
|
||||
AddTestCase (new TcpRttEstimationTest ("RTT estimation, no ts, some data", false, 10),
|
||||
TestCase::QUICK);
|
||||
}
|
||||
} g_tcpRttEstimationTestSuite;
|
||||
|
||||
} // namespace ns3
|
||||
@@ -243,6 +243,7 @@ def build(bld):
|
||||
'test/tcp-hybla-test.cc',
|
||||
'test/tcp-zero-window-test.cc',
|
||||
'test/tcp-pkts-acked-test.cc',
|
||||
'test/tcp-rtt-estimation.cc',
|
||||
'test/udp-test.cc',
|
||||
'test/ipv6-address-generator-test-suite.cc',
|
||||
'test/ipv6-dual-stack-test-suite.cc',
|
||||
|
||||
Reference in New Issue
Block a user