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 namespace ns3 {
26 
27 NS_LOG_COMPONENT_DEFINE ("TcpZeroWindowTestSuite");
28 
30 {
31 public:
32  TcpZeroWindowTest (const std::string &desc);
33 
34 protected:
35  //virtual void ReceivePacket (Ptr<Socket> socket);
37 
38  virtual void Tx (const Ptr<const Packet> p, const TcpHeader&h, SocketWho who);
39  virtual void Rx (const Ptr<const Packet> p, const TcpHeader&h, SocketWho who);
40  virtual void ProcessedAck (const Ptr<const TcpSocketState> tcb,
41  const TcpHeader& h, SocketWho who);
42  void NormalClose (SocketWho who);
43  void FinalChecks ();
44 
45  virtual void ConfigureEnvironment ();
46  virtual void ConfigureProperties ();
47 
48  void IncreaseBufSize ();
49 
50 protected:
56 };
57 
58 TcpZeroWindowTest::TcpZeroWindowTest (const std::string &desc)
59  : TcpGeneralTest (desc),
60  m_zeroWindowProbe (false),
61  m_windowUpdated (false),
62  m_senderFinished (false),
63  m_receiverFinished (false)
64 {
65 }
66 
67 void
69 {
71  SetAppPktCount (20);
72  SetMTU (500);
73  SetTransmitStart (Seconds (2.0));
75 }
76 
77 void
79 {
81  SetInitialCwnd (SENDER, 10);
82 }
83 
84 void
86 {
87  SetRcvBufSize (RECEIVER, 2500);
88 }
89 
92 {
94 
95  socket->SetAttribute ("RcvBufSize", UintegerValue (0));
98 
99  return socket;
100 }
101 
102 void
104 {
105  if (who == SENDER)
106  {
107  NS_LOG_INFO ("\tSENDER TX " << h << " size " << p->GetSize ());
108 
109  if (Simulator::Now ().GetSeconds () <= 6.0)
110  {
111  NS_TEST_ASSERT_MSG_EQ (p->GetSize (), 0,
112  "Data packet sent anyway");
113  }
114  else if (Simulator::Now ().GetSeconds () > 6.0
115  && Simulator::Now ().GetSeconds () <= 7.0)
116  {
117  NS_TEST_ASSERT_MSG_EQ (m_zeroWindowProbe, false, "Sent another probe");
118 
119  if (!m_zeroWindowProbe)
120  {
121  NS_TEST_ASSERT_MSG_EQ (p->GetSize (), 1,
122  "Data packet sent instead of window probe");
124  "Data packet sent instead of window probe");
125  m_zeroWindowProbe = true;
126  }
127  }
128  else if (Simulator::Now ().GetSeconds () > 7.0
129  && Simulator::Now ().GetSeconds () < 10.0)
130  {
131  NS_FATAL_ERROR ("No packets should be sent before the window update");
132  }
133  }
134  else if (who == RECEIVER)
135  {
136  NS_LOG_INFO ("\tRECEIVER TX " << h << " size " << p->GetSize ());
137 
138  if (h.GetFlags () & TcpHeader::SYN)
139  {
141  "RECEIVER window size is not 0 in the SYN-ACK");
142  }
143 
144  if (Simulator::Now ().GetSeconds () > 6.0
145  && Simulator::Now ().GetSeconds () <= 7.0)
146  {
148  "Data packet sent instead of window probe");
150  "No zero window advertised by RECEIVER");
151  }
152  else if (Simulator::Now ().GetSeconds () > 7.0
153  && Simulator::Now ().GetSeconds () < 10.0)
154  {
155  NS_FATAL_ERROR ("No packets should be sent before the window update");
156  }
157  else if (Simulator::Now ().GetSeconds () >= 10.0)
158  {
160  "Receiver window not updated");
161  }
162  }
163 
165  "Sender State is not OPEN");
167  "Receiver State is not OPEN");
168 }
169 
170 void
172 {
173  if (who == SENDER)
174  {
175  NS_LOG_INFO ("\tSENDER RX " << h << " size " << p->GetSize ());
176 
177  if (h.GetFlags () & TcpHeader::SYN)
178  {
180  "RECEIVER window size is not 0 in the SYN-ACK");
181  }
182 
183  if (Simulator::Now ().GetSeconds () >= 10.0)
184  {
186  "Receiver window not updated");
187  m_windowUpdated = true;
188  }
189  }
190  else if (who == RECEIVER)
191  {
192  NS_LOG_INFO ("\tRECEIVER RX " << h << " size " << p->GetSize ());
193  }
194 }
195 
196 void
198 {
199  if (who == SENDER)
200  {
201  m_senderFinished = true;
202  }
203  else if (who == RECEIVER)
204  {
205  m_receiverFinished = true;
206  }
207 }
208 
209 void
211 {
213  "Zero window probe not sent");
215  "Window has not updated during the connection");
217  "Connection not closed successfully (SENDER)");
219  "Connection not closed successfully (RECEIVER)");
220 }
221 
222 void
224  const TcpHeader& h, SocketWho who)
225 {
226  if (who == SENDER)
227  {
228  if (h.GetFlags () & TcpHeader::SYN)
229  {
230  EventId persistentEvent = GetPersistentEvent (SENDER);
231  NS_TEST_ASSERT_MSG_EQ (persistentEvent.IsRunning (), true,
232  "Persistent event not started");
233  }
234  }
235  else if (who == RECEIVER)
236  {
237 
238  }
239 }
240 
241 //-----------------------------------------------------------------------------
242 
243 static class TcpZeroWindowTestSuite : public TestSuite
244 {
245 public:
246  TcpZeroWindowTestSuite () : TestSuite ("tcp-zero-window-test", UNIT)
247  {
248  AddTestCase (new TcpZeroWindowTest ("zero window test"),
250  }
252 
253 } // namespace ns3
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
Normal state, no dubious events.
SequenceNumber32 GetSequenceNumber() const
Get the sequence number.
Definition: tcp-header.cc:143
uint8_t GetFlags() const
Get the flags.
Definition: tcp-header.cc:173
Fast test.
Definition: test.h:1152
A suite of tests to run.
Definition: test.h:1333
virtual Ptr< TcpSocketMsgBase > CreateReceiverSocket(Ptr< Node > node)
Create and install the socket to install on the receiver.
TcpZeroWindowTest(const std::string &desc)
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:903
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:792
void SetTransmitStart(Time startTime)
Set the initial time at which the application sends the first data packet.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:65
This test suite implements a Unit Test.
Definition: test.h:1343
static TcpSocketState::TcpCongState_t GetCongStateFrom(Ptr< const TcpSocketState > tcb)
Convenience function to retrieve the ACK state from a TCB.
void NormalClose(SocketWho who)
Socket closed normally.
ns3::TcpZeroWindowTestSuite g_tcpZeroWindowTestSuite
virtual Ptr< TcpSocketMsgBase > CreateReceiverSocket(Ptr< Node > node)
Create and install the socket to install on the receiver.
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:341
void FinalChecks()
Performs the (eventual) final checks through test asserts.
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1238
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:298
uint16_t GetWindowSize() const
Get the window size.
Definition: tcp-header.cc:179
void SetMTU(uint32_t mtu)
MTU of the bottleneck link.
virtual void ConfigureProperties(void)
Change the configuration of the socket properties.
virtual void ProcessedAck(const Ptr< const TcpSocketState > tcb, const TcpHeader &h, SocketWho who)
Processed ack.
Hold an unsigned integer type.
Definition: uinteger.h:44
#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:161
void SetInitialCwnd(SocketWho who, uint32_t initialCwnd)
Forcefully set the initial cwnd.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Header for the Transmission Control Protocol.
Definition: tcp-header.h:44
void SetAppPktCount(uint32_t pktCount)
Set app packet count.
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:224
virtual void Rx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Packet received from IP layer.
SocketWho
Used as parameter of methods, specifies on what node the caller is interested (e.g.
General infrastructure for TCP testing.
An identifier for simulation events.
Definition: event-id.h:53
virtual void ConfigureEnvironment(void)
Change the configuration of the evironment.
virtual void ConfigureProperties()
Change the configuration of the socket properties.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
Ptr< TcpSocketState > GetTcb(SocketWho who)
Get the TCB from selected socket.
EventId GetPersistentEvent(SocketWho who)
Get the persistent event of the selected socket.
void SetRcvBufSize(SocketWho who, uint32_t size)
Forcefully set a defined size for rx buffer.
virtual void Tx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Packet transmitted down to IP layer.
virtual void ConfigureEnvironment()
Change the configuration of the evironment.
SequenceNumber< uint32_t, int32_t > SequenceNumber32
32 bit Sequence number.
void SetPropagationDelay(Time propDelay)
Propagation delay of the bottleneck link.