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 oopration 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 
230  event.m_oldCwnd = oldCwnd;
231  event.m_newCwnd = newCwnd;
232 
233  m_responses.Add (event);
234 }
235 
236 void
238 {
239  //
240  // Just create two nodes. One (node zero) will be the node with the TCP
241  // under test which is the ns-3 TCP implementation. The other node (node
242  // one) will be the node with the reference implementation we use to drive
243  // the tests.
244  //
246  nodes.Create (2);
247 
248  //
249  // For this test we'll use a point-to-point net device. It's not as simple
250  // as a simple-net-device, but it provides nice places to hook trace events
251  // so we can see what's moving between our nodes.
252  //
254  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
255  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
256 
257  //
258  // Install the point-to-point devices on both nodes and connec them up.
259  //
261  devices = pointToPoint.Install (nodes);
262 
263  //
264  // Install two variants of the internet stack. The first, on node zero
265  // uses the TCP under test, which is the default ns-3 TCP implementation.
266  //
268  stack.Install (nodes.Get (0));
269 
270  //
271  // The other node, node one, is going to be set up to use a Linux TCP
272  // implementation that we consider a known good TCP.
273  //
274  std::string nscStack = "liblinux2.6.26.so";
275  stack.SetTcp ("ns3::NscTcpL4Protocol", "Library", StringValue ("liblinux2.6.26.so"));
276  stack.Install (nodes.Get (1));
277 
278  //
279  // Assign the address 10.1.1.1 to the TCP implementation under test (index
280  // zero) and 10.1.1.2 to the reference implementation (index one).
281  //
283  address.SetBase ("10.1.1.0", "255.255.255.252");
284  Ipv4InterfaceContainer interfaces = address.Assign (devices);
285 
286  //
287  // We need a place to send our TCP data on the node with the reference TCP
288  // implementation. We aren't really concerned about what happens there, so
289  // just create a sink.
290  //
291  uint16_t sinkPort = 8080;
292  Address sinkAddress (InetSocketAddress (interfaces.GetAddress (1), sinkPort));
293  PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
294  ApplicationContainer sinkApps = packetSinkHelper.Install (nodes.Get (1));
295  sinkApps.Start (Seconds (0.));
296  sinkApps.Stop (Seconds (1.1));
297 
298  //
299  // We want to look at changes in the ns-3 TCP congestion window. The
300  // congestion window is flow clontrol imposed by the sender, so we need
301  // to crank up a flow from the ns-3 TCP node to the NSC TCP node and hook the
302  // CongestionWindow attribute on the socket. Normally one would use an on-off
303  // application to generate a flow, but this has a couple of problems. First,
304  // the socket of the on-off application is not created until Application Start
305  // time, so we wouldn't be able to hook the socket now at configuration time.
306  // Second, even if we could arrange a call after start time, the socket is not
307  // public.
308  //
309  // So, we can cook up a simple version of the on-off application that does what
310  // we want. On the plus side we don't need all of the complexity of the on-off
311  // application. On the minus side, we don't have a helper, so we have to get
312  // a little more involved in the details, but this is trivial.
313  //
314  // So first, we create a socket and do the trace connect on it; then we pass this
315  // socket into the constructor of our simple application which we then install
316  // in the node with the ns-3 TCP.
317  //
318  Ptr<Socket> ns3TcpSocket = Socket::CreateSocket (nodes.Get (0), TcpSocketFactory::GetTypeId ());
319  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeCallback (&Ns3TcpCwndTestCase1::CwndChange, this));
320 
321  Ptr<SimpleSource> app = CreateObject<SimpleSource> ();
322  app->Setup (ns3TcpSocket, sinkAddress, 1040, 10, DataRate ("5Mbps"));
323  nodes.Get (0)->AddApplication (app);
324  app->SetStartTime (Seconds (1.));
325  app->SetStopTime (Seconds (1.1));
326 
327  //
328  // The idea here is that someone will look very closely at the all of the
329  // communications between the reference TCP and the TCP under test in this
330  // simulation and determine that all of the responses are correct. We expect
331  // that this means generating a pcap trace file from the point-to-point link
332  // and examining the packets closely using tcpdump, wireshark or some such
333  // program. So we provide the ability to generate a pcap trace of the
334  // test execution for your perusal.
335  //
336  // Once the validation test is determined to be running exactly as exptected,
337  // the set of congestion window changes is collected and hard coded into the
338  // test results which will then be checked during the actual execution of the
339  // test.
340  //
341 
342  if (m_writeResults)
343  {
344  pointToPoint.EnablePcapAll ("tcp-cwnd");
345  }
346 
347  Simulator::Stop (Seconds (2));
348  Simulator::Run ();
349  Simulator::Destroy ();
350 
351  //
352  // As new acks are received by the TCP under test, the congestion window
353  // should be opened up by one segment (MSS bytes) each time. This should
354  // trigger a congestion window change event which we hooked and saved above.
355  // We should now be able to look through the saved response vectors and follow
356  // the congestion window as it opens up when the ns-3 TCP under test
357  // transmits its bits
358  //
359  // From inspecting the results, we know that we should see N_EVENTS congestion
360  // window change events. The window should expand N_EVENTS - 1 times (each
361  // time by MSS bytes) until it gets to its largest value. Then the application
362  // sending stops and the window should be slammed shut, with the last event
363  // reflecting the change from LARGEST_CWND back to MSS
364  //
365  const uint32_t MSS = 536;
366  const uint32_t N_EVENTS = 21;
367 
368  CwndEvent event;
369 
370  NS_TEST_ASSERT_MSG_EQ (m_responses.GetN (), N_EVENTS, "Unexpectedly low number of cwnd change events");
371 
372 
373  // Ignore the first event logged (i=0) when m_cWnd goes from 0 to MSS bytes
374  for (uint32_t i = 1, from = MSS, to = MSS * 2; i < N_EVENTS; ++i, from += MSS, to += MSS)
375  {
376  event = m_responses.Get (i);
377  NS_TEST_ASSERT_MSG_EQ (event.m_oldCwnd, from, "Wrong old cwnd value in cwnd change event " << i);
378  NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, to, "Wrong new cwnd value in cwnd change event " << i);
379  }
380 }
381 
382 
383 // ===========================================================================
384 // Test case for cwnd changes due to out-of-order packets. A bottleneck
385 // link is created, and a limited droptail queue is used in order to
386 // force dropped packets, resulting in out-of-order packet delivery.
387 // This out-of-order delivery will result in a different congestion
388 // window behavior than testcase 1. Specifically, duplicate ACKs
389 // are encountered.
390 //
391 // Network topology
392 //
393 // 1Mb/s, 10ms 100kb/s, 10ms 1Mb/s, 10ms
394 // n0--------------n1-----------------n2---------------n3
395 //
396 // ===========================================================================
398 {
399 public:
401  virtual ~Ns3TcpCwndTestCase2 ();
402 
403 private:
404  virtual void DoRun (void);
405  void VerifyCwndRun (uint32_t beginIdx, uint32_t endIdx, uint32_t initialCwnd, uint32_t mss);
407 
408  class CwndEvent {
409 public:
410  uint32_t m_oldCwnd;
411  uint32_t m_newCwnd;
412  };
413 
415 
416  void CwndChange (uint32_t oldCwnd, uint32_t newCwnd);
417 };
418 
420  : TestCase ("Check to see that the ns-3 TCP congestion window works as expected for out-of-order packet delivery"),
421  m_writeResults (false)
422 {
423 }
424 
426 {
427 }
428 
429 void
430 Ns3TcpCwndTestCase2::CwndChange (uint32_t oldCwnd, uint32_t newCwnd)
431 {
432  CwndEvent event;
433 
434  event.m_oldCwnd = oldCwnd;
435  event.m_newCwnd = newCwnd;
436 
437  m_responses.Add (event);
438 }
439 
440 void
442 {
443  // Set up some default values for the simulation.
444  Config::SetDefault ("ns3::DropTailQueue::MaxPackets", UintegerValue (4));
445 
446  NodeContainer n0n1;
447  n0n1.Create (2);
448 
450  n1n2.Add (n0n1.Get (1));
451  n1n2.Create (1);
452 
454  n2n3.Add (n1n2.Get (1));
455  n2n3.Create (1);
456 
457  PointToPointHelper p2p1;
458  p2p1.SetDeviceAttribute ("DataRate", DataRateValue (DataRate (1000000)));
459  p2p1.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (10)));
460  PointToPointHelper p2p2;
461  p2p2.SetDeviceAttribute ("DataRate", DataRateValue (DataRate (100000)));
462  p2p2.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (10)));
463 
464  // And then install devices and channels connecting our topology.
465  NetDeviceContainer dev0 = p2p1.Install (n0n1);
466  NetDeviceContainer dev1 = p2p2.Install (n1n2);
467  NetDeviceContainer dev2 = p2p1.Install (n2n3);
468 
469  // Now add ip/tcp stack to all nodes.
470  InternetStackHelper internet;
471  internet.InstallAll ();
472 
473  // Later, we add IP addresses.
474  Ipv4AddressHelper ipv4;
475  ipv4.SetBase ("10.1.3.0", "255.255.255.0");
476  ipv4.Assign (dev0);
477  ipv4.SetBase ("10.1.2.0", "255.255.255.0");
478  ipv4.Assign (dev1);
479  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
480  Ipv4InterfaceContainer ipInterfs = ipv4.Assign (dev2);
481 
482  // and setup ip routing tables to get total ip-level connectivity.
483  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
484 
485  // Set up the apps
486  uint16_t servPort = 50000;
487 
488  // Create a packet sink to receive these packets on n3
489  PacketSinkHelper sink ("ns3::TcpSocketFactory",
490  InetSocketAddress (Ipv4Address::GetAny (), servPort));
491 
492  ApplicationContainer apps = sink.Install (n2n3.Get (1));
493  apps.Start (Seconds (0.0));
494  apps.Stop (Seconds (5.4));
495 
496  // Create the socket for n0
497  Address sinkAddress (InetSocketAddress (ipInterfs.GetAddress (1), servPort));
498  Ptr<Socket> ns3TcpSocket = Socket::CreateSocket (n0n1.Get (0), TcpSocketFactory::GetTypeId ());
499  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeCallback (&Ns3TcpCwndTestCase2::CwndChange, this));
500 
501  // Create and start the app for n0
502  Ptr<SimpleSource> app = CreateObject<SimpleSource> ();
503  app->Setup (ns3TcpSocket, sinkAddress, 1040, 1000, DataRate ("1Mbps"));
504  n0n1.Get (0)->AddApplication (app);
505  app->SetStartTime (Seconds (1.0));
506  app->SetStopTime (Seconds (4.1));
507 
508  if (m_writeResults)
509  {
510  // Write a pcap for tcp cwnd testcase with out-of-order delivery
512  pointToPoint.EnablePcapAll ("tcp-cwnd-ood");
513  }
514 
515  // Finally, set up the simulator to run.
516  Simulator::Stop (Seconds (4.1));
517  Simulator::Run ();
518  Simulator::Destroy ();
519 
520  //
521  // As new acks are received by the TCP under test, the congestion window
522  // should be opened up by one segment (MSS bytes) each time. This should
523  // trigger a congestion window change event which we hooked and saved above.
524  // We should now be able to look through the saved response vectors and follow
525  // the congestion window as it opens up when the ns-3 TCP under test
526  // transmits its bits
527  //
528  // From inspecting the results, we know that we should see N_EVENTS congestion
529  // window change events. On the tenth change event, the window should
530  // be cut from 5360 to 4288 due to 3 dup acks (NewReno behavior is to
531  // cut in half, and then add 3 segments (5360/2 + 3*536 = 4288)
532  //
533 
534 
535 
536  const uint32_t MSS = 536;
537  const uint32_t N_EVENTS = 37;
538 
539  CwndEvent event;
540 
541  NS_TEST_ASSERT_MSG_EQ (m_responses.GetN (), N_EVENTS, "Unexpected number of cwnd change events");
542 
543  // Ignore the first event logged (i=0) when m_cWnd goes from 0 to MSS bytes
544  VerifyCwndRun (1, 10, 2 * MSS, MSS);
545 
546  // Cwnd should be back to (10/2 + 3) = 8*MSS
547  event = m_responses.Get (10);
548  NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, 8*MSS, "Wrong new cwnd value in cwnd change event " << 10);
549 
550  VerifyCwndRun (11, 13, 9 * MSS, MSS);
551 
552  // partial ack, cwnd reset to 9
553  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (14).m_newCwnd, 9 * MSS, "Wrong new cwnd value in cwnd change event " << 14);
554 
555  // partial ack, cwnd reset to 8
556  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (16).m_newCwnd, 8 * MSS, "Wrong new cwnd value in cwnd change event " << 16);
557 
558  //DUP ACKS in fast recovery
559  VerifyCwndRun (17, 18, 9 * MSS, MSS);
560 
561  VerifyCwndRun (19, 22, 8 * MSS, MSS);
562 
563  //Leaving fast recovery
564  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (23).m_newCwnd, 5 * MSS, "Wrong new cwnd value in cwnd change event " << 23);
565 
566  uint32_t cwnd = 5 * MSS;
567  //In CongAvoid each event will increase cwnd by (MSS * MSS / cwnd)
568  for (uint32_t i = 24; i < N_EVENTS; ++i)
569  {
570  double adder = static_cast<double> (MSS * MSS) / cwnd;
571  adder = std::max (1.0, adder);
572  cwnd += static_cast<uint32_t> (adder);
573  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (i).m_newCwnd, cwnd, "Wrong new cwnd value in cwnd change event " << i);
574  }
575 
576  for (uint32_t i = 0; i < N_EVENTS; ++i)
577  {
578  std::cout << "i: " << i << " newCwnd: " << m_responses.Get(i).m_newCwnd << " newCwnd segments " << static_cast<double> (m_responses.Get(i).m_newCwnd)/MSS << std::endl;
579  }
580 }
581 
582 void
583 Ns3TcpCwndTestCase2::VerifyCwndRun (uint32_t beginIdx, uint32_t endIdx, uint32_t initialCwnd, uint32_t mss)
584 {
585 
586  CwndEvent event;
587 
588  for(uint32_t i = beginIdx, to = initialCwnd; i < endIdx; ++i, to += mss)
589  {
590  event = m_responses.Get (i);
591  NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, to, "Wrong new cwnd value in cwnd change event " << i);
592  }
593 }
594 
596 {
597 public:
599 };
600 
602  : TestSuite ("ns3-tcp-cwnd", SYSTEM)
603 {
604  AddTestCase (new Ns3TcpCwndTestCase1, TestCase::QUICK);
605  AddTestCase (new Ns3TcpCwndTestCase2, TestCase::QUICK);
606 }
607 
holds a vector of ns3::Application pointers.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:150
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.
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.
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