A Discrete-Event Network Simulator
API
tcp-zero-window-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 
20 #include "tcp-general-test.h"
21 #include "tcp-error-model.h"
22 #include "ns3/node.h"
23 #include "ns3/log.h"
24 
25 using namespace ns3;
26 
27 
28 NS_LOG_COMPONENT_DEFINE ("TcpZeroWindowTestSuite");
29 
37 {
38 public:
43  TcpZeroWindowTest (const std::string &desc);
44 
45 protected:
46  //virtual void ReceivePacket (Ptr<Socket> socket);
47  virtual Ptr<TcpSocketMsgBase> CreateReceiverSocket (Ptr<Node> node);
48 
49  virtual void Tx (const Ptr<const Packet> p, const TcpHeader&h, SocketWho who);
50  virtual void Rx (const Ptr<const Packet> p, const TcpHeader&h, SocketWho who);
51  virtual void ProcessedAck (const Ptr<const TcpSocketState> tcb,
52  const TcpHeader& h, SocketWho who);
53  void NormalClose (SocketWho who);
54  void FinalChecks ();
55 
56  virtual void ConfigureEnvironment ();
57  virtual void ConfigureProperties ();
58 
62  void IncreaseBufSize ();
63 
64 protected:
70 };
71 
72 TcpZeroWindowTest::TcpZeroWindowTest (const std::string &desc)
73  : TcpGeneralTest (desc),
74  m_zeroWindowProbe (false),
75  m_windowUpdated (false),
76  m_senderFinished (false),
77  m_receiverFinished (false)
78 {
79 }
80 
81 void
83 {
84  TcpGeneralTest::ConfigureEnvironment ();
85  SetAppPktCount (20);
86  SetMTU (500);
87  SetTransmitStart (Seconds (2.0));
89 }
90 
91 void
93 {
94  TcpGeneralTest::ConfigureProperties ();
95  SetInitialCwnd (SENDER, 10);
96 }
97 
98 void
100 {
101  SetRcvBufSize (RECEIVER, 2500);
102 }
103 
106 {
107  Ptr<TcpSocketMsgBase> socket = TcpGeneralTest::CreateReceiverSocket (node);
108 
109  socket->SetAttribute ("RcvBufSize", UintegerValue (0));
110  Simulator::Schedule (Seconds (10.0),
112 
113  return socket;
114 }
115 
116 void
118 {
119  if (who == SENDER)
120  {
121  NS_LOG_INFO ("\tSENDER TX " << h << " size " << p->GetSize ());
122 
123  if (Simulator::Now ().GetSeconds () <= 6.0)
124  {
125  NS_TEST_ASSERT_MSG_EQ (p->GetSize (), 0,
126  "Data packet sent anyway");
127  }
128  else if (Simulator::Now ().GetSeconds () > 6.0
129  && Simulator::Now ().GetSeconds () <= 7.0)
130  {
131  NS_TEST_ASSERT_MSG_EQ (m_zeroWindowProbe, false, "Sent another probe");
132 
133  if (!m_zeroWindowProbe)
134  {
135  NS_TEST_ASSERT_MSG_EQ (p->GetSize (), 1,
136  "Data packet sent instead of window probe");
138  "Data packet sent instead of window probe");
139  m_zeroWindowProbe = true;
140  }
141  }
142  else if (Simulator::Now ().GetSeconds () > 7.0
143  && Simulator::Now ().GetSeconds () < 10.0)
144  {
145  NS_FATAL_ERROR ("No packets should be sent before the window update");
146  }
147  }
148  else if (who == RECEIVER)
149  {
150  NS_LOG_INFO ("\tRECEIVER TX " << h << " size " << p->GetSize ());
151 
152  if (h.GetFlags () & TcpHeader::SYN)
153  {
155  "RECEIVER window size is not 0 in the SYN-ACK");
156  }
157 
158  if (Simulator::Now ().GetSeconds () > 6.0
159  && Simulator::Now ().GetSeconds () <= 7.0)
160  {
162  "Data packet sent instead of window probe");
164  "No zero window advertised by RECEIVER");
165  }
166  else if (Simulator::Now ().GetSeconds () > 7.0
167  && Simulator::Now ().GetSeconds () < 10.0)
168  {
169  NS_FATAL_ERROR ("No packets should be sent before the window update");
170  }
171  else if (Simulator::Now ().GetSeconds () >= 10.0)
172  {
174  "Receiver window not updated");
175  }
176  }
177 
178  NS_TEST_ASSERT_MSG_EQ (GetCongStateFrom (GetTcb (SENDER)), TcpSocketState::CA_OPEN,
179  "Sender State is not OPEN");
180  NS_TEST_ASSERT_MSG_EQ (GetCongStateFrom (GetTcb (RECEIVER)), TcpSocketState::CA_OPEN,
181  "Receiver State is not OPEN");
182 }
183 
184 void
186 {
187  if (who == SENDER)
188  {
189  NS_LOG_INFO ("\tSENDER RX " << h << " size " << p->GetSize ());
190 
191  if (h.GetFlags () & TcpHeader::SYN)
192  {
194  "RECEIVER window size is not 0 in the SYN-ACK");
195  }
196 
197  if (Simulator::Now ().GetSeconds () >= 10.0)
198  {
200  "Receiver window not updated");
201  m_windowUpdated = true;
202  }
203  }
204  else if (who == RECEIVER)
205  {
206  NS_LOG_INFO ("\tRECEIVER RX " << h << " size " << p->GetSize ());
207  }
208 }
209 
210 void
212 {
213  if (who == SENDER)
214  {
215  m_senderFinished = true;
216  }
217  else if (who == RECEIVER)
218  {
219  m_receiverFinished = true;
220  }
221 }
222 
223 void
225 {
227  "Zero window probe not sent");
229  "Window has not updated during the connection");
231  "Connection not closed successfully (SENDER)");
233  "Connection not closed successfully (RECEIVER)");
234 }
235 
236 void
238  const TcpHeader& h, SocketWho who)
239 {
240  if (who == SENDER)
241  {
242  if (h.GetFlags () & TcpHeader::SYN)
243  {
244  EventId persistentEvent = GetPersistentEvent (SENDER);
245  NS_TEST_ASSERT_MSG_EQ (persistentEvent.IsRunning (), true,
246  "Persistent event not started");
247  }
248  }
249  else if (who == RECEIVER)
250  {
251 
252  }
253 }
254 
255 
263 {
264 public:
265  TcpZeroWindowTestSuite () : TestSuite ("tcp-zero-window-test", UNIT)
266  {
267  AddTestCase (new TcpZeroWindowTest ("zero window test"),
268  TestCase::QUICK);
269  }
270 };
271 
273 
Testing the congestion avoidance increment on TCP ZeroWindow.
void FinalChecks()
Performs the (eventual) final checks through test asserts.
bool m_windowUpdated
Window updated.
virtual void ConfigureProperties()
Change the configuration of the socket properties.
virtual Ptr< TcpSocketMsgBase > CreateReceiverSocket(Ptr< Node > node)
Create and install the socket to install on the receiver.
bool m_senderFinished
Send finished.
bool m_receiverFinished
Receiver finished.
virtual void Rx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Packet received from IP layer.
virtual void ProcessedAck(const Ptr< const TcpSocketState > tcb, const TcpHeader &h, SocketWho who)
void IncreaseBufSize()
Increase the receiver buffer size.
virtual void Tx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Packet transmitted down to IP layer.
bool m_zeroWindowProbe
ZeroWindow probe.
TcpZeroWindowTest(const std::string &desc)
Constructor.
EventId m_receivePktEvent
Receive packet event.
virtual void ConfigureEnvironment()
Change the configuration of the environment.
void NormalClose(SocketWho who)
TCP ZeroWindow TestSuite.
An identifier for simulation events.
Definition: event-id.h:54
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:71
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
General infrastructure for TCP testing.
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.
Ptr< TcpSocketState > GetTcb(SocketWho who)
Get the TCB from selected socket.
void SetRcvBufSize(SocketWho who, uint32_t size)
Forcefully set a defined size for rx buffer.
EventId GetPersistentEvent(SocketWho who)
Get the persistent event of the selected socket.
void SetInitialCwnd(SocketWho who, uint32_t initialCwnd)
Forcefully set the initial cwnd.
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:45
SequenceNumber32 GetSequenceNumber() const
Get the sequence number.
Definition: tcp-header.cc:143
uint16_t GetWindowSize() const
Get the window size.
Definition: tcp-header.cc:179
uint8_t GetFlags() const
Get the flags.
Definition: tcp-header.cc:173
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
@ UNIT
This test suite implements a Unit Test.
Definition: test.h:1197
Hold an unsigned integer type.
Definition: uinteger.h:44
#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_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
static TcpSocketState::TcpCongState_t GetCongStateFrom(Ptr< const TcpSocketState > tcb)
Convenience function to retrieve the ACK state from a TCB.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1252
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static TcpZeroWindowTestSuite g_tcpZeroWindowTestSuite
Static variable for test initialization.