A Discrete-Event Network Simulator
API
tcp-slow-start-test.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2015 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 #include "ns3/log.h"
20 #include "ns3/test.h"
21 #include "ns3/simple-channel.h"
22 #include "ns3/node.h"
23 #include "ns3/config.h"
24 #include "ns3/tcp-header.h"
25 #include "tcp-general-test.h"
26 
27 using namespace ns3;
28 
29 NS_LOG_COMPONENT_DEFINE ("TcpSlowStartTest");
30 
46 class
48 {
49 public:
59  TcpSlowStartNormalTest (uint32_t segmentSize, uint32_t packetSize,
60  uint32_t initSsTh, uint32_t packets, const TypeId& congControl,
61  const std::string &desc);
62 
63 protected:
64  virtual void CWndTrace (uint32_t oldValue, uint32_t newValue);
65  virtual void Tx (const Ptr<const Packet> p, const TcpHeader &h, SocketWho who);
66  virtual void Rx (const Ptr<const Packet> p, const TcpHeader &h, SocketWho who);
67  void QueueDrop (SocketWho who);
68  void PhyDrop (SocketWho who);
69 
70  virtual void ConfigureEnvironment ();
71  virtual void ConfigureProperties ();
72 
73  uint32_t m_ackedBytes;
74  uint32_t m_sentBytes;
75  uint32_t m_totalAckedBytes;
76  uint32_t m_allowedIncrease;
77 
78  bool m_initial;
79 
80 private:
81  uint32_t m_segmentSize;
82  uint32_t m_packetSize;
83  uint32_t m_packets;
84 };
85 
87  uint32_t packetSize,
88  uint32_t initSsTh,
89  uint32_t packets,
90  const TypeId &typeId,
91  const std::string &desc)
92  : TcpGeneralTest (desc),
93  m_ackedBytes (0),
94  m_sentBytes (0),
95  m_totalAckedBytes (0),
96  m_allowedIncrease (0),
97  m_initial (true),
98  m_segmentSize (segmentSize),
99  m_packetSize (packetSize),
100  m_packets (packets)
101 {
102  m_congControlTypeId = typeId;
103 }
104 
105 void
107 {
108  TcpGeneralTest::ConfigureEnvironment ();
111 }
112 
113 void
115 {
116  TcpGeneralTest::ConfigureProperties ();
117  SetInitialSsThresh (SENDER, 400000);
120 }
121 
122 void
124 {
125  NS_FATAL_ERROR ("Drop on the queue; cannot validate slow start");
126 }
127 
128 void
130 {
131  NS_FATAL_ERROR ("Drop on the phy: cannot validate slow start");
132 }
133 
145 void
146 TcpSlowStartNormalTest::CWndTrace (uint32_t oldValue, uint32_t newValue)
147 {
148  uint32_t segSize = GetSegSize (TcpGeneralTest::SENDER);
149  uint32_t increase = newValue - oldValue;
150 
151  if (m_initial)
152  {
153  m_initial = false;
154  NS_LOG_INFO ("Ignored update to " << newValue <<
155  " with a segsize of " << segSize);
156  return;
157  }
158 
159  // The increase in RFC should be <= of segSize. In ns-3 we force = segSize
160  NS_TEST_ASSERT_MSG_EQ (increase, segSize, "Increase different than segsize");
161  NS_TEST_ASSERT_MSG_LT_OR_EQ (newValue, GetInitialSsThresh (SENDER), "cWnd increased over ssth");
162 
163  NS_LOG_INFO ("Incremented cWnd by " << segSize << " bytes in Slow Start " <<
164  "achieving a value of " << newValue);
165 
166  NS_TEST_ASSERT_MSG_GT_OR_EQ (m_allowedIncrease, 1, "Increase not allowed");
168 }
169 
170 void
172 {
173  NS_LOG_FUNCTION (this << p << h << who);
174 
175  if (who == SENDER && Simulator::Now ().GetSeconds () > 5.0)
176  {
177  m_sentBytes += GetSegSize (TcpGeneralTest::SENDER);
178  }
179 }
180 
181 void
183 {
184  NS_LOG_FUNCTION (this << p << h << who);
185 
186  if (who == SENDER && Simulator::Now ().GetSeconds () > 5.0)
187  {
188  uint32_t acked = h.GetAckNumber ().GetValue () - m_totalAckedBytes - 1;
189  m_totalAckedBytes += acked;
190  m_ackedBytes += acked;
191 
192  NS_LOG_INFO ("Ack of " << acked << " bytes, acked this round=" << m_ackedBytes);
193 
194  if (m_ackedBytes >= GetSegSize (SENDER))
195  {
196  NS_LOG_INFO ("FULL ACK achieved, bytes=" << m_ackedBytes);
197  m_allowedIncrease += 1;
199  }
200 
201  while (m_ackedBytes >= GetSegSize (SENDER))
202  {
204  }
205  }
206 }
207 
219 class
221 {
222 public:
232  TcpSlowStartAttackerTest (uint32_t segmentSize, uint32_t packetSize,
233  uint32_t initSsTh, uint32_t packets, const TypeId& congControl,
234  const std::string &desc);
235 
236 protected:
237  virtual Ptr<TcpSocketMsgBase> CreateReceiverSocket (Ptr<Node> node);
238 };
239 
241  uint32_t packetSize,
242  uint32_t initSsTh,
243  uint32_t packets,
244  const TypeId &typeId,
245  const std::string &msg)
246  : TcpSlowStartNormalTest (segmentSize, packetSize, initSsTh, packets, typeId, msg)
247 {
248 
249 }
250 
253 {
254  Ptr<TcpSocketSmallAcks> socket = DynamicCast<TcpSocketSmallAcks> (
255  CreateSocket (node,
256  TcpSocketSmallAcks::GetTypeId (),
258  socket->SetBytesToAck (125);
259 
260  return socket;
261 }
262 
263 
271 {
272 public:
273  TcpSlowStartTestSuite () : TestSuite ("tcp-slow-start-test", UNIT)
274  {
275  // This test have less packets to transmit than SsTh
276  std::list<TypeId> types = {
277  TcpNewReno::GetTypeId (),
278  };
279 
280  for (const auto &t : types)
281  {
282  std::string typeName = t.GetName ();
283 
284  AddTestCase (new TcpSlowStartNormalTest (500, 500, 10000, 10, t,
285  "slow start 500 byte, " + typeName),
286  TestCase::QUICK);
287  AddTestCase (new TcpSlowStartNormalTest (1000, 1000, 10000, 9, t,
288  "slow start 1000 byte, " + typeName),
289  TestCase::QUICK);
290  AddTestCase (new TcpSlowStartNormalTest (500, 250, 10000, 10, t,
291  "slow start small packets, " + typeName),
292  TestCase::QUICK);
293  AddTestCase (new TcpSlowStartAttackerTest (500, 500, 10000, 10, t,
294  "slow start ack attacker, 500 byte, " + typeName),
295  TestCase::QUICK);
296  AddTestCase (new TcpSlowStartAttackerTest (1000, 1000, 10000, 9, t,
297  "slow start ack attacker, 1000 byte, " + typeName),
298  TestCase::QUICK);
299  }
300  }
301 };
302 
A slow start test using a socket which sends smaller ACKs.
TcpSlowStartAttackerTest(uint32_t segmentSize, uint32_t packetSize, uint32_t initSsTh, uint32_t packets, const TypeId &congControl, const std::string &desc)
Constructor.
virtual Ptr< TcpSocketMsgBase > CreateReceiverSocket(Ptr< Node > node)
Create and install the socket to install on the receiver.
Test the normal behavior for slow start.
bool m_initial
First cycle flag.
TcpSlowStartNormalTest(uint32_t segmentSize, uint32_t packetSize, uint32_t initSsTh, uint32_t packets, const TypeId &congControl, const std::string &desc)
Constructor.
uint32_t m_packetSize
Packet size.
virtual void Tx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Packet transmitted down to IP layer.
uint32_t m_packets
Packet counter.
virtual void Rx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Packet received from IP layer.
void QueueDrop(SocketWho who)
uint32_t m_ackedBytes
ACKed bytes.
void PhyDrop(SocketWho who)
uint32_t m_segmentSize
Segment size.
virtual void ConfigureEnvironment()
Change the configuration of the environment.
uint32_t m_sentBytes
Sent bytes.
uint32_t m_totalAckedBytes
Total ACKed bytes.
virtual void ConfigureProperties()
Change the configuration of the socket properties.
uint32_t m_allowedIncrease
Allowed increase.
virtual void CWndTrace(uint32_t oldValue, uint32_t newValue)
Trace the cWnd over the slow start.
TCP Slow Start TestSuite.
NUMERIC_TYPE GetValue() const
Extracts the numeric value of the sequence number.
General infrastructure for TCP testing.
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 SetAppPktSize(uint32_t pktSize)
Set app packet size.
uint32_t GetInitialSsThresh(SocketWho who)
Get the initial slow start threshold.
virtual Ptr< TcpSocketMsgBase > CreateSocket(Ptr< Node > node, TypeId socketType, TypeId congControl)
Create a socket.
uint32_t GetSegSize(SocketWho who)
Get the segment size of the node specified.
TypeId m_congControlTypeId
Congestion control.
void SetInitialSsThresh(SocketWho who, uint32_t initialSsThresh)
Forcefully set the initial ssthresh.
void SetSegmentSize(SocketWho who, uint32_t segmentSize)
Forcefully set the segment size.
Header for the Transmission Control Protocol.
Definition: tcp-header.h:45
SequenceNumber32 GetAckNumber() const
Get the ACK number.
Definition: tcp-header.cc:149
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
std::string GetName(void) const
Definition: test.cc:370
A suite of tests to run.
Definition: test.h:1188
@ UNIT
This test suite implements a Unit Test.
Definition: test.h:1197
a unique identifier for an interface.
Definition: type-id.h:59
uint32_t segmentSize
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
#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:141
#define NS_TEST_ASSERT_MSG_LT_OR_EQ(actual, limit, msg)
Test that an actual value is less than or equal to a limit and report and abort if not.
Definition: test.h:712
#define NS_TEST_ASSERT_MSG_GT_OR_EQ(actual, limit, msg)
Test that an actual value is greater than or equal to a limit and report and abort if not.
Definition: test.h:862
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static TcpSlowStartTestSuite g_tcpSlowStartTestSuite
Static variable for test initialization.
static const uint32_t packetSize