A Discrete-Event Network Simulator
API
ns3tcp-no-delay-test-suite.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License version 2 as
4  * published by the Free Software Foundation;
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program; if not, write to the Free Software
13  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14  */
15 
16 #include "ns3tcp-socket-writer.h"
17 
18 #include "ns3/abort.h"
19 #include "ns3/boolean.h"
20 #include "ns3/config.h"
21 #include "ns3/csma-helper.h"
22 #include "ns3/data-rate.h"
23 #include "ns3/inet-socket-address.h"
24 #include "ns3/internet-stack-helper.h"
25 #include "ns3/ipv4-address-helper.h"
26 #include "ns3/ipv4-global-routing-helper.h"
27 #include "ns3/log.h"
28 #include "ns3/node-container.h"
29 #include "ns3/packet-sink-helper.h"
30 #include "ns3/pcap-file.h"
31 #include "ns3/point-to-point-helper.h"
32 #include "ns3/simulator.h"
33 #include "ns3/string.h"
34 #include "ns3/tcp-socket-factory.h"
35 #include "ns3/test.h"
36 #include "ns3/uinteger.h"
37 
38 using namespace ns3;
39 
40 NS_LOG_COMPONENT_DEFINE("Ns3TcpNoDelayTest");
41 
48 {
49  public:
55  Ns3TcpNoDelayTestCase(bool noDelay);
56 
58  {
59  }
60 
61  private:
62  void DoRun() override;
63  bool m_noDelay;
65 
72  void SinkRx(std::string path, Ptr<const Packet> p, const Address& address);
73 
76 };
77 
79  : TestCase(
80  "Check that ns-3 TCP Nagle's algorithm works correctly and that we can turn it off."),
81  m_noDelay(noDelay),
82  m_writeResults(false)
83 {
84 }
85 
86 void
88 {
89  m_responses.Add(p->GetSize());
90 }
91 
92 void
94 {
95  uint16_t sinkPort = 50000;
96  double sinkStopTime = 8; // sec; will trigger Socket::Close
97  double writerStopTime = 5; // sec; will trigger Socket::Close
98  double simStopTime = 10; // sec
99  Time sinkStopTimeObj = Seconds(sinkStopTime);
100  Time writerStopTimeObj = Seconds(writerStopTime);
101  Time simStopTimeObj = Seconds(simStopTime);
102 
103  Ptr<Node> n0 = CreateObject<Node>();
104  Ptr<Node> n1 = CreateObject<Node>();
105 
107  pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
108  pointToPoint.SetChannelAttribute("Delay", StringValue("2ms"));
109 
111  devices = pointToPoint.Install(n0, n1);
112 
114  internet.InstallAll();
115 
117  address.SetBase("10.1.1.0", "255.255.255.252");
118  Ipv4InterfaceContainer ifContainer = address.Assign(devices);
119 
120  Ptr<SocketWriter> socketWriter = CreateObject<SocketWriter>();
121  Address sinkAddress(InetSocketAddress(ifContainer.GetAddress(1), sinkPort));
122  socketWriter->Setup(n0, sinkAddress);
123  n0->AddApplication(socketWriter);
124  socketWriter->SetStartTime(Seconds(0.));
125  socketWriter->SetStopTime(writerStopTimeObj);
126 
127  PacketSinkHelper sink("ns3::TcpSocketFactory",
128  InetSocketAddress(Ipv4Address::GetAny(), sinkPort));
129  ApplicationContainer apps = sink.Install(n1);
130  // Start the sink application at time zero, and stop it at sinkStopTime
131  apps.Start(Seconds(0.0));
132  apps.Stop(sinkStopTimeObj);
133 
134  Config::Connect("/NodeList/*/ApplicationList/*/$ns3::PacketSink/Rx",
136 
137  // Enable or disable TCP no delay option
138  Config::SetDefault("ns3::TcpSocket::TcpNoDelay", BooleanValue(m_noDelay));
139  // This test was written with initial window of 1 segment
140  Config::SetDefault("ns3::TcpSocket::InitialCwnd", UintegerValue(1));
141 
142  // Connect the socket writer
143  Simulator::Schedule(Seconds(1), &SocketWriter::Connect, socketWriter);
144 
145  // Write 5 packets to get some bytes in flight and some acks going
146  Simulator::Schedule(Seconds(2), &SocketWriter::Write, socketWriter, 2680);
147  m_inputs.Add(536);
148  m_inputs.Add(536);
149  m_inputs.Add(536);
150  m_inputs.Add(536);
151  m_inputs.Add(536);
152 
153  // Write one byte after 10 ms to ensure that some data is outstanding
154  // and the window is big enough
155  Simulator::Schedule(Seconds(2.010), &SocketWriter::Write, socketWriter, 1);
156 
157  // If Nagle is not enabled, i.e. no delay is on, add an input for a 1-byte
158  // packet to be received
159  if (m_noDelay)
160  {
161  m_inputs.Add(1);
162  }
163 
164  // One ms later, write 535 bytes, i.e. one segment size - 1
165  Simulator::Schedule(Seconds(2.012), &SocketWriter::Write, socketWriter, 535);
166 
167  // If Nagle is not enabled, add an input for a 535 byte packet,
168  // otherwise, we should get a single "full" packet of 536 bytes
169  if (m_noDelay)
170  {
171  m_inputs.Add(535);
172  }
173  else
174  {
175  m_inputs.Add(536);
176  }
177 
178  // Close down the socket
179  Simulator::Schedule(writerStopTimeObj, &SocketWriter::Close, socketWriter);
180 
181  if (m_writeResults)
182  {
183  std::ostringstream oss;
184  if (m_noDelay)
185  {
186  oss << "tcp-no-delay-on-test-case";
187  pointToPoint.EnablePcapAll(oss.str());
188  }
189  else
190  {
191  oss << "tcp-no-delay-off-test-case";
192  pointToPoint.EnablePcapAll(oss.str());
193  }
194  }
195 
196  Simulator::Stop(simStopTimeObj);
197  Simulator::Run();
198  Simulator::Destroy();
199 
200  // Compare inputs and outputs
202  m_responses.GetN(),
203  "Incorrect number of expected receive events");
204  for (uint32_t i = 0; i < m_responses.GetN(); i++)
205  {
206  uint32_t in = m_inputs.Get(i);
207  uint32_t out = m_responses.Get(i);
209  out,
210  "Mismatch: expected " << in << " bytes, got " << out << " bytes");
211  }
212 }
213 
220 {
221  public:
223 };
224 
226  : TestSuite("ns3-tcp-no-delay", SYSTEM)
227 {
228  AddTestCase(new Ns3TcpNoDelayTestCase(true), TestCase::QUICK);
229  AddTestCase(new Ns3TcpNoDelayTestCase(false), TestCase::QUICK);
230 }
231 
Tests of Nagle's algorithm and the TCP no delay option.
Ns3TcpNoDelayTestCase(bool noDelay)
Constructor.
bool m_noDelay
Enable or disable TCP no delay option.
void SinkRx(std::string path, Ptr< const Packet > p, const Address &address)
Receive a TCP packet.
TestVectors< uint32_t > m_responses
Received packets test vector.
void DoRun() override
Implementation to actually run this TestCase.
bool m_writeResults
True if write PCAP files.
TestVectors< uint32_t > m_inputs
Sent packets test vector.
TCP Nagle's algorithm and the TCP no delay option TestSuite.
a polymophic address class
Definition: address.h:101
holds a vector of ns3::Application pointers.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
holds a vector of ns3::NetDevice pointers
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:169
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
Build a set of PointToPointNetDevice objects.
Hold variables of type string.
Definition: string.h:56
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
T Get(std::size_t i) const
Get the i'th test vector.
Definition: test.h:1401
std::size_t GetN() const
Get the total number of test vectors.
Definition: test.h:1394
std::size_t Add(T vector)
Definition: test.h:1385
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
Hold an unsigned integer type.
Definition: uinteger.h:45
static void SinkRx(std::string path, Ptr< const Packet > p, const Address &address)
Rx sink.
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:974
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#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
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
address
Definition: first.py:47
pointToPoint
Definition: first.py:38
devices
Definition: first.py:42
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
static Ns3TcpNoDelayTestSuite g_ns3TcpNoDelayTestSuite
Do not forget to allocate an instance of this TestSuite.
Ptr< PacketSink > sink
Pointer to the packet sink application.
Definition: wifi-tcp.cc:55