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 #include "ns3/point-to-point-net-device.h"
37 #include "ns3/pointer.h"
38 #include "ns3/queue.h"
39 
40 using namespace ns3;
41 
42 NS_LOG_COMPONENT_DEFINE ("Ns3CwndTest");
43 
44 // ===========================================================================
45 // This is a simple test to demonstrate how a known good model (a reference
46 // implementation) may be used to test another model without resorting to
47 // storing stimulus or response vectors.
48 //
49 // Node zero contains the model under test, in this case the ns-3 TCP
50 // implementation. Node one contains the reference implementation that we
51 // assume will generate good test vectors for us. In this case, a Linux
52 // TCP implementation is used to stimulate the ns-3 TCP model with what we
53 // assume are perfectly good packets. We watch the ns-3 implementation to
54 // see what it does in the presence of these assumed good stimuli.
55 //
56 // The test is arranged as a typical ns-3 script, but we use the trace system
57 // to peek into the running system and monitor the ns-3 TCP.
58 //
59 // The topology is just two nodes communicating over a point-to-point network.
60 // The point-to-point network is chosen because it is simple and allows us to
61 // easily generate pcap traces we can use to separately verify that the ns-3
62 // implementation is responding correctly. Once the operation is verified, we
63 // enter a list of responses that capture the response succinctly.
64 //
65 // node 0 node 1
66 // +----------------+ +----------------+
67 // | ns-3 TCP | | Linux TCP |
68 // +----------------+ +----------------+
69 // | 10.1.1.1 | | 10.1.1.2 |
70 // +----------------+ +----------------+
71 // | point-to-point | | point-to-point |
72 // +----------------+ +----------------+
73 // | |
74 // +---------------------+
75 // 5 Mbps, 2 ms
76 //
77 // ===========================================================================
78 //
79 class SimpleSource : public Application
80 {
81 public:
82 
83  SimpleSource ();
84  virtual ~SimpleSource();
85 
90  static TypeId GetTypeId (void);
91 
92  void Setup (Ptr<Socket> socket, Address address, uint32_t packetSize, uint32_t nPackets, DataRate dataRate);
93 
94 private:
95  virtual void StartApplication (void);
96  virtual void StopApplication (void);
97 
98  void ScheduleTx (void);
99  void SendPacket (void);
100 
103  uint32_t m_packetSize;
104  uint32_t m_nPackets;
107  bool m_running;
108  uint32_t m_packetsSent;
109 };
110 
112  : m_socket (0),
113  m_peer (),
114  m_packetSize (0),
115  m_nPackets (0),
116  m_dataRate (0),
117  m_sendEvent (),
118  m_running (false),
119  m_packetsSent (0)
120 {
121 }
122 
124 {
125  m_socket = 0;
126 }
127 
128 /* static */
129 TypeId
131 {
132  static TypeId tid = TypeId ("SimpleSource")
134  .SetGroupName ("Stats")
135  .AddConstructor<SimpleSource> ()
136  ;
137  return tid;
138 }
139 
140 void
141 SimpleSource::Setup (Ptr<Socket> socket, Address address, uint32_t packetSize, uint32_t nPackets, DataRate dataRate)
142 {
143  m_socket = socket;
144  m_peer = address;
146  m_nPackets = nPackets;
147  m_dataRate = dataRate;
148 }
149 
150 void
152 {
153  m_running = true;
154  m_packetsSent = 0;
155  m_socket->Bind ();
157  SendPacket ();
158 }
159 
160 void
162 {
163  m_running = false;
164 
165  if (m_sendEvent.IsRunning ())
166  {
167  Simulator::Cancel (m_sendEvent);
168  }
169 
170  if (m_socket)
171  {
172  m_socket->Close ();
173  }
174 }
175 
176 void
178 {
179  Ptr<Packet> packet = Create<Packet> (m_packetSize);
180  m_socket->Send (packet);
181 
182  if (++m_packetsSent < m_nPackets)
183  {
184  ScheduleTx ();
185  }
186 }
187 
188 void
190 {
191  if (m_running)
192  {
193  Time tNext (Seconds (m_packetSize * 8 / static_cast<double> (m_dataRate.GetBitRate ())));
194  m_sendEvent = Simulator::Schedule (tNext, &SimpleSource::SendPacket, this);
195  }
196 }
197 
199 {
200 public:
202  virtual ~Ns3TcpCwndTestCase1 ();
203 
204 private:
205  virtual void DoRun (void);
207 
208  class CwndEvent {
209 public:
210  uint32_t m_oldCwnd;
211  uint32_t m_newCwnd;
212  };
213 
215 
216  void CwndChange (uint32_t oldCwnd, uint32_t newCwnd);
217 };
218 
220  : TestCase ("Check to see that the ns-3 TCP congestion window works as expected against liblinux2.6.26.so"),
221  m_writeResults (false)
222 {
223 }
224 
226 {
227 }
228 
229 void
230 Ns3TcpCwndTestCase1::CwndChange (uint32_t oldCwnd, uint32_t newCwnd)
231 {
232  CwndEvent event;
233 
234  event.m_oldCwnd = oldCwnd;
235  event.m_newCwnd = newCwnd;
236 
237  m_responses.Add (event);
238 
239  NS_LOG_DEBUG ("Cwnd change event " << m_responses.GetN () << " at " << Now ().As (Time::S) << " " << oldCwnd << " " << newCwnd);
240 }
241 
242 void
244 {
245  NS_LOG_DEBUG ("Starting test case 1");
246  // This test was written with initial window of 1 segment
247  Config::SetDefault ("ns3::TcpSocket::InitialCwnd", UintegerValue (1));
248 
249  //
250  // Create two nodes. One (node zero) will be the node with the TCP
251  // under test which is the ns-3 TCP implementation. The other node (node
252  // one) will be the node with the reference implementation we use to drive
253  // the tests.
254  //
256  nodes.Create (2);
257 
258  //
259  // For this test we'll use a point-to-point net device. It's not as simple
260  // as a simple-net-device, but it provides nice places to hook trace events
261  // so we can see what's moving between our nodes.
262  //
264  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
265  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
266 
268  devices = pointToPoint.Install (nodes);
269 
270  //
271  // Install two variants of the internet stack. The first, on node zero
272  // uses the TCP under test, which is the default ns-3 TCP implementation.
273  //
275  stack.Install (nodes.Get (0));
276 
277  //
278  // The other node, node one, is going to be set up to use a Linux TCP
279  // implementation that we consider a known good TCP.
280  //
281  std::string nscStack = "liblinux2.6.26.so";
282  stack.SetTcp ("ns3::NscTcpL4Protocol", "Library", StringValue ("liblinux2.6.26.so"));
283  stack.Install (nodes.Get (1));
284 
285  //
286  // Assign the address 10.1.1.1 to the TCP implementation under test (index
287  // zero) and 10.1.1.2 to the reference implementation (index one).
288  //
290  address.SetBase ("10.1.1.0", "255.255.255.252");
292 
293  //
294  // We need a place to send our TCP data on the node with the reference TCP
295  // implementation. We aren't really concerned about what happens there, so
296  // just create a sink.
297  //
298  uint16_t sinkPort = 8080;
299  Address sinkAddress (InetSocketAddress (interfaces.GetAddress (1), sinkPort));
300  PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
301  ApplicationContainer sinkApps = packetSinkHelper.Install (nodes.Get (1));
302  sinkApps.Start (Seconds (0.));
303  sinkApps.Stop (Seconds (1.1));
304 
305  //
306  // This test uses a custom application that provides a direct handle to
307  // the socket (the socket of applications such as the OnOffApplication
308  // is not created until Application Start time, and is not easily accessible).
309  //
310  // So first, we create a socket and do the trace connect on it; then we pass this
311  // socket into the constructor of our simple application which we then install
312  // in the node with the ns-3 TCP.
313  //
314  Ptr<Socket> ns3TcpSocket = Socket::CreateSocket (nodes.Get (0), TcpSocketFactory::GetTypeId ());
315  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindowInflated", MakeCallback (&Ns3TcpCwndTestCase1::CwndChange, this));
316 
317  Ptr<SimpleSource> app = CreateObject<SimpleSource> ();
318  // 1040 is size of packet objects used to write data to the socket (note:
319  // the actual TCP segment size will be 536 bytes). 10 is the number
320  // of packets, so we write 10 * 1040 bytes. This requires 20 segments
321  // of payload size 536, with the last one being a partially full segment
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 expected,
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 (each time by MSS bytes) until reaching the largest
361  // value when the client closes.
362  //
363  const uint32_t MSS = 536;
364  const uint32_t N_EVENTS = 20;
365 
366  CwndEvent event;
367 
368  NS_TEST_ASSERT_MSG_EQ (m_responses.GetN (), N_EVENTS, "Unexpectedly low number of cwnd change events");
369 
370  // Ignore the first event logged (i=0) when m_cWnd goes from 0 to MSS bytes
371  for (uint32_t i = 1, from = MSS, to = MSS * 2; i < N_EVENTS; ++i, from += MSS, to += MSS)
372  {
373  event = m_responses.Get (i);
374  NS_TEST_ASSERT_MSG_EQ (event.m_oldCwnd, from, "Wrong old cwnd value in cwnd change event " << i);
375  NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, to, "Wrong new cwnd value in cwnd change event " << i);
376  }
377 }
378 
379 
380 // ===========================================================================
381 // Test case for cwnd changes due to out-of-order packets. A bottleneck
382 // link is created, and a limited droptail queue is used in order to
383 // force dropped packets, resulting in out-of-order packet delivery.
384 // This out-of-order delivery will result in a different congestion
385 // window behavior than testcase 1. Specifically, duplicate ACKs
386 // are encountered.
387 //
388 // Network topology
389 //
390 // 1Mb/s, 10ms 100kb/s, 10ms 1Mb/s, 10ms
391 // n0--------------n1-----------------n2---------------n3
392 //
393 // ===========================================================================
395 {
396 public:
398  virtual ~Ns3TcpCwndTestCase2 ();
399 
400 private:
401  virtual void DoRun (void);
402  void VerifyCwndRun (uint32_t beginIdx, uint32_t endIdx, uint32_t initialCwnd, uint32_t mss);
404 
405  class CwndEvent {
406 public:
407  uint32_t m_oldCwnd;
408  uint32_t m_newCwnd;
409  };
410 
412 
413  void CwndChange (uint32_t oldCwnd, uint32_t newCwnd);
414  void CwndChangeNotInflated (uint32_t oldCwnd, uint32_t newCwnd);
415 };
416 
418  : TestCase ("Check to see that the ns-3 TCP congestion window works as expected for out-of-order packet delivery"),
419  m_writeResults (false)
420 {
421 }
422 
424 {
425 }
426 
427 void
428 Ns3TcpCwndTestCase2::CwndChange (uint32_t oldCwnd, uint32_t newCwnd)
429 {
430  CwndEvent event;
431 
432  event.m_oldCwnd = oldCwnd;
433  event.m_newCwnd = newCwnd;
434 
435  m_responses.Add (event);
436  NS_LOG_DEBUG ("Cwnd change event " << m_responses.GetN () << " at " << Now ().As (Time::S) << " " << oldCwnd << " " << newCwnd);
437 }
438 
439 void
440 Ns3TcpCwndTestCase2::CwndChangeNotInflated (uint32_t oldCwnd, uint32_t newCwnd)
441 {
442  NS_LOG_DEBUG ("Cwnd NOT INFLATED change event " << m_responses.GetN () << " at " << Now ().As (Time::S) << " " << oldCwnd << " " << newCwnd);
443 }
444 
445 void
447 {
448  NS_LOG_DEBUG ("Starting test case 2");
449  // Set up some default values for the simulation.
450  Config::SetDefault ("ns3::QueueBase::MaxSize", QueueSizeValue (QueueSize (QueueSizeUnit::PACKETS, 4)));
451  Packet::EnablePrinting ();
452  // This test was written with initial window of 1 segment
453  Config::SetDefault ("ns3::TcpSocket::InitialCwnd", UintegerValue (1));
454 
455  NodeContainer n0n1;
456  n0n1.Create (2);
457 
459  n1n2.Add (n0n1.Get (1));
460  n1n2.Create (1);
461 
463  n2n3.Add (n1n2.Get (1));
464  n2n3.Create (1);
465 
466  PointToPointHelper p2p1;
467  p2p1.SetDeviceAttribute ("DataRate", DataRateValue (DataRate (1000000)));
468  p2p1.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (10)));
469  PointToPointHelper p2p2;
470  p2p2.SetDeviceAttribute ("DataRate", DataRateValue (DataRate (100000)));
471  p2p2.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (10)));
472 
473  // And then install devices and channels connecting our topology.
474  NetDeviceContainer dev0 = p2p1.Install (n0n1);
475  NetDeviceContainer dev1 = p2p2.Install (n1n2);
476  NetDeviceContainer dev2 = p2p1.Install (n2n3);
477 
478  // Now add ip/tcp stack to all nodes.
479  InternetStackHelper internet;
480  internet.InstallAll ();
481 
482  // Later, we add IP addresses.
483  Ipv4AddressHelper ipv4;
484  ipv4.SetBase ("10.1.3.0", "255.255.255.0");
485  ipv4.Assign (dev0);
486  ipv4.SetBase ("10.1.2.0", "255.255.255.0");
487  ipv4.Assign (dev1);
488  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
489  Ipv4InterfaceContainer ipInterfs = ipv4.Assign (dev2);
490 
491  // and setup ip routing tables to get total ip-level connectivity.
492  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
493 
494  // Disable traffic control layer so that drops occur
496  tch.Uninstall (dev0);
497  tch.Uninstall (dev1);
498  tch.Uninstall (dev2);
499 
500  // Set up the apps
501  uint16_t servPort = 50000;
502 
503  // Create a packet sink to receive these packets on n3
504  PacketSinkHelper sink ("ns3::TcpSocketFactory",
505  InetSocketAddress (Ipv4Address::GetAny (), servPort));
506 
507  ApplicationContainer apps = sink.Install (n2n3.Get (1));
508  apps.Start (Seconds (0.0));
509  apps.Stop (Seconds (5.4));
510 
511  // Create the socket for n0
512  Address sinkAddress (InetSocketAddress (ipInterfs.GetAddress (1), servPort));
513  Ptr<Socket> ns3TcpSocket = Socket::CreateSocket (n0n1.Get (0), TcpSocketFactory::GetTypeId ());
514  // Disable SACK because this test is testing NewReno behavior
515  ns3TcpSocket->SetAttribute ("Sack", BooleanValue (false));
516  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindowInflated", MakeCallback (&Ns3TcpCwndTestCase2::CwndChange, this));
517  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeCallback (&Ns3TcpCwndTestCase2::CwndChangeNotInflated, this));
518 
519  // Create and start the app for n0
520  Ptr<SimpleSource> app = CreateObject<SimpleSource> ();
521  app->Setup (ns3TcpSocket, sinkAddress, 1040, 1000, DataRate ("1Mbps"));
522  n0n1.Get (0)->AddApplication (app);
523  app->SetStartTime (Seconds (1.0));
524  app->SetStopTime (Seconds (4.1));
525 
526  if (m_writeResults)
527  {
528  // Write a pcap for tcp cwnd testcase with out-of-order delivery
530  pointToPoint.EnablePcapAll ("tcp-cwnd-ood");
531  }
532 
533  // Finally, set up the simulator to run.
534  Simulator::Stop (Seconds (4.1));
535  Simulator::Run ();
536  Simulator::Destroy ();
537 
538  //
539  // As new acks are received by the TCP under test, the congestion window
540  // should be opened up by one segment (MSS bytes) each time. This should
541  // trigger a congestion window change event which we hooked and saved above.
542  // We should now be able to look through the saved response vectors and follow
543  // the congestion window as it opens up when the ns-3 TCP under test
544  // transmits its bits
545  //
546  // From inspecting the results, we know that we should see N_EVENTS congestion
547  // window change events. On the tenth change event, the window should
548  // be cut from 5360 to 4288 due to 3 dup acks (NewReno behavior is to
549  // cut in half, and then add 3 segments (5360/2 + 3*536 = 4288)
550  //
551 
552  const uint32_t MSS = 536;
553  const uint32_t N_EVENTS = 38;
554 
555  CwndEvent event;
556 
557  NS_LOG_DEBUG ("Number of response events: " << m_responses.GetN ());
558  //NS_TEST_ASSERT_MSG_EQ (m_responses.GetN (), N_EVENTS, "Unexpected number of cwnd change events");
559 
560  // Ignore the first event logged (i=0) when m_cWnd goes from 0 to MSS bytes
561  VerifyCwndRun (1, 10, 2 * MSS, MSS);
562 
563  // At the point of loss, sndNxt = 15545; sndUna = 9113. FlightSize is 4824,
564  // so there are 9 segments outstanding. Cut ssthresh to 9/2 (2412) and
565  // cwnd to (9/2 + 3) = 4020
566  event = m_responses.Get (10);
567  NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, (MSS * 15)/2, "Wrong new cwnd value in cwnd change event " << 10);
568 
569  // Verify that cwnd increments by one for a few segments
570  // from 8.5 at index 11 to 12.5 at index 15
571  VerifyCwndRun (11, 15, (MSS * 17)/2, MSS);
572 
573  // partial ack at event 16, cwnd reset from 6700 (12.5*MSS) to 5092 (9.5*MSS)
574  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (16).m_newCwnd, (MSS * 19)/2, "Wrong new cwnd value in cwnd change event " << 16);
575 
576  // partial ack again of 3 segments after one more acks, cwnd reset to 7.5
577  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (18).m_newCwnd, (MSS * 15)/2, "Wrong new cwnd value in cwnd change event " << 18);
578 
579  //DUP ACKS in remaining fast recovery
580  VerifyCwndRun (18, 20, (MSS * 15)/2, MSS);
581 
582  // Process another partial ack
583  VerifyCwndRun (21, 24, (MSS * 13)/2, MSS);
584 
585  // Leaving fast recovery at event 25; set cwnd to 4 segments as per RFC 2582
586  // Sec. 3 para. 5 option 2 (sshthresh is 2412, 4.5 times MSS)
587  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (25).m_newCwnd, 2412, "Wrong new cwnd value in cwnd change event " << 25);
588 
589  //In CongAvoid each event will increase cwnd by (MSS * MSS / cwnd)
590  uint32_t cwnd = 2412;
591  for (uint32_t i = 26; i < N_EVENTS; ++i)
592  {
593  double adder = static_cast<double> (MSS * MSS) / cwnd;
594  adder = std::max (1.0, adder);
595  cwnd += static_cast<uint32_t> (adder);
596  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (i).m_newCwnd, cwnd, "Wrong new cwnd value in cwnd change event " << i);
597  }
598  NS_LOG_DEBUG ("Reading out the cwnd event log");
599  for (uint32_t i = 0; i < N_EVENTS; ++i)
600  {
601  NS_LOG_DEBUG ("i: " << i << " newCwnd: " << m_responses.Get(i).m_newCwnd << " newCwnd segments " << static_cast<double> (m_responses.Get(i).m_newCwnd)/MSS);
602  }
603 }
604 
605 void
606 Ns3TcpCwndTestCase2::VerifyCwndRun (uint32_t beginIdx, uint32_t endIdx, uint32_t initialCwnd, uint32_t mss)
607 {
608 
609  CwndEvent event;
610 
611  for(uint32_t i = beginIdx, to = initialCwnd; i < endIdx; ++i, to += mss)
612  {
613  event = m_responses.Get (i);
614  NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, to, "Wrong new cwnd value in cwnd change event " << i);
615  }
616 }
617 
619 {
620 public:
622 };
623 
625  : TestSuite ("ns3-tcp-cwnd", SYSTEM)
626 {
627  AddTestCase (new Ns3TcpCwndTestCase1, TestCase::QUICK);
628  AddTestCase (new Ns3TcpCwndTestCase2, TestCase::QUICK);
629 }
630 
void InstallAll(void) const
Aggregate IPv4, IPv6, UDP, and TCP stacks to all nodes in the simulation.
Ptr< PacketSink > sink
Definition: wifi-tcp.cc:56
holds a vector of ns3::Application pointers.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:159
Ptr< Socket > m_socket
void SetStopTime(Time stop)
Specify application stop time.
Definition: application.cc:75
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
an Inet address class
AttributeValue implementation for Boolean.
Definition: boolean.h:36
Class for representing queue sizes.
Definition: queue-size.h:94
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Hold variables of type string.
Definition: string.h:41
NetDeviceContainer Install(NodeContainer c)
static const uint32_t packetSize
A suite of tests to run.
Definition: test.h:1343
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1286
ApplicationContainer Install(NodeContainer c) const
Install an ns3::PacketSinkApplication on each node of the input container configured with all the att...
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes...
Build a set of PointToPointNetDevice objects.
void CwndChange(uint32_t oldCwnd, uint32_t newCwnd)
encapsulates test code
Definition: test.h:1153
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:389
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.
uint64_t GetBitRate() const
Get the underlying bitrate.
Definition: data-rate.cc:241
stack
Definition: first.py:41
a polymophic address class
Definition: address.h:90
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1406
virtual void StopApplication(void)
Application specific shutdown code.
Class for representing data rates.
Definition: data-rate.h:88
TestVectors< CwndEvent > m_responses
nodes
Definition: first.py:32
#define max(a, b)
Definition: 80211b.c:43
The base class for all ns3 applications.
Definition: application.h:60
AttributeValue implementation for Time.
Definition: nstime.h:1342
virtual void StartApplication(void)
Application specific startup code.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
Hold an unsigned integer type.
Definition: uinteger.h:44
Use number of packets for queue size.
Definition: queue-size.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:166
pointToPoint
Definition: first.py:35
holds a vector of ns3::NetDevice pointers
virtual void DoRun(void)
Implementation to actually run this TestCase.
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:293
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.
address
Definition: first.py:44
TestVectors< CwndEvent > m_responses
NodeContainer n2n3
void SendPacket(Ptr< NetDevice > sourceDevice, Address &destination)
This example (inspired from tv-trans-example) enables to generate the transmitted spectra of Wi-Fi st...
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:229
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1278
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
interfaces
Definition: first.py:48
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:71
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
void Setup(Ptr< Socket > socket, Address address, uint32_t packetSize, uint32_t nPackets, DataRate dataRate)
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:287
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
void CwndChange(uint32_t oldCwnd, uint32_t newCwnd)
devices
Definition: first.py:39
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.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
void SetStartTime(Time start)
Specify application start time.
Definition: application.cc:69
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
NodeContainer n1n2
void CwndChangeNotInflated(uint32_t oldCwnd, uint32_t newCwnd)
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.