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/traffic-control-helper.h"
35 #include "ns3/simulator.h"
36 
37 using namespace ns3;
38 
39 NS_LOG_COMPONENT_DEFINE ("Ns3CwndTest");
40 
41 // ===========================================================================
42 // This is a simple test to demonstrate how a known good model (a reference
43 // implementation) may be used to test another model without resorting to
44 // storing stimulus or response vectors.
45 //
46 // Node zero contains the model under test, in this case the ns-3 TCP
47 // implementation. Node one contains the reference implementation that we
48 // assume will generate good test vectors for us. In this case, a Linux
49 // TCP implementation is used to stimulate the ns-3 TCP model with what we
50 // assume are perfectly good packets. We watch the ns-3 implementation to
51 // see what it does in the presence of these assumed good stimuli.
52 //
53 // The test is arranged as a typical ns-3 script, but we use the trace system
54 // to peek into the running system and monitor the ns-3 TCP.
55 //
56 // The topology is just two nodes communicating over a point-to-point network.
57 // The point-to-point network is chosen because it is simple and allows us to
58 // easily generate pcap traces we can use to separately verify that the ns-3
59 // implementation is responding correctly. Once the operation is verified, we
60 // enter a list of responses that capture the response succinctly.
61 //
62 // node 0 node 1
63 // +----------------+ +----------------+
64 // | ns-3 TCP | | Linux TCP |
65 // +----------------+ +----------------+
66 // | 10.1.1.1 | | 10.1.1.2 |
67 // +----------------+ +----------------+
68 // | point-to-point | | point-to-point |
69 // +----------------+ +----------------+
70 // | |
71 // +---------------------+
72 // 5 Mbps, 2 ms
73 //
74 // ===========================================================================
75 //
76 class SimpleSource : public Application
77 {
78 public:
79 
80  SimpleSource ();
81  virtual ~SimpleSource();
82 
87  static TypeId GetTypeId (void);
88 
89  void Setup (Ptr<Socket> socket, Address address, uint32_t packetSize, uint32_t nPackets, DataRate dataRate);
90 
91 private:
92  virtual void StartApplication (void);
93  virtual void StopApplication (void);
94 
95  void ScheduleTx (void);
96  void SendPacket (void);
97 
100  uint32_t m_packetSize;
101  uint32_t m_nPackets;
104  bool m_running;
105  uint32_t m_packetsSent;
106 };
107 
109  : m_socket (0),
110  m_peer (),
111  m_packetSize (0),
112  m_nPackets (0),
113  m_dataRate (0),
114  m_sendEvent (),
115  m_running (false),
116  m_packetsSent (0)
117 {
118 }
119 
121 {
122  m_socket = 0;
123 }
124 
125 /* static */
126 TypeId
128 {
129  static TypeId tid = TypeId ("SimpleSource")
131  .SetGroupName ("Stats")
132  .AddConstructor<SimpleSource> ()
133  ;
134  return tid;
135 }
136 
137 void
138 SimpleSource::Setup (Ptr<Socket> socket, Address address, uint32_t packetSize, uint32_t nPackets, DataRate dataRate)
139 {
140  m_socket = socket;
141  m_peer = address;
143  m_nPackets = nPackets;
144  m_dataRate = dataRate;
145 }
146 
147 void
149 {
150  m_running = true;
151  m_packetsSent = 0;
152  m_socket->Bind ();
154  SendPacket ();
155 }
156 
157 void
159 {
160  m_running = false;
161 
162  if (m_sendEvent.IsRunning ())
163  {
164  Simulator::Cancel (m_sendEvent);
165  }
166 
167  if (m_socket)
168  {
169  m_socket->Close ();
170  }
171 }
172 
173 void
175 {
176  Ptr<Packet> packet = Create<Packet> (m_packetSize);
177  m_socket->Send (packet);
178 
179  if (++m_packetsSent < m_nPackets)
180  {
181  ScheduleTx ();
182  }
183 }
184 
185 void
187 {
188  if (m_running)
189  {
190  Time tNext (Seconds (m_packetSize * 8 / static_cast<double> (m_dataRate.GetBitRate ())));
191  m_sendEvent = Simulator::Schedule (tNext, &SimpleSource::SendPacket, this);
192  }
193 }
194 
196 {
197 public:
199  virtual ~Ns3TcpCwndTestCase1 ();
200 
201 private:
202  virtual void DoRun (void);
204 
205  class CwndEvent {
206 public:
207  uint32_t m_oldCwnd;
208  uint32_t m_newCwnd;
209  };
210 
212 
213  void CwndChange (uint32_t oldCwnd, uint32_t newCwnd);
214 };
215 
217  : TestCase ("Check to see that the ns-3 TCP congestion window works as expected against liblinux2.6.26.so"),
218  m_writeResults (false)
219 {
220 }
221 
223 {
224 }
225 
226 void
227 Ns3TcpCwndTestCase1::CwndChange (uint32_t oldCwnd, uint32_t newCwnd)
228 {
229  CwndEvent event;
230 
231  event.m_oldCwnd = oldCwnd;
232  event.m_newCwnd = newCwnd;
233 
234  m_responses.Add (event);
235 
236  NS_LOG_DEBUG ("Cwnd change event " << m_responses.GetN () << " at " << Now ().As (Time::S) << " " << oldCwnd << " " << newCwnd);
237 }
238 
239 void
241 {
242  NS_LOG_DEBUG ("Starting test case 1");
243  //
244  // Create two nodes. One (node zero) will be the node with the TCP
245  // under test which is the ns-3 TCP implementation. The other node (node
246  // one) will be the node with the reference implementation we use to drive
247  // the tests.
248  //
250  nodes.Create (2);
251 
252  //
253  // For this test we'll use a point-to-point net device. It's not as simple
254  // as a simple-net-device, but it provides nice places to hook trace events
255  // so we can see what's moving between our nodes.
256  //
258  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
259  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
260 
262  devices = pointToPoint.Install (nodes);
263 
264  //
265  // Install two variants of the internet stack. The first, on node zero
266  // uses the TCP under test, which is the default ns-3 TCP implementation.
267  //
269  stack.Install (nodes.Get (0));
270 
271  //
272  // The other node, node one, is going to be set up to use a Linux TCP
273  // implementation that we consider a known good TCP.
274  //
275  std::string nscStack = "liblinux2.6.26.so";
276  stack.SetTcp ("ns3::NscTcpL4Protocol", "Library", StringValue ("liblinux2.6.26.so"));
277  stack.Install (nodes.Get (1));
278 
279  //
280  // Assign the address 10.1.1.1 to the TCP implementation under test (index
281  // zero) and 10.1.1.2 to the reference implementation (index one).
282  //
284  address.SetBase ("10.1.1.0", "255.255.255.252");
285  Ipv4InterfaceContainer interfaces = address.Assign (devices);
286 
287  //
288  // We need a place to send our TCP data on the node with the reference TCP
289  // implementation. We aren't really concerned about what happens there, so
290  // just create a sink.
291  //
292  uint16_t sinkPort = 8080;
293  Address sinkAddress (InetSocketAddress (interfaces.GetAddress (1), sinkPort));
294  PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
295  ApplicationContainer sinkApps = packetSinkHelper.Install (nodes.Get (1));
296  sinkApps.Start (Seconds (0.));
297  sinkApps.Stop (Seconds (1.1));
298 
299  //
300  // This test uses a custom application that provides a direct handle to
301  // the socket (the socket of applications such as the OnOffApplication
302  // is not created until Application Start time, and is not easily accessible).
303  //
304  // So first, we create a socket and do the trace connect on it; then we pass this
305  // socket into the constructor of our simple application which we then install
306  // in the node with the ns-3 TCP.
307  //
308  Ptr<Socket> ns3TcpSocket = Socket::CreateSocket (nodes.Get (0), TcpSocketFactory::GetTypeId ());
309  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeCallback (&Ns3TcpCwndTestCase1::CwndChange, this));
310 
311  Ptr<SimpleSource> app = CreateObject<SimpleSource> ();
312  // 1040 is size of packet objects used to write data to the socket (note:
313  // the actual TCP segment size will be 536 bytes). 10 is the number
314  // of packets, so we write 10 * 1040 bytes. This requires 20 segments
315  // of payload size 536, with the last one being a partially full segment
316  app->Setup (ns3TcpSocket, sinkAddress, 1040, 10, DataRate ("5Mbps"));
317  nodes.Get (0)->AddApplication (app);
318  app->SetStartTime (Seconds (1.));
319  app->SetStopTime (Seconds (1.1));
320 
321  //
322  // The idea here is that someone will look very closely at the all of the
323  // communications between the reference TCP and the TCP under test in this
324  // simulation and determine that all of the responses are correct. We expect
325  // that this means generating a pcap trace file from the point-to-point link
326  // and examining the packets closely using tcpdump, wireshark or some such
327  // program. So we provide the ability to generate a pcap trace of the
328  // test execution for your perusal.
329  //
330  // Once the validation test is determined to be running exactly as expected,
331  // the set of congestion window changes is collected and hard coded into the
332  // test results which will then be checked during the actual execution of the
333  // test.
334  //
335 
336  if (m_writeResults)
337  {
338  pointToPoint.EnablePcapAll ("tcp-cwnd");
339  }
340 
341  Simulator::Stop (Seconds (2));
342  Simulator::Run ();
343  Simulator::Destroy ();
344 
345  //
346  // As new acks are received by the TCP under test, the congestion window
347  // should be opened up by one segment (MSS bytes) each time. This should
348  // trigger a congestion window change event which we hooked and saved above.
349  // We should now be able to look through the saved response vectors and follow
350  // the congestion window as it opens up when the ns-3 TCP under test
351  // transmits its bits
352  //
353  // From inspecting the results, we know that we should see N_EVENTS congestion
354  // window change events (each time by MSS bytes) until reaching the largest
355  // value when the client closes.
356  //
357  const uint32_t MSS = 536;
358  const uint32_t N_EVENTS = 20;
359 
360  CwndEvent event;
361 
362  NS_TEST_ASSERT_MSG_EQ (m_responses.GetN (), N_EVENTS, "Unexpectedly low number of cwnd change events");
363 
364 
365  // Ignore the first event logged (i=0) when m_cWnd goes from 0 to MSS bytes
366  for (uint32_t i = 1, from = MSS, to = MSS * 2; i < N_EVENTS; ++i, from += MSS, to += MSS)
367  {
368  event = m_responses.Get (i);
369  NS_TEST_ASSERT_MSG_EQ (event.m_oldCwnd, from, "Wrong old cwnd value in cwnd change event " << i);
370  NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, to, "Wrong new cwnd value in cwnd change event " << i);
371  }
372 }
373 
374 
375 // ===========================================================================
376 // Test case for cwnd changes due to out-of-order packets. A bottleneck
377 // link is created, and a limited droptail queue is used in order to
378 // force dropped packets, resulting in out-of-order packet delivery.
379 // This out-of-order delivery will result in a different congestion
380 // window behavior than testcase 1. Specifically, duplicate ACKs
381 // are encountered.
382 //
383 // Network topology
384 //
385 // 1Mb/s, 10ms 100kb/s, 10ms 1Mb/s, 10ms
386 // n0--------------n1-----------------n2---------------n3
387 //
388 // ===========================================================================
390 {
391 public:
393  virtual ~Ns3TcpCwndTestCase2 ();
394 
395 private:
396  virtual void DoRun (void);
397  void VerifyCwndRun (uint32_t beginIdx, uint32_t endIdx, uint32_t initialCwnd, uint32_t mss);
399 
400  class CwndEvent {
401 public:
402  uint32_t m_oldCwnd;
403  uint32_t m_newCwnd;
404  };
405 
407 
408  void CwndChange (uint32_t oldCwnd, uint32_t newCwnd);
409 };
410 
412  : TestCase ("Check to see that the ns-3 TCP congestion window works as expected for out-of-order packet delivery"),
413  m_writeResults (false)
414 {
415 }
416 
418 {
419 }
420 
421 void
422 Ns3TcpCwndTestCase2::CwndChange (uint32_t oldCwnd, uint32_t newCwnd)
423 {
424  CwndEvent event;
425 
426  event.m_oldCwnd = oldCwnd;
427  event.m_newCwnd = newCwnd;
428 
429  m_responses.Add (event);
430  NS_LOG_DEBUG ("Cwnd change event " << m_responses.GetN () << " at " << Now ().As (Time::S) << " " << oldCwnd << " " << newCwnd);
431 }
432 
433 void
435 {
436  NS_LOG_DEBUG ("Starting test case 2");
437  // Set up some default values for the simulation.
438  Config::SetDefault ("ns3::Queue::MaxPackets", UintegerValue (4));
439 
440  NodeContainer n0n1;
441  n0n1.Create (2);
442 
444  n1n2.Add (n0n1.Get (1));
445  n1n2.Create (1);
446 
448  n2n3.Add (n1n2.Get (1));
449  n2n3.Create (1);
450 
451  PointToPointHelper p2p1;
452  p2p1.SetDeviceAttribute ("DataRate", DataRateValue (DataRate (1000000)));
453  p2p1.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (10)));
454  PointToPointHelper p2p2;
455  p2p2.SetDeviceAttribute ("DataRate", DataRateValue (DataRate (100000)));
456  p2p2.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (10)));
457 
458  // And then install devices and channels connecting our topology.
459  NetDeviceContainer dev0 = p2p1.Install (n0n1);
460  NetDeviceContainer dev1 = p2p2.Install (n1n2);
461  NetDeviceContainer dev2 = p2p1.Install (n2n3);
462 
463  // Now add ip/tcp stack to all nodes.
464  InternetStackHelper internet;
465  internet.InstallAll ();
466 
467  // Later, we add IP addresses.
468  Ipv4AddressHelper ipv4;
469  ipv4.SetBase ("10.1.3.0", "255.255.255.0");
470  ipv4.Assign (dev0);
471  ipv4.SetBase ("10.1.2.0", "255.255.255.0");
472  ipv4.Assign (dev1);
473  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
474  Ipv4InterfaceContainer ipInterfs = ipv4.Assign (dev2);
475 
476  // and setup ip routing tables to get total ip-level connectivity.
477  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
478 
479  // Disable traffic control layer so that drops occur
481  tch.Uninstall (dev0);
482  tch.Uninstall (dev1);
483  tch.Uninstall (dev2);
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  const uint32_t MSS = 536;
535  const uint32_t N_EVENTS = 40;
536 
537  CwndEvent event;
538 
539  NS_LOG_DEBUG ("Number of response events: " << m_responses.GetN ());
540  NS_TEST_ASSERT_MSG_EQ (m_responses.GetN (), N_EVENTS, "Unexpected number of cwnd change events");
541 
542  // Ignore the first event logged (i=0) when m_cWnd goes from 0 to MSS bytes
543  VerifyCwndRun (1, 10, 2 * MSS, MSS);
544 
545  // At the point of loss, sndNxt = 15545; sndUna = 9113. FlightSize is 4824,
546  // so there are 9 segments outstanding. Cut ssthresh to 9/2 (2412) and
547  // cwnd to (9/2 + 3) = 4020
548  event = m_responses.Get (10);
549  NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, (MSS * 15)/2, "Wrong new cwnd value in cwnd change event " << 10);
550 
551  // Verify that cwnd increments by one for a few segments
552  // from 8.5 at index 11 to 12.5 at index 15
553  VerifyCwndRun (11, 15, (MSS * 17)/2, MSS);
554 
555  // partial ack at event 16, cwnd reset from 6700 (12.5*MSS) to 5092 (9.5*MSS)
556  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (16).m_newCwnd, (MSS * 19)/2, "Wrong new cwnd value in cwnd change event " << 16);
557 
558  // partial ack again of 3 segments after one more acks, cwnd reset to 7.5
559  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (18).m_newCwnd, (MSS * 15)/2, "Wrong new cwnd value in cwnd change event " << 18);
560 
561  //DUP ACKS in remaining fast recovery
562  VerifyCwndRun (18, 20, (MSS * 15)/2, MSS);
563 
564  // Process another partial ack
565  VerifyCwndRun (21, 24, (MSS * 13)/2, MSS);
566 
567  //Leaving fast recovery at event 25; set cwnd to 3 segments
568  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (25).m_newCwnd, (MSS * 3), "Wrong new cwnd value in cwnd change event " << 25);
569 
570  // Until ssthresh, each event will increase cwnd by MSS
571  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (26).m_newCwnd, (4 * MSS), "Wrong new cwnd value in cwnd change event " << 26);
572  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (27).m_newCwnd, (5 * MSS), "Wrong new cwnd value in cwnd change event " << 27);
573  //In CongAvoid each event will increase cwnd by (MSS * MSS / cwnd)
574  uint32_t cwnd = 5 * MSS;
575  for (uint32_t i = 28; i < N_EVENTS; ++i)
576  {
577  double adder = static_cast<double> (MSS * MSS) / cwnd;
578  adder = std::max (1.0, adder);
579  cwnd += static_cast<uint32_t> (adder);
580  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (i).m_newCwnd, cwnd, "Wrong new cwnd value in cwnd change event " << i);
581  }
582  NS_LOG_DEBUG ("Reading out the cwnd event log");
583  for (uint32_t i = 0; i < N_EVENTS; ++i)
584  {
585  NS_LOG_DEBUG ("i: " << i << " newCwnd: " << m_responses.Get(i).m_newCwnd << " newCwnd segments " << static_cast<double> (m_responses.Get(i).m_newCwnd)/MSS);
586  }
587 }
588 
589 void
590 Ns3TcpCwndTestCase2::VerifyCwndRun (uint32_t beginIdx, uint32_t endIdx, uint32_t initialCwnd, uint32_t mss)
591 {
592 
593  CwndEvent event;
594 
595  for(uint32_t i = beginIdx, to = initialCwnd; i < endIdx; ++i, to += mss)
596  {
597  event = m_responses.Get (i);
598  NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, to, "Wrong new cwnd value in cwnd change event " << i);
599  }
600 }
601 
603 {
604 public:
606 };
607 
609  : TestSuite ("ns3-tcp-cwnd", SYSTEM)
610 {
611  AddTestCase (new Ns3TcpCwndTestCase1, TestCase::QUICK);
612  AddTestCase (new Ns3TcpCwndTestCase2, TestCase::QUICK);
613 }
614 
Ptr< PacketSink > sink
Definition: wifi-tcp.cc:47
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
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 Uninstall(NetDeviceContainer c)
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 ...
#define max(a, b)
Definition: 80211b.c:45
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:298
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:1489
Build a set of QueueDisc objects.
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
NodeContainer n2n3
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.
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:388
An identifier for simulation events.
Definition: event-id.h:53
AttributeValue implementation for DataRate.
Definition: data-rate.h:242
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)
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:340
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:904
void SetStartTime(Time start)
Specify application start time.
Definition: application.cc:69
NodeContainer n1n2
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