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