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 "tcp-error-model.h"
24 
25 using namespace ns3;
26 
27 NS_LOG_COMPONENT_DEFINE ("TcpRttEstimationTestSuite");
28 
41 {
42 public:
49  TcpRttEstimationTest (const std::string &desc, bool enableTs, uint32_t pktCount);
50 
51 protected:
52  virtual Ptr<TcpSocketMsgBase> CreateReceiverSocket (Ptr<Node> node);
53  virtual Ptr<TcpSocketMsgBase> CreateSenderSocket (Ptr<Node> node);
54 
55  virtual void Rx (const Ptr<const Packet> p, const TcpHeader&h, SocketWho who);
56  virtual void Tx (const Ptr<const Packet> p, const TcpHeader&h, SocketWho who);
57  virtual void UpdatedRttHistory (const SequenceNumber32 & seq, uint32_t sz,
58  bool isRetransmission, SocketWho who);
59  virtual void RttTrace (Time oldTime, Time newTime);
60  void FinalChecks ();
61 
62  virtual void ConfigureEnvironment ();
63 
64 private:
65  bool m_enableTs;
66  bool m_rttChanged;
68  uint32_t m_pktCount;
69  uint32_t m_dataCount;
70 };
71 
72 TcpRttEstimationTest::TcpRttEstimationTest (const std::string &desc, bool enableTs,
73  uint32_t pktCount)
74  : TcpGeneralTest (desc),
75  m_enableTs (enableTs),
76  m_rttChanged (false),
77  m_highestTxSeq (0),
78  m_pktCount (pktCount),
79  m_dataCount (0)
80 {
81 }
82 
83 void
85 {
86  TcpGeneralTest::ConfigureEnvironment ();
89  SetTransmitStart (Seconds (2.0));
90  SetMTU (500);
91 }
92 
95 {
96  Ptr<TcpSocketMsgBase> s = TcpGeneralTest::CreateReceiverSocket (node);
97  if (!m_enableTs)
98  {
99  s->SetAttribute ("Timestamp", BooleanValue (false));
100  }
101 
102  return s;
103 }
104 
107 {
108  Ptr<TcpSocketMsgBase> s = TcpGeneralTest::CreateSenderSocket (node);
109  if (!m_enableTs)
110  {
111  s->SetAttribute ("Timestamp", BooleanValue (false));
112  }
113 
114  return s;
115 }
116 
117 void
119 {
120  if (who == SENDER && h.GetFlags () != TcpHeader::SYN)
121  {
123  {
125  m_dataCount = 0;
126  }
127 
128  Ptr<RttEstimator> rttEstimator = GetRttEstimator (SENDER);
129  NS_ASSERT (rttEstimator != 0);
130  NS_LOG_DEBUG ("S Tx: seq=" << h.GetSequenceNumber () << " ack=" << h.GetAckNumber ());
131  NS_TEST_ASSERT_MSG_NE (rttEstimator->GetEstimate (), Seconds (1),
132  "Default Estimate for the RTT");
133  }
134 }
135 
136 void
138 {
139  if (who == RECEIVER)
140  {
141  NS_LOG_DEBUG ("R Rx: seq=" << h.GetSequenceNumber () << " ack=" << h.GetAckNumber ());
142  }
143 }
144 
145 void
147  bool isRetransmission, SocketWho who)
148 {
149  if (sz == 0)
150  {
151  return;
152  }
153 
154  if (seq < m_highestTxSeq)
155  {
156  NS_TEST_ASSERT_MSG_EQ (isRetransmission, true,
157  "A retransmission is not flagged as such");
158  }
159  else if (seq == m_highestTxSeq && m_dataCount == 0)
160  {
161  NS_TEST_ASSERT_MSG_EQ (isRetransmission, false,
162  "Incorrectly flagging seq as retransmission");
163  m_dataCount++;
164  }
165  else if (seq == m_highestTxSeq && m_dataCount > 0)
166  {
167  NS_TEST_ASSERT_MSG_EQ (isRetransmission, true,
168  "A retransmission is not flagged as such");
169  }
170 }
171 
172 void
174 {
175  NS_LOG_DEBUG ("Rtt changed to " << newTime.GetSeconds ());
176  m_rttChanged = true;
177 }
178 
179 void
181 {
182  NS_TEST_ASSERT_MSG_EQ (m_rttChanged, true, "Rtt was not updated");
183 }
184 
185 
195 {
196 public:
204  TcpRttEstimationWithLossTest (const std::string &desc, bool enableTs,
205  uint32_t pktCount, std::vector<uint32_t> toDrop);
206 
207 protected:
209 
210 private:
211  std::vector<uint32_t> m_toDrop;
212 };
213 
215  bool enableTs,
216  uint32_t pktCount,
217  std::vector<uint32_t> toDrop)
218  : TcpRttEstimationTest (desc, enableTs, pktCount),
219  m_toDrop (toDrop)
220 {
221 
222 }
223 
226 {
227  Ptr<TcpSeqErrorModel> errorModel = CreateObject<TcpSeqErrorModel> ();
228 
229  std::vector<uint32_t>::iterator it;
230 
231  for (it = m_toDrop.begin (); it != m_toDrop.end (); ++it)
232  {
233  errorModel->AddSeqToKill (SequenceNumber32 ((*it)));
234  }
235 
236  return errorModel;
237 }
238 
239 
240 
248 {
249 public:
250  TcpRttEstimationTestSuite () : TestSuite ("tcp-rtt-estimation-test", UNIT)
251  {
252  AddTestCase (new TcpRttEstimationTest ("RTT estimation, ts, no data", true, 0),
253  TestCase::QUICK);
254  AddTestCase (new TcpRttEstimationTest ("RTT estimation, no ts, no data", false, 0),
255  TestCase::QUICK);
256  AddTestCase (new TcpRttEstimationTest ("RTT estimation, ts, some data", true, 10),
257  TestCase::QUICK);
258  AddTestCase (new TcpRttEstimationTest ("RTT estimation, no ts, some data", false, 10),
259  TestCase::QUICK);
260 
261  std::vector<uint32_t> toDrop;
262  toDrop.push_back (501);
263 
264  AddTestCase (new TcpRttEstimationWithLossTest ("RTT estimation, no ts,"
265  " some data, with retr",
266  false, 10, toDrop),
267  TestCase::QUICK);
268  AddTestCase (new TcpRttEstimationWithLossTest ("RTT estimation, ts,"
269  " some data, with retr",
270  true, 10, toDrop),
271  TestCase::QUICK);
272 
273  toDrop.push_back (501);
274  AddTestCase (new TcpRttEstimationWithLossTest ("RTT estimation, no ts,"
275  " some data, with retr",
276  false, 10, toDrop),
277  TestCase::QUICK);
278  AddTestCase (new TcpRttEstimationWithLossTest ("RTT estimation, ts,"
279  " some data, with retr",
280  true, 10, toDrop),
281  TestCase::QUICK);
282 
283  toDrop.push_back (54001);
284  toDrop.push_back (58001);
285  toDrop.push_back (58501);
286  toDrop.push_back (60001);
287  toDrop.push_back (68501);
288  AddTestCase (new TcpRttEstimationWithLossTest ("RTT estimation, no ts,"
289  " a lot of data, with retr",
290  false, 1000, toDrop),
291  TestCase::QUICK);
292  AddTestCase (new TcpRttEstimationWithLossTest ("RTT estimation, ts,"
293  " a lot of data, with retr",
294  true, 1000, toDrop),
295  TestCase::QUICK);
296  }
297 
298 };
299 
301 
302 
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
SequenceNumber32 GetSequenceNumber() const
Get the sequence number.
Definition: tcp-header.cc:143
AttributeValue implementation for Boolean.
Definition: boolean.h:36
uint8_t GetFlags() const
Get the flags.
Definition: tcp-header.cc:173
virtual void RttTrace(Time oldTime, Time newTime)
Rtt changes.
A suite of tests to run.
Definition: test.h:1342
bool m_enableTs
Enable TimeStamp option.
SequenceNumber32 GetAckNumber() const
Get the ACK number.
Definition: tcp-header.cc:149
#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:201
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1001
void SetTransmitStart(Time startTime)
Set the initial time at which the application sends the first data packet.
This test suite implements a Unit Test.
Definition: test.h:1352
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.
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:341
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 evironment.
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.
SocketWho
Used as parameter of methods, specifies on what node the caller is interested (e.g.
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:168
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.
virtual void UpdatedRttHistory(const SequenceNumber32 &seq, uint32_t sz, bool isRetransmission, SocketWho who)
Updated the Rtt history.
General infrastructure for TCP testing.
#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:624
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:269
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:993
Time GetEstimate(void) const
gets the RTT estimate.
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.