A Discrete-Event Network Simulator
API
tcp-slow-start-test.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 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 #include "tcp-general-test.h"
19 
20 #include "ns3/config.h"
21 #include "ns3/log.h"
22 #include "ns3/node.h"
23 #include "ns3/simple-channel.h"
24 #include "ns3/tcp-header.h"
25 #include "ns3/test.h"
26 
27 using namespace ns3;
28 
29 NS_LOG_COMPONENT_DEFINE("TcpSlowStartTest");
30 
46 {
47  public:
58  uint32_t packetSize,
59  uint32_t initSsTh,
60  uint32_t packets,
61  const TypeId& congControl,
62  const std::string& desc);
63 
64  protected:
65  void CWndTrace(uint32_t oldValue, uint32_t newValue) override;
66  void Tx(const Ptr<const Packet> p, const TcpHeader& h, SocketWho who) override;
67  void Rx(const Ptr<const Packet> p, const TcpHeader& h, SocketWho who) override;
68  void QueueDrop(SocketWho who) override;
69  void PhyDrop(SocketWho who) override;
70 
71  void ConfigureEnvironment() override;
72  void ConfigureProperties() override;
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  const 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 << " 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 
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 {
220  public:
231  uint32_t packetSize,
232  uint32_t initSsTh,
233  uint32_t packets,
234  const TypeId& congControl,
235  const std::string& desc);
236 
237  protected:
239 };
240 
242  uint32_t packetSize,
243  uint32_t initSsTh,
244  uint32_t packets,
245  const TypeId& typeId,
246  const std::string& msg)
247  : TcpSlowStartNormalTest(segmentSize, packetSize, initSsTh, packets, typeId, msg)
248 {
249 }
250 
253 {
254  Ptr<TcpSocketSmallAcks> socket = DynamicCast<TcpSocketSmallAcks>(
255  CreateSocket(node, TcpSocketSmallAcks::GetTypeId(), m_congControlTypeId));
256  socket->SetBytesToAck(125);
257 
258  return socket;
259 }
260 
267 {
268  public:
270  : TestSuite("tcp-slow-start-test", UNIT)
271  {
272  // This test have less packets to transmit than SsTh
273  std::list<TypeId> types = {
274  TcpNewReno::GetTypeId(),
275  };
276 
277  for (const auto& t : types)
278  {
279  std::string typeName = t.GetName();
280 
282  500,
283  10000,
284  10,
285  t,
286  "slow start 500 byte, " + typeName),
287  TestCase::QUICK);
289  1000,
290  10000,
291  9,
292  t,
293  "slow start 1000 byte, " + typeName),
294  TestCase::QUICK);
296  250,
297  10000,
298  10,
299  t,
300  "slow start small packets, " + typeName),
301  TestCase::QUICK);
302  AddTestCase(
303  new TcpSlowStartAttackerTest(500,
304  500,
305  10000,
306  10,
307  t,
308  "slow start ack attacker, 500 byte, " + typeName),
309  TestCase::QUICK);
310  AddTestCase(
311  new TcpSlowStartAttackerTest(1000,
312  1000,
313  10000,
314  9,
315  t,
316  "slow start ack attacker, 1000 byte, " + typeName),
317  TestCase::QUICK);
318  }
319  }
320 };
321 
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.
Ptr< TcpSocketMsgBase > CreateReceiverSocket(Ptr< Node > node) override
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.
void CWndTrace(uint32_t oldValue, uint32_t newValue) override
Trace the cWnd over the slow start.
void ConfigureEnvironment() override
Change the configuration of the environment.
uint32_t m_packetSize
Packet size.
void Tx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who) override
Packet transmitted down to IP layer.
uint32_t m_packets
Packet counter.
uint32_t m_ackedBytes
ACKed bytes.
uint32_t m_segmentSize
Segment size.
void PhyDrop(SocketWho who) override
void QueueDrop(SocketWho who) override
uint32_t m_sentBytes
Sent bytes.
uint32_t m_totalAckedBytes
Total ACKed bytes.
void Rx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who) override
Packet received from IP layer.
void ConfigureProperties() override
Change the configuration of the socket properties.
uint32_t m_allowedIncrease
Allowed increase.
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:47
SequenceNumber32 GetAckNumber() const
Get the ACK number.
Definition: tcp-header.cc:124
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
std::string GetName() const
Definition: test.cc:373
A suite of tests to run.
Definition: test.h:1256
@ UNIT
This test suite implements a Unit Test.
Definition: test.h:1265
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:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#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:275
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:305
#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_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:750
#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:915
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
Packet size generated at the AP.