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-westwood.h"
25 #include "ns3/tcp-header.h"
26 #include "tcp-general-test.h"
27 
28 using namespace ns3;
29 
30 NS_LOG_COMPONENT_DEFINE ("TcpSlowStartTest");
31 
47 class
49 {
50 public:
60  TcpSlowStartNormalTest (uint32_t segmentSize, uint32_t packetSize,
61  uint32_t initSsTh, uint32_t packets, TypeId& congControl,
62  const std::string &desc);
63 
64 protected:
65  virtual void CWndTrace (uint32_t oldValue, uint32_t newValue);
66  virtual void Tx (const Ptr<const Packet> p, const TcpHeader &h, SocketWho who);
67  virtual void Rx (const Ptr<const Packet> p, const TcpHeader &h, SocketWho who);
68  void QueueDrop (SocketWho who);
69  void PhyDrop (SocketWho who);
70 
71  virtual void ConfigureEnvironment ();
72  virtual void ConfigureProperties ();
73 
74  uint32_t m_ackedBytes;
75  uint32_t m_sentBytes;
76  uint32_t m_totalAckedBytes;
77  uint32_t m_allowedIncrease;
78 
79  bool m_initial;
80 
81 private:
82  uint32_t m_segmentSize;
83  uint32_t m_packetSize;
84  uint32_t m_packets;
85 };
86 
88  uint32_t packetSize,
89  uint32_t initSsTh,
90  uint32_t packets,
91  TypeId &typeId,
92  const std::string &desc)
93  : TcpGeneralTest (desc),
94  m_ackedBytes (0),
95  m_sentBytes (0),
96  m_totalAckedBytes (0),
97  m_allowedIncrease (0),
98  m_initial (true),
99  m_segmentSize (segmentSize),
100  m_packetSize (packetSize),
101  m_packets (packets)
102 {
103  m_congControlTypeId = typeId;
104 }
105 
106 void
108 {
109  TcpGeneralTest::ConfigureEnvironment ();
112 }
113 
114 void
116 {
117  TcpGeneralTest::ConfigureProperties ();
118  SetInitialSsThresh (SENDER, 400000);
121 }
122 
123 void
125 {
126  NS_FATAL_ERROR ("Drop on the queue; cannot validate slow start");
127 }
128 
129 void
131 {
132  NS_FATAL_ERROR ("Drop on the phy: cannot validate slow start");
133 }
134 
146 void
147 TcpSlowStartNormalTest::CWndTrace (uint32_t oldValue, uint32_t newValue)
148 {
149  uint32_t segSize = GetSegSize (TcpGeneralTest::SENDER);
150  uint32_t increase = newValue - oldValue;
151 
152  if (m_initial)
153  {
154  m_initial = false;
155  NS_LOG_INFO ("Ignored update to " << newValue <<
156  " with a segsize of " << segSize);
157  return;
158  }
159 
160  // The increase in RFC should be <= of segSize. In ns-3 we force = segSize
161  NS_TEST_ASSERT_MSG_EQ (increase, segSize, "Increase different than segsize");
162  NS_TEST_ASSERT_MSG_LT_OR_EQ (newValue, GetInitialSsThresh (SENDER), "cWnd increased over ssth");
163 
164  NS_LOG_INFO ("Incremented cWnd by " << segSize << " bytes in Slow Start " <<
165  "achieving a value of " << newValue);
166 
167  NS_TEST_ASSERT_MSG_GT_OR_EQ (m_allowedIncrease, 1, "Increase not allowed");
169 }
170 
171 void
173 {
174  NS_LOG_FUNCTION (this << p << h << who);
175 
176  if (who == SENDER && Simulator::Now ().GetSeconds () > 5.0)
177  {
178  m_sentBytes += GetSegSize (TcpGeneralTest::SENDER);
179  }
180 }
181 
182 void
184 {
185  NS_LOG_FUNCTION (this << p << h << who);
186 
187  if (who == SENDER && Simulator::Now ().GetSeconds () > 5.0)
188  {
189  uint32_t acked = h.GetAckNumber ().GetValue () - m_totalAckedBytes - 1;
190  m_totalAckedBytes += acked;
191  m_ackedBytes += acked;
192 
193  NS_LOG_INFO ("Ack of " << acked << " bytes, acked this round=" << m_ackedBytes);
194 
195  if (m_ackedBytes >= GetSegSize (SENDER))
196  {
197  NS_LOG_INFO ("FULL ACK achieved, bytes=" << m_ackedBytes);
198  m_allowedIncrease += 1;
200  }
201 
202  while (m_ackedBytes >= GetSegSize (SENDER))
203  {
205  }
206  }
207 }
208 
220 class
222 {
223 public:
233  TcpSlowStartAttackerTest (uint32_t segmentSize, uint32_t packetSize,
234  uint32_t initSsTh, uint32_t packets, TypeId& congControl,
235  const std::string &desc);
236 
237 protected:
238  virtual Ptr<TcpSocketMsgBase> CreateReceiverSocket (Ptr<Node> node);
239 };
240 
242  uint32_t packetSize,
243  uint32_t initSsTh,
244  uint32_t packets,
245  TypeId &typeId, 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  types.insert (types.begin (), TcpNewReno::GetTypeId ());
278  types.insert (types.begin (), TcpWestwood::GetTypeId ());
279 
280  for (std::list<TypeId>::iterator it = types.begin (); it != types.end (); ++it)
281  {
282  AddTestCase (new TcpSlowStartNormalTest (500, 500, 10000, 10, (*it),
283  "slow start 500 byte, " + (*it).GetName ()),
284  TestCase::QUICK);
285  AddTestCase (new TcpSlowStartNormalTest (1000, 1000, 10000, 9, (*it),
286  "slow start 1000 byte, " + (*it).GetName ()),
287  TestCase::QUICK);
288  AddTestCase (new TcpSlowStartNormalTest (500, 250, 10000, 10, (*it),
289  "slow start small packets, " + (*it).GetName ()),
290  TestCase::QUICK);
291  AddTestCase (new TcpSlowStartAttackerTest (500, 500, 10000, 10, (*it),
292  "slow start ack attacker, 500 byte, " + (*it).GetName ()),
293  TestCase::QUICK);
294  AddTestCase (new TcpSlowStartAttackerTest (1000, 1000, 10000, 9, (*it),
295  "slow start ack attacker, 1000 byte, " + (*it).GetName ()),
296  TestCase::QUICK);
297  }
298  }
299 };
300 
302 
virtual void ConfigureEnvironment()
Change the configuration of the environment.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void SetSegmentSize(SocketWho who, uint32_t segmentSize)
Forcefully set the segment size.
TcpSlowStartAttackerTest(uint32_t segmentSize, uint32_t packetSize, uint32_t initSsTh, uint32_t packets, TypeId &congControl, const std::string &desc)
Constructor.
virtual void ConfigureProperties()
Change the configuration of the socket properties.
bool m_initial
First cycle flag.
static const uint32_t packetSize
A suite of tests to run.
Definition: test.h:1343
virtual void CWndTrace(uint32_t oldValue, uint32_t newValue)
Trace the cWnd over the slow start.
uint32_t segmentSize
void SetBytesToAck(uint32_t bytes)
Set the bytes to be ACKed.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
virtual Ptr< TcpSocketMsgBase > CreateReceiverSocket(Ptr< Node > node)
Create and install the socket to install on the receiver.
void SetAppPktSize(uint32_t pktSize)
Set app packet size.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
Test the normal behavior for slow start.
void PhyDrop(SocketWho who)
Link drop.
SequenceNumber32 GetAckNumber() const
Get the ACK number.
Definition: tcp-header.cc:149
uint32_t m_allowedIncrease
Allowed increase.
TCP Slow Start TestSuite.
uint32_t m_packetSize
Packet size.
A slow start test using a socket which sends smaller ACKs.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
void QueueDrop(SocketWho who)
Drop on the queue.
uint32_t GetInitialSsThresh(SocketWho who)
Get the initial slow start threshold.
#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
static TcpSlowStartTestSuite g_tcpSlowStartTestSuite
Static variable for test initialization.
virtual void Rx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Packet received from IP layer.
void SetInitialSsThresh(SocketWho who, uint32_t initialSsThresh)
Forcefully set the initial ssthresh.
uint32_t m_packets
Packet counter.
virtual Ptr< TcpSocketMsgBase > CreateSocket(Ptr< Node > node, TypeId socketType, TypeId congControl)
Create a socket.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
TcpSlowStartNormalTest(uint32_t segmentSize, uint32_t packetSize, uint32_t initSsTh, uint32_t packets, TypeId &congControl, const std::string &desc)
Constructor.
uint32_t GetSegSize(SocketWho who)
Get the segment size of the node specified.
Header for the Transmission Control Protocol.
Definition: tcp-header.h:44
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.
uint32_t m_segmentSize
Segment size.
General infrastructure for TCP testing.
uint32_t m_ackedBytes
ACKed bytes.
uint32_t m_totalAckedBytes
Total ACKed bytes.
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
#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:830
This test suite implements a Unit Test.
Definition: test.h:1353
NUMERIC_TYPE GetValue() const
Extracts the numeric value of the sequence number.
#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:1016
a unique identifier for an interface.
Definition: type-id.h:58
virtual void Tx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Packet transmitted down to IP layer.
TypeId m_congControlTypeId
Congestion control.
uint32_t m_sentBytes
Sent bytes.