A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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
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
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:1221
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:297
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.
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:223
virtual void Rx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Packet received from IP layer.
Fast test.
Definition: test.h:1152
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.
This test suite implements a Unit Test.
Definition: test.h:1343
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.