This documentation is not the Latest Release.
A Discrete-Event Network Simulator
API
ns3tcp-cwnd-test-suite.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 University of Washington
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 #include "ns3/log.h"
20 #include "ns3/abort.h"
21 #include "ns3/test.h"
22 #include "ns3/pcap-file.h"
23 #include "ns3/config.h"
24 #include "ns3/string.h"
25 #include "ns3/uinteger.h"
26 #include "ns3/data-rate.h"
27 #include "ns3/inet-socket-address.h"
28 #include "ns3/point-to-point-helper.h"
29 #include "ns3/internet-stack-helper.h"
30 #include "ns3/ipv4-global-routing-helper.h"
31 #include "ns3/ipv4-address-helper.h"
32 #include "ns3/packet-sink-helper.h"
33 #include "ns3/tcp-socket-factory.h"
34 #include "ns3/simulator.h"
35 
36 using namespace ns3;
37 
38 NS_LOG_COMPONENT_DEFINE ("Ns3CwndTest");
39 
40 // ===========================================================================
41 // This is a simple test to demonstrate how a known good model (a reference
42 // implementation) may be used to test another model without resorting to
43 // storing stimulus or response vectors.
44 //
45 // Node zero contains the model under test, in this case the ns-3 TCP
46 // implementation. Node one contains the reference implementation that we
47 // assume will generate good test vectors for us. In this case, a Linux
48 // TCP implementation is used to stimulate the ns-3 TCP model with what we
49 // assume are perfectly good packets. We watch the ns-3 implementation to
50 // see what it does in the presence of these assumed good stimuli.
51 //
52 // The test is arranged as a typical ns-3 script, but we use the trace system
53 // to peek into the running system and monitor the ns-3 TCP.
54 //
55 // The topology is just two nodes communicating over a point-to-point network.
56 // The point-to-point network is chosen because it is simple and allows us to
57 // easily generate pcap traces we can use to separately verify that the ns-3
58 // implementation is responding correctly. Once the operation is verified, we
59 // enter a list of responses that capture the response succinctly.
60 //
61 // node 0 node 1
62 // +----------------+ +----------------+
63 // | ns-3 TCP | | Linux TCP |
64 // +----------------+ +----------------+
65 // | 10.1.1.1 | | 10.1.1.2 |
66 // +----------------+ +----------------+
67 // | point-to-point | | point-to-point |
68 // +----------------+ +----------------+
69 // | |
70 // +---------------------+
71 // 5 Mbps, 2 ms
72 //
73 // ===========================================================================
74 //
75 class SimpleSource : public Application
76 {
77 public:
78 
79  SimpleSource ();
80  virtual ~SimpleSource();
81 
86  static TypeId GetTypeId (void);
87 
88  void Setup (Ptr<Socket> socket, Address address, uint32_t packetSize, uint32_t nPackets, DataRate dataRate);
89 
90 private:
91  virtual void StartApplication (void);
92  virtual void StopApplication (void);
93 
94  void ScheduleTx (void);
95  void SendPacket (void);
96 
99  uint32_t m_packetSize;
100  uint32_t m_nPackets;
103  bool m_running;
104  uint32_t m_packetsSent;
105 };
106 
108  : m_socket (0),
109  m_peer (),
110  m_packetSize (0),
111  m_nPackets (0),
112  m_dataRate (0),
113  m_sendEvent (),
114  m_running (false),
115  m_packetsSent (0)
116 {
117 }
118 
120 {
121  m_socket = 0;
122 }
123 
124 /* static */
125 TypeId
127 {
128  static TypeId tid = TypeId ("SimpleSource")
130  .SetGroupName ("Stats")
131  .AddConstructor<SimpleSource> ()
132  ;
133  return tid;
134 }
135 
136 void
137 SimpleSource::Setup (Ptr<Socket> socket, Address address, uint32_t packetSize, uint32_t nPackets, DataRate dataRate)
138 {
139  m_socket = socket;
140  m_peer = address;
142  m_nPackets = nPackets;
143  m_dataRate = dataRate;
144 }
145 
146 void
148 {
149  m_running = true;
150  m_packetsSent = 0;
151  m_socket->Bind ();
153  SendPacket ();
154 }
155 
156 void
158 {
159  m_running = false;
160 
161  if (m_sendEvent.IsRunning ())
162  {
163  Simulator::Cancel (m_sendEvent);
164  }
165 
166  if (m_socket)
167  {
168  m_socket->Close ();
169  }
170 }
171 
172 void
174 {
175  Ptr<Packet> packet = Create<Packet> (m_packetSize);
176  m_socket->Send (packet);
177 
178  if (++m_packetsSent < m_nPackets)
179  {
180  ScheduleTx ();
181  }
182 }
183 
184 void
186 {
187  if (m_running)
188  {
189  Time tNext (Seconds (m_packetSize * 8 / static_cast<double> (m_dataRate.GetBitRate ())));
190  m_sendEvent = Simulator::Schedule (tNext, &SimpleSource::SendPacket, this);
191  }
192 }
193 
195 {
196 public:
198  virtual ~Ns3TcpCwndTestCase1 ();
199 
200 private:
201  virtual void DoRun (void);
203 
204  class CwndEvent {
205 public:
206  uint32_t m_oldCwnd;
207  uint32_t m_newCwnd;
208  };
209 
211 
212  void CwndChange (uint32_t oldCwnd, uint32_t newCwnd);
213 };
214 
216  : TestCase ("Check to see that the ns-3 TCP congestion window works as expected against liblinux2.6.26.so"),
217  m_writeResults (false)
218 {
219 }
220 
222 {
223 }
224 
225 void
226 Ns3TcpCwndTestCase1::CwndChange (uint32_t oldCwnd, uint32_t newCwnd)
227 {
228  CwndEvent event;
229  NS_LOG_DEBUG ("Cwnd change event at " << Now ().As (Time::S) << " " << oldCwnd << " " << newCwnd);
230 
231  event.m_oldCwnd = oldCwnd;
232  event.m_newCwnd = newCwnd;
233 
234  m_responses.Add (event);
235 }
236 
237 void
239 {
240  NS_LOG_DEBUG ("Starting test case 1");
241  //
242  // Create two nodes. One (node zero) will be the node with the TCP
243  // under test which is the ns-3 TCP implementation. The other node (node
244  // one) will be the node with the reference implementation we use to drive
245  // the tests.
246  //
248  nodes.Create (2);
249 
250  //
251  // For this test we'll use a point-to-point net device. It's not as simple
252  // as a simple-net-device, but it provides nice places to hook trace events
253  // so we can see what's moving between our nodes.
254  //
256  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
257  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
258 
260  devices = pointToPoint.Install (nodes);
261 
262  //
263  // Install two variants of the internet stack. The first, on node zero
264  // uses the TCP under test, which is the default ns-3 TCP implementation.
265  //
267  stack.Install (nodes.Get (0));
268 
269  //
270  // The other node, node one, is going to be set up to use a Linux TCP
271  // implementation that we consider a known good TCP.
272  //
273  std::string nscStack = "liblinux2.6.26.so";
274  stack.SetTcp ("ns3::NscTcpL4Protocol", "Library", StringValue ("liblinux2.6.26.so"));
275  stack.Install (nodes.Get (1));
276 
277  //
278  // Assign the address 10.1.1.1 to the TCP implementation under test (index
279  // zero) and 10.1.1.2 to the reference implementation (index one).
280  //
282  address.SetBase ("10.1.1.0", "255.255.255.252");
283  Ipv4InterfaceContainer interfaces = address.Assign (devices);
284 
285  //
286  // We need a place to send our TCP data on the node with the reference TCP
287  // implementation. We aren't really concerned about what happens there, so
288  // just create a sink.
289  //
290  uint16_t sinkPort = 8080;
291  Address sinkAddress (InetSocketAddress (interfaces.GetAddress (1), sinkPort));
292  PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
293  ApplicationContainer sinkApps = packetSinkHelper.Install (nodes.Get (1));
294  sinkApps.Start (Seconds (0.));
295  sinkApps.Stop (Seconds (1.1));
296 
297  //
298  // This test uses a custom application that provides a direct handle to
299  // the socket (the socket of applications such as the OnOffApplication
300  // is not created until Application Start time, and is not easily accessible).
301  //
302  // So first, we create a socket and do the trace connect on it; then we pass this
303  // socket into the constructor of our simple application which we then install
304  // in the node with the ns-3 TCP.
305  //
306  Ptr<Socket> ns3TcpSocket = Socket::CreateSocket (nodes.Get (0), TcpSocketFactory::GetTypeId ());
307  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeCallback (&Ns3TcpCwndTestCase1::CwndChange, this));
308 
309  Ptr<SimpleSource> app = CreateObject<SimpleSource> ();
310  // 1040 is size of packet objects used to write data to the socket (note:
311  // the actual TCP segment size will be 536 bytes). 10 is the number
312  // of packets, so we write 10 * 1040 bytes. This requires 20 segments
313  // of payload size 536, with the last one being a partially full segment
314  app->Setup (ns3TcpSocket, sinkAddress, 1040, 10, DataRate ("5Mbps"));
315  nodes.Get (0)->AddApplication (app);
316  app->SetStartTime (Seconds (1.));
317  app->SetStopTime (Seconds (1.1));
318 
319  //
320  // The idea here is that someone will look very closely at the all of the
321  // communications between the reference TCP and the TCP under test in this
322  // simulation and determine that all of the responses are correct. We expect
323  // that this means generating a pcap trace file from the point-to-point link
324  // and examining the packets closely using tcpdump, wireshark or some such
325  // program. So we provide the ability to generate a pcap trace of the
326  // test execution for your perusal.
327  //
328  // Once the validation test is determined to be running exactly as expected,
329  // the set of congestion window changes is collected and hard coded into the
330  // test results which will then be checked during the actual execution of the
331  // test.
332  //
333 
334  if (m_writeResults)
335  {
336  pointToPoint.EnablePcapAll ("tcp-cwnd");
337  }
338 
339  Simulator::Stop (Seconds (2));
340  Simulator::Run ();
341  Simulator::Destroy ();
342 
343  //
344  // As new acks are received by the TCP under test, the congestion window
345  // should be opened up by one segment (MSS bytes) each time. This should
346  // trigger a congestion window change event which we hooked and saved above.
347  // We should now be able to look through the saved response vectors and follow
348  // the congestion window as it opens up when the ns-3 TCP under test
349  // transmits its bits
350  //
351  // From inspecting the results, we know that we should see N_EVENTS congestion
352  // window change events (each time by MSS bytes) until reaching the largest
353  // value when the client closes.
354  //
355  const uint32_t MSS = 536;
356  const uint32_t N_EVENTS = 20;
357 
358  CwndEvent event;
359 
360  NS_TEST_ASSERT_MSG_EQ (m_responses.GetN (), N_EVENTS, "Unexpectedly low number of cwnd change events");
361 
362 
363  // Ignore the first event logged (i=0) when m_cWnd goes from 0 to MSS bytes
364  for (uint32_t i = 1, from = MSS, to = MSS * 2; i < N_EVENTS; ++i, from += MSS, to += MSS)
365  {
366  event = m_responses.Get (i);
367  NS_TEST_ASSERT_MSG_EQ (event.m_oldCwnd, from, "Wrong old cwnd value in cwnd change event " << i);
368  NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, to, "Wrong new cwnd value in cwnd change event " << i);
369  }
370 }
371 
372 
373 // ===========================================================================
374 // Test case for cwnd changes due to out-of-order packets. A bottleneck
375 // link is created, and a limited droptail queue is used in order to
376 // force dropped packets, resulting in out-of-order packet delivery.
377 // This out-of-order delivery will result in a different congestion
378 // window behavior than testcase 1. Specifically, duplicate ACKs
379 // are encountered.
380 //
381 // Network topology
382 //
383 // 1Mb/s, 10ms 100kb/s, 10ms 1Mb/s, 10ms
384 // n0--------------n1-----------------n2---------------n3
385 //
386 // ===========================================================================
388 {
389 public:
391  virtual ~Ns3TcpCwndTestCase2 ();
392 
393 private:
394  virtual void DoRun (void);
395  void VerifyCwndRun (uint32_t beginIdx, uint32_t endIdx, uint32_t initialCwnd, uint32_t mss);
397 
398  class CwndEvent {
399 public:
400  uint32_t m_oldCwnd;
401  uint32_t m_newCwnd;
402  };
403 
405 
406  void CwndChange (uint32_t oldCwnd, uint32_t newCwnd);
407 };
408 
410  : TestCase ("Check to see that the ns-3 TCP congestion window works as expected for out-of-order packet delivery"),
411  m_writeResults (false)
412 {
413 }
414 
416 {
417 }
418 
419 void
420 Ns3TcpCwndTestCase2::CwndChange (uint32_t oldCwnd, uint32_t newCwnd)
421 {
422  CwndEvent event;
423  NS_LOG_DEBUG ("Cwnd change event at " << Now ().As (Time::S) << " " << oldCwnd << " " << newCwnd);
424 
425  event.m_oldCwnd = oldCwnd;
426  event.m_newCwnd = newCwnd;
427 
428  m_responses.Add (event);
429 }
430 
431 void
433 {
434  NS_LOG_DEBUG ("Starting test case 2");
435  // Set up some default values for the simulation.
436  Config::SetDefault ("ns3::DropTailQueue::MaxPackets", UintegerValue (4));
437 
438  NodeContainer n0n1;
439  n0n1.Create (2);
440 
442  n1n2.Add (n0n1.Get (1));
443  n1n2.Create (1);
444 
446  n2n3.Add (n1n2.Get (1));
447  n2n3.Create (1);
448 
449  PointToPointHelper p2p1;
450  p2p1.SetDeviceAttribute ("DataRate", DataRateValue (DataRate (1000000)));
451  p2p1.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (10)));
452  PointToPointHelper p2p2;
453  p2p2.SetDeviceAttribute ("DataRate", DataRateValue (DataRate (100000)));
454  p2p2.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (10)));
455 
456  // And then install devices and channels connecting our topology.
457  NetDeviceContainer dev0 = p2p1.Install (n0n1);
458  NetDeviceContainer dev1 = p2p2.Install (n1n2);
459  NetDeviceContainer dev2 = p2p1.Install (n2n3);
460 
461  // Now add ip/tcp stack to all nodes.
462  InternetStackHelper internet;
463  internet.InstallAll ();
464 
465  // Later, we add IP addresses.
466  Ipv4AddressHelper ipv4;
467  ipv4.SetBase ("10.1.3.0", "255.255.255.0");
468  ipv4.Assign (dev0);
469  ipv4.SetBase ("10.1.2.0", "255.255.255.0");
470  ipv4.Assign (dev1);
471  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
472  Ipv4InterfaceContainer ipInterfs = ipv4.Assign (dev2);
473 
474  // and setup ip routing tables to get total ip-level connectivity.
475  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
476 
477  // Set up the apps
478  uint16_t servPort = 50000;
479 
480  // Create a packet sink to receive these packets on n3
481  PacketSinkHelper sink ("ns3::TcpSocketFactory",
482  InetSocketAddress (Ipv4Address::GetAny (), servPort));
483 
484  ApplicationContainer apps = sink.Install (n2n3.Get (1));
485  apps.Start (Seconds (0.0));
486  apps.Stop (Seconds (5.4));
487 
488  // Create the socket for n0
489  Address sinkAddress (InetSocketAddress (ipInterfs.GetAddress (1), servPort));
490  Ptr<Socket> ns3TcpSocket = Socket::CreateSocket (n0n1.Get (0), TcpSocketFactory::GetTypeId ());
491  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeCallback (&Ns3TcpCwndTestCase2::CwndChange, this));
492 
493  // Create and start the app for n0
494  Ptr<SimpleSource> app = CreateObject<SimpleSource> ();
495  app->Setup (ns3TcpSocket, sinkAddress, 1040, 1000, DataRate ("1Mbps"));
496  n0n1.Get (0)->AddApplication (app);
497  app->SetStartTime (Seconds (1.0));
498  app->SetStopTime (Seconds (4.1));
499 
500  if (m_writeResults)
501  {
502  // Write a pcap for tcp cwnd testcase with out-of-order delivery
504  pointToPoint.EnablePcapAll ("tcp-cwnd-ood");
505  }
506 
507  // Finally, set up the simulator to run.
508  Simulator::Stop (Seconds (4.1));
509  Simulator::Run ();
510  Simulator::Destroy ();
511 
512  //
513  // As new acks are received by the TCP under test, the congestion window
514  // should be opened up by one segment (MSS bytes) each time. This should
515  // trigger a congestion window change event which we hooked and saved above.
516  // We should now be able to look through the saved response vectors and follow
517  // the congestion window as it opens up when the ns-3 TCP under test
518  // transmits its bits
519  //
520  // From inspecting the results, we know that we should see N_EVENTS congestion
521  // window change events. On the tenth change event, the window should
522  // be cut from 5360 to 4288 due to 3 dup acks (NewReno behavior is to
523  // cut in half, and then add 3 segments (5360/2 + 3*536 = 4288)
524  //
525 
526  const uint32_t MSS = 536;
527  const uint32_t N_EVENTS = 38;
528 
529  CwndEvent event;
530 
531  NS_TEST_ASSERT_MSG_EQ (m_responses.GetN (), N_EVENTS, "Unexpected number of cwnd change events");
532 
533  // Ignore the first event logged (i=0) when m_cWnd goes from 0 to MSS bytes
534  VerifyCwndRun (1, 10, 2 * MSS, MSS);
535 
536  // At the point of loss, sndNxt = 15009; sndUna = 9113, so there are
537  // 11 segments outstanding. Cut ssthresh to 11/2 and cwnd to (11/2 + 3)
538  // Cwnd should be back to (11/2 + 3) = 8.5*MSS
539  event = m_responses.Get (10);
540  NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, (MSS * 17)/2, "Wrong new cwnd value in cwnd change event " << 10);
541 
542  // Verify that cwnd increments by one for a few segments
543  // from 9.5 at index 11 to 12.5 at index 14
544  VerifyCwndRun (11, 14, (MSS * 19)/2, MSS);
545 
546  // partial ack at event 15, cwnd reset from 6700 (12.5*MSS) to 5628 (10.5*MSS)
547  // ack of 3 segments, so deflate by 3, and add back one
548  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (15).m_newCwnd, (MSS * 21)/2, "Wrong new cwnd value in cwnd change event " << 15);
549 
550  // partial ack again of 3 segments after one more acks, cwnd reset to 9.5
551  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (17).m_newCwnd, (MSS * 19)/2, "Wrong new cwnd value in cwnd change event " << 17);
552 
553  //DUP ACKS in remaining fast recovery
554  VerifyCwndRun (18, 19, (MSS * 21)/2, MSS);
555 
556  // another partial ack
557  //DUP ACKS in remaining fast recovery
558  VerifyCwndRun (21, 23, (MSS * 21)/2, MSS);
559 
560  //Leaving fast recovery at event 24; set cwnd to 11/2 from above
561  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (24).m_newCwnd, (MSS * 11)/2, "Wrong new cwnd value in cwnd change event " << 24);
562 
563  uint32_t cwnd = 11 * MSS/2;
564  //In CongAvoid each event will increase cwnd by (MSS * MSS / cwnd)
565  for (uint32_t i = 25; i < N_EVENTS; ++i)
566  {
567  double adder = static_cast<double> (MSS * MSS) / cwnd;
568  adder = std::max (1.0, adder);
569  cwnd += static_cast<uint32_t> (adder);
570  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (i).m_newCwnd, cwnd, "Wrong new cwnd value in cwnd change event " << i);
571  }
572  NS_LOG_DEBUG ("Reading out the cwnd event log");
573  for (uint32_t i = 0; i < N_EVENTS; ++i)
574  {
575  NS_LOG_DEBUG ("i: " << i << " newCwnd: " << m_responses.Get(i).m_newCwnd << " newCwnd segments " << static_cast<double> (m_responses.Get(i).m_newCwnd)/MSS);
576  }
577 }
578 
579 void
580 Ns3TcpCwndTestCase2::VerifyCwndRun (uint32_t beginIdx, uint32_t endIdx, uint32_t initialCwnd, uint32_t mss)
581 {
582 
583  CwndEvent event;
584 
585  for(uint32_t i = beginIdx, to = initialCwnd; i < endIdx; ++i, to += mss)
586  {
587  event = m_responses.Get (i);
588  NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, to, "Wrong new cwnd value in cwnd change event " << i);
589  }
590 }
591 
593 {
594 public:
596 };
597 
599  : TestSuite ("ns3-tcp-cwnd", SYSTEM)
600 {
601  AddTestCase (new Ns3TcpCwndTestCase1, TestCase::QUICK);
602  AddTestCase (new Ns3TcpCwndTestCase2, TestCase::QUICK);
603 }
604 
holds a vector of ns3::Application pointers.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:157
Ptr< Socket > m_socket
static void SendPacket(Ptr< Socket > socket, uint32_t pktSize, uint32_t pktCount, Time pktInterval)
tuple pointToPoint
Definition: first.py:28
void SetStopTime(Time stop)
Specify application stop time.
Definition: application.cc:75
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
an Inet address class
tuple devices
Definition: first.py:32
NodeContainer n1n2
Definition: red-tests.cc:63
holds a vector of std::pair of Ptr and interface index.
Hold variables of type string.
Definition: string.h:41
NetDeviceContainer Install(NodeContainer c)
A suite of tests to run.
Definition: test.h:1333
#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
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes...
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:65
Build a set of PointToPointNetDevice objects.
void CwndChange(uint32_t oldCwnd, uint32_t newCwnd)
encapsulates test code
Definition: test.h:1147
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
a polymophic address class
Definition: address.h:90
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1396
virtual void StopApplication(void)
Application specific shutdown code.
tuple nodes
Definition: first.py:25
Class for representing data rates.
Definition: data-rate.h:88
TestVectors< CwndEvent > m_responses
void EnablePcapAll(std::string prefix, bool promiscuous=false)
Enable pcap output on each device (which is of the appropriate type) in the set of all nodes created ...
void InstallAll(void) const
Aggregate IPv4, IPv6, UDP, and TCP stacks to all nodes in the simulation.
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:297
The base class for all ns3 applications.
Definition: application.h:60
AttributeValue implementation for Time.
Definition: nstime.h:957
virtual void StartApplication(void)
Application specific startup code.
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
tuple interfaces
Definition: first.py:41
holds a vector of ns3::NetDevice pointers
virtual void DoRun(void)
Implementation to actually run this TestCase.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1480
Ns3TcpCwndTestSuite ns3TcpCwndTestSuite
void Start(Time start)
Arrange for all of the Applications in this container to Start() at the Time given as a parameter...
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
void VerifyCwndRun(uint32_t beginIdx, uint32_t endIdx, uint32_t initialCwnd, uint32_t mss)
static TypeId GetTypeId(void)
Register this type.
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:299
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
void SetTcp(std::string tid)
set the Tcp stack which will not need any other parameter.
uint64_t GetBitRate() const
Get the underlying bitrate.
Definition: data-rate.cc:249
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
TestVectors< CwndEvent > m_responses
tuple stack
Definition: first.py:34
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
void Stop(Time stop)
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter...
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
void Add(NodeContainer other)
Append the contents of another NodeContainer to the end of this container.
An identifier for simulation events.
Definition: event-id.h:53
AttributeValue implementation for DataRate.
Definition: data-rate.h:241
Ptr< Node > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:774
void Setup(Ptr< Socket > socket, Address address, uint32_t packetSize, uint32_t nPackets, DataRate dataRate)
NodeContainer n2n3
Definition: red-tests.cc:64
ApplicationContainer Install(NodeContainer c) const
Install an ns3::PacketSinkApplication on each node of the input container configured with all the att...
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:330
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
static const uint32_t packetSize
tuple address
Definition: first.py:37
void CwndChange(uint32_t oldCwnd, uint32_t newCwnd)
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
virtual int Close(void)=0
Close a socket.
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:826
void SetStartTime(Time start)
Specify application start time.
Definition: application.cc:69
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const