A Discrete-Event Network Simulator
API
tcp-rtt-estimation.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2016 Natale Patriciello <natale.patriciello@gmail.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  */
19 
20 #include "tcp-general-test.h"
21 #include "ns3/node.h"
22 #include "ns3/log.h"
23 #include "ns3/rtt-estimator.h"
24 #include "tcp-error-model.h"
25 
26 using namespace ns3;
27 
28 NS_LOG_COMPONENT_DEFINE ("TcpRttEstimationTestSuite");
29 
42 {
43 public:
50  TcpRttEstimationTest (const std::string &desc, bool enableTs, uint32_t pktCount);
51 
52 protected:
53  virtual Ptr<TcpSocketMsgBase> CreateReceiverSocket (Ptr<Node> node);
54  virtual Ptr<TcpSocketMsgBase> CreateSenderSocket (Ptr<Node> node);
55 
56  virtual void Rx (const Ptr<const Packet> p, const TcpHeader&h, SocketWho who);
57  virtual void Tx (const Ptr<const Packet> p, const TcpHeader&h, SocketWho who);
58  virtual void UpdatedRttHistory (const SequenceNumber32 & seq, uint32_t sz,
59  bool isRetransmission, SocketWho who);
60  virtual void RttTrace (Time oldTime, Time newTime);
61  void FinalChecks ();
62 
63  virtual void ConfigureEnvironment ();
64 
65 private:
66  bool m_enableTs;
67  bool m_rttChanged;
69  uint32_t m_pktCount;
70  uint32_t m_dataCount;
71 };
72 
73 TcpRttEstimationTest::TcpRttEstimationTest (const std::string &desc, bool enableTs,
74  uint32_t pktCount)
75  : TcpGeneralTest (desc),
76  m_enableTs (enableTs),
77  m_rttChanged (false),
78  m_highestTxSeq (0),
79  m_pktCount (pktCount),
80  m_dataCount (0)
81 {
82 }
83 
84 void
86 {
87  TcpGeneralTest::ConfigureEnvironment ();
90  SetTransmitStart (Seconds (2.0));
91  SetMTU (500);
92 }
93 
96 {
97  Ptr<TcpSocketMsgBase> s = TcpGeneralTest::CreateReceiverSocket (node);
98  if (!m_enableTs)
99  {
100  s->SetAttribute ("Timestamp", BooleanValue (false));
101  }
102 
103  return s;
104 }
105 
108 {
109  Ptr<TcpSocketMsgBase> s = TcpGeneralTest::CreateSenderSocket (node);
110  if (!m_enableTs)
111  {
112  s->SetAttribute ("Timestamp", BooleanValue (false));
113  }
114 
115  return s;
116 }
117 
118 void
120 {
121  if (who == SENDER && h.GetFlags () != TcpHeader::SYN)
122  {
124  {
126  m_dataCount = 0;
127  }
128 
129  Ptr<RttEstimator> rttEstimator = GetRttEstimator (SENDER);
130  NS_ASSERT (rttEstimator != 0);
131  NS_LOG_DEBUG ("S Tx: seq=" << h.GetSequenceNumber () << " ack=" << h.GetAckNumber ());
132  NS_TEST_ASSERT_MSG_NE (rttEstimator->GetEstimate (), Seconds (1),
133  "Default Estimate for the RTT");
134  }
135 }
136 
137 void
139 {
140  if (who == RECEIVER)
141  {
142  NS_LOG_DEBUG ("R Rx: seq=" << h.GetSequenceNumber () << " ack=" << h.GetAckNumber ());
143  }
144 }
145 
146 void
148  bool isRetransmission, SocketWho who)
149 {
150  if (sz == 0)
151  {
152  return;
153  }
154 
155  if (seq < m_highestTxSeq)
156  {
157  NS_TEST_ASSERT_MSG_EQ (isRetransmission, true,
158  "A retransmission is not flagged as such");
159  }
160  else if (seq == m_highestTxSeq && m_dataCount == 0)
161  {
162  NS_TEST_ASSERT_MSG_EQ (isRetransmission, false,
163  "Incorrectly flagging seq as retransmission");
164  m_dataCount++;
165  }
166  else if (seq == m_highestTxSeq && m_dataCount > 0)
167  {
168  NS_TEST_ASSERT_MSG_EQ (isRetransmission, true,
169  "A retransmission is not flagged as such");
170  }
171 }
172 
173 void
175 {
176  NS_LOG_DEBUG ("Rtt changed to " << newTime.GetSeconds ());
177  m_rttChanged = true;
178 }
179 
180 void
182 {
183  NS_TEST_ASSERT_MSG_EQ (m_rttChanged, true, "Rtt was not updated");
184 }
185 
186 
196 {
197 public:
205  TcpRttEstimationWithLossTest (const std::string &desc, bool enableTs,
206  uint32_t pktCount, std::vector<uint32_t> toDrop);
207 
208 protected:
210 
211 private:
212  std::vector<uint32_t> m_toDrop;
213 };
214 
216  bool enableTs,
217  uint32_t pktCount,
218  std::vector<uint32_t> toDrop)
219  : TcpRttEstimationTest (desc, enableTs, pktCount),
220  m_toDrop (toDrop)
221 {
222 
223 }
224 
227 {
228  Ptr<TcpSeqErrorModel> errorModel = CreateObject<TcpSeqErrorModel> ();
229 
230  std::vector<uint32_t>::iterator it;
231 
232  for (it = m_toDrop.begin (); it != m_toDrop.end (); ++it)
233  {
234  errorModel->AddSeqToKill (SequenceNumber32 ((*it)));
235  }
236 
237  return errorModel;
238 }
239 
240 
241 
249 {
250 public:
251  TcpRttEstimationTestSuite () : TestSuite ("tcp-rtt-estimation-test", UNIT)
252  {
253  AddTestCase (new TcpRttEstimationTest ("RTT estimation, ts, no data", true, 0),
254  TestCase::QUICK);
255  AddTestCase (new TcpRttEstimationTest ("RTT estimation, no ts, no data", false, 0),
256  TestCase::QUICK);
257  AddTestCase (new TcpRttEstimationTest ("RTT estimation, ts, some data", true, 10),
258  TestCase::QUICK);
259  AddTestCase (new TcpRttEstimationTest ("RTT estimation, no ts, some data", false, 10),
260  TestCase::QUICK);
261 
262  std::vector<uint32_t> toDrop;
263  toDrop.push_back (501);
264 
265  AddTestCase (new TcpRttEstimationWithLossTest ("RTT estimation, no ts,"
266  " some data, with retr",
267  false, 10, toDrop),
268  TestCase::QUICK);
269  AddTestCase (new TcpRttEstimationWithLossTest ("RTT estimation, ts,"
270  " some data, with retr",
271  true, 10, toDrop),
272  TestCase::QUICK);
273 
274  toDrop.push_back (501);
275  AddTestCase (new TcpRttEstimationWithLossTest ("RTT estimation, no ts,"
276  " some data, with retr",
277  false, 10, toDrop),
278  TestCase::QUICK);
279  AddTestCase (new TcpRttEstimationWithLossTest ("RTT estimation, ts,"
280  " some data, with retr",
281  true, 10, toDrop),
282  TestCase::QUICK);
283 
284  toDrop.push_back (54001);
285  toDrop.push_back (58001);
286  toDrop.push_back (58501);
287  toDrop.push_back (60001);
288  toDrop.push_back (68501);
289  AddTestCase (new TcpRttEstimationWithLossTest ("RTT estimation, no ts,"
290  " a lot of data, with retr",
291  false, 1000, toDrop),
292  TestCase::QUICK);
293  AddTestCase (new TcpRttEstimationWithLossTest ("RTT estimation, ts,"
294  " a lot of data, with retr",
295  true, 1000, toDrop),
296  TestCase::QUICK);
297  }
298 
299 };
300 
302 
303 
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
AttributeValue implementation for Boolean.
Definition: boolean.h:36
virtual void RttTrace(Time oldTime, Time newTime)
Rtt changes.
A suite of tests to run.
Definition: test.h:1343
bool m_enableTs
Enable TimeStamp option.
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:379
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1286
Time GetEstimate(void) const
gets the RTT estimate.
void SetTransmitStart(Time startTime)
Set the initial time at which the application sends the first data packet.
SequenceNumber32 GetAckNumber() const
Get the ACK number.
Definition: tcp-header.cc:149
virtual Ptr< TcpSocketMsgBase > CreateSenderSocket(Ptr< Node > node)
Create and install the socket to install on the sender.
virtual void Tx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Packet transmitted down to IP layer.
virtual Ptr< TcpSocketMsgBase > CreateReceiverSocket(Ptr< Node > node)
Create and install the socket to install on the receiver.
Check Rtt calculations with packet losses.
virtual void ConfigureEnvironment()
Change the configuration of the environment.
TcpRttEstimationWithLossTest(const std::string &desc, bool enableTs, uint32_t pktCount, std::vector< uint32_t > toDrop)
Constructor.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
SequenceNumber32 m_highestTxSeq
Highest sequence number sent.
void SetMTU(uint32_t mtu)
MTU of the bottleneck link.
void FinalChecks()
Performs the (eventual) final checks through test asserts.
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:166
uint32_t m_pktCount
Packet counter.
TCP RTT estimation TestSuite.
static TcpRttEstimationTestSuite g_tcpRttEstimationTestSuite
Static variable for test initialization.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::vector< uint32_t > m_toDrop
Packets to drop.
Generic "sequence number" class.
Header for the Transmission Control Protocol.
Definition: tcp-header.h:44
void AddSeqToKill(const SequenceNumber32 &seq)
Add the sequence number to the list of segments to be killed.
TcpRttEstimationTest(const std::string &desc, bool enableTs, uint32_t pktCount)
Constructor.
bool m_rttChanged
True if RTT has changed.
void SetAppPktCount(uint32_t pktCount)
Set app packet count.
virtual void Rx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Packet received from IP layer.
Check Rtt calculations.
SocketWho
Used as parameter of methods, specifies on what node the caller is interested (e.g.
virtual void UpdatedRttHistory(const SequenceNumber32 &seq, uint32_t sz, bool isRetransmission, SocketWho who)
Updated the Rtt history.
General infrastructure for TCP testing.
uint8_t GetFlags() const
Get the flags.
Definition: tcp-header.cc:173
#define NS_TEST_ASSERT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report and abort if not...
Definition: test.h:622
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
Ptr< ErrorModel > CreateReceiverErrorModel()
Create and return the error model to install in the receiver node.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1278
SequenceNumber32 GetSequenceNumber() const
Get the sequence number.
Definition: tcp-header.cc:143
This test suite implements a Unit Test.
Definition: test.h:1353
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
Ptr< RttEstimator > GetRttEstimator(SocketWho who)
Get the Rtt estimator of the socket.
void SetPropagationDelay(Time propDelay)
Propagation delay of the bottleneck link.
uint32_t m_dataCount
Data counter.