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  //
247  // Create two nodes. One (node zero) will be the node with the TCP
248  // under test which is the ns-3 TCP implementation. The other node (node
249  // one) will be the node with the reference implementation we use to drive
250  // the tests.
251  //
253  nodes.Create (2);
254 
255  //
256  // For this test we'll use a point-to-point net device. It's not as simple
257  // as a simple-net-device, but it provides nice places to hook trace events
258  // so we can see what's moving between our nodes.
259  //
261  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
262  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
263 
265  devices = pointToPoint.Install (nodes);
266 
267  //
268  // Install two variants of the internet stack. The first, on node zero
269  // uses the TCP under test, which is the default ns-3 TCP implementation.
270  //
272  stack.Install (nodes.Get (0));
273 
274  //
275  // The other node, node one, is going to be set up to use a Linux TCP
276  // implementation that we consider a known good TCP.
277  //
278  std::string nscStack = "liblinux2.6.26.so";
279  stack.SetTcp ("ns3::NscTcpL4Protocol", "Library", StringValue ("liblinux2.6.26.so"));
280  stack.Install (nodes.Get (1));
281 
282  //
283  // Assign the address 10.1.1.1 to the TCP implementation under test (index
284  // zero) and 10.1.1.2 to the reference implementation (index one).
285  //
287  address.SetBase ("10.1.1.0", "255.255.255.252");
289 
290  //
291  // We need a place to send our TCP data on the node with the reference TCP
292  // implementation. We aren't really concerned about what happens there, so
293  // just create a sink.
294  //
295  uint16_t sinkPort = 8080;
296  Address sinkAddress (InetSocketAddress (interfaces.GetAddress (1), sinkPort));
297  PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
298  ApplicationContainer sinkApps = packetSinkHelper.Install (nodes.Get (1));
299  sinkApps.Start (Seconds (0.));
300  sinkApps.Stop (Seconds (1.1));
301 
302  //
303  // This test uses a custom application that provides a direct handle to
304  // the socket (the socket of applications such as the OnOffApplication
305  // is not created until Application Start time, and is not easily accessible).
306  //
307  // So first, we create a socket and do the trace connect on it; then we pass this
308  // socket into the constructor of our simple application which we then install
309  // in the node with the ns-3 TCP.
310  //
311  Ptr<Socket> ns3TcpSocket = Socket::CreateSocket (nodes.Get (0), TcpSocketFactory::GetTypeId ());
312  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindowInflated", MakeCallback (&Ns3TcpCwndTestCase1::CwndChange, this));
313 
314  Ptr<SimpleSource> app = CreateObject<SimpleSource> ();
315  // 1040 is size of packet objects used to write data to the socket (note:
316  // the actual TCP segment size will be 536 bytes). 10 is the number
317  // of packets, so we write 10 * 1040 bytes. This requires 20 segments
318  // of payload size 536, with the last one being a partially full segment
319  app->Setup (ns3TcpSocket, sinkAddress, 1040, 10, DataRate ("5Mbps"));
320  nodes.Get (0)->AddApplication (app);
321  app->SetStartTime (Seconds (1.));
322  app->SetStopTime (Seconds (1.1));
323 
324  //
325  // The idea here is that someone will look very closely at the all of the
326  // communications between the reference TCP and the TCP under test in this
327  // simulation and determine that all of the responses are correct. We expect
328  // that this means generating a pcap trace file from the point-to-point link
329  // and examining the packets closely using tcpdump, wireshark or some such
330  // program. So we provide the ability to generate a pcap trace of the
331  // test execution for your perusal.
332  //
333  // Once the validation test is determined to be running exactly as expected,
334  // the set of congestion window changes is collected and hard coded into the
335  // test results which will then be checked during the actual execution of the
336  // test.
337  //
338 
339  if (m_writeResults)
340  {
341  pointToPoint.EnablePcapAll ("tcp-cwnd");
342  }
343 
344  Simulator::Stop (Seconds (2));
345  Simulator::Run ();
346  Simulator::Destroy ();
347 
348  //
349  // As new acks are received by the TCP under test, the congestion window
350  // should be opened up by one segment (MSS bytes) each time. This should
351  // trigger a congestion window change event which we hooked and saved above.
352  // We should now be able to look through the saved response vectors and follow
353  // the congestion window as it opens up when the ns-3 TCP under test
354  // transmits its bits
355  //
356  // From inspecting the results, we know that we should see N_EVENTS congestion
357  // window change events (each time by MSS bytes) until reaching the largest
358  // value when the client closes.
359  //
360  const uint32_t MSS = 536;
361  const uint32_t N_EVENTS = 20;
362 
363  CwndEvent event;
364 
365  NS_TEST_ASSERT_MSG_EQ (m_responses.GetN (), N_EVENTS, "Unexpectedly low number of cwnd change events");
366 
367  // Ignore the first event logged (i=0) when m_cWnd goes from 0 to MSS bytes
368  for (uint32_t i = 1, from = MSS, to = MSS * 2; i < N_EVENTS; ++i, from += MSS, to += MSS)
369  {
370  event = m_responses.Get (i);
371  NS_TEST_ASSERT_MSG_EQ (event.m_oldCwnd, from, "Wrong old cwnd value in cwnd change event " << i);
372  NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, to, "Wrong new cwnd value in cwnd change event " << i);
373  }
374 }
375 
376 
377 // ===========================================================================
378 // Test case for cwnd changes due to out-of-order packets. A bottleneck
379 // link is created, and a limited droptail queue is used in order to
380 // force dropped packets, resulting in out-of-order packet delivery.
381 // This out-of-order delivery will result in a different congestion
382 // window behavior than testcase 1. Specifically, duplicate ACKs
383 // are encountered.
384 //
385 // Network topology
386 //
387 // 1Mb/s, 10ms 100kb/s, 10ms 1Mb/s, 10ms
388 // n0--------------n1-----------------n2---------------n3
389 //
390 // ===========================================================================
392 {
393 public:
395  virtual ~Ns3TcpCwndTestCase2 ();
396 
397 private:
398  virtual void DoRun (void);
399  void VerifyCwndRun (uint32_t beginIdx, uint32_t endIdx, uint32_t initialCwnd, uint32_t mss);
401 
402  class CwndEvent {
403 public:
404  uint32_t m_oldCwnd;
405  uint32_t m_newCwnd;
406  };
407 
409 
410  void CwndChange (uint32_t oldCwnd, uint32_t newCwnd);
411  void CwndChangeNotInflated (uint32_t oldCwnd, uint32_t newCwnd);
412 };
413 
415  : TestCase ("Check to see that the ns-3 TCP congestion window works as expected for out-of-order packet delivery"),
416  m_writeResults (false)
417 {
418 }
419 
421 {
422 }
423 
424 void
425 Ns3TcpCwndTestCase2::CwndChange (uint32_t oldCwnd, uint32_t newCwnd)
426 {
427  CwndEvent event;
428 
429  event.m_oldCwnd = oldCwnd;
430  event.m_newCwnd = newCwnd;
431 
432  m_responses.Add (event);
433  NS_LOG_DEBUG ("Cwnd change event " << m_responses.GetN () << " at " << Now ().As (Time::S) << " " << oldCwnd << " " << newCwnd);
434 }
435 
436 void
437 Ns3TcpCwndTestCase2::CwndChangeNotInflated (uint32_t oldCwnd, uint32_t newCwnd)
438 {
439  NS_LOG_DEBUG ("Cwnd NOT INFLATED change event " << m_responses.GetN () << " at " << Now ().As (Time::S) << " " << oldCwnd << " " << newCwnd);
440 }
441 
442 void
444 {
445  NS_LOG_DEBUG ("Starting test case 2");
446  // Set up some default values for the simulation.
447  Config::SetDefault ("ns3::QueueBase::MaxSize", QueueSizeValue (QueueSize (QueueSizeUnit::PACKETS, 4)));
448  Packet::EnablePrinting ();
449 
450  NodeContainer n0n1;
451  n0n1.Create (2);
452 
454  n1n2.Add (n0n1.Get (1));
455  n1n2.Create (1);
456 
458  n2n3.Add (n1n2.Get (1));
459  n2n3.Create (1);
460 
461  PointToPointHelper p2p1;
462  p2p1.SetDeviceAttribute ("DataRate", DataRateValue (DataRate (1000000)));
463  p2p1.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (10)));
464  PointToPointHelper p2p2;
465  p2p2.SetDeviceAttribute ("DataRate", DataRateValue (DataRate (100000)));
466  p2p2.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (10)));
467 
468  // And then install devices and channels connecting our topology.
469  NetDeviceContainer dev0 = p2p1.Install (n0n1);
470  NetDeviceContainer dev1 = p2p2.Install (n1n2);
471  NetDeviceContainer dev2 = p2p1.Install (n2n3);
472 
473  // Now add ip/tcp stack to all nodes.
474  InternetStackHelper internet;
475  internet.InstallAll ();
476 
477  // Later, we add IP addresses.
478  Ipv4AddressHelper ipv4;
479  ipv4.SetBase ("10.1.3.0", "255.255.255.0");
480  ipv4.Assign (dev0);
481  ipv4.SetBase ("10.1.2.0", "255.255.255.0");
482  ipv4.Assign (dev1);
483  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
484  Ipv4InterfaceContainer ipInterfs = ipv4.Assign (dev2);
485 
486  // and setup ip routing tables to get total ip-level connectivity.
487  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
488 
489  // Disable traffic control layer so that drops occur
491  tch.Uninstall (dev0);
492  tch.Uninstall (dev1);
493  tch.Uninstall (dev2);
494 
495  // Set up the apps
496  uint16_t servPort = 50000;
497 
498  // Create a packet sink to receive these packets on n3
499  PacketSinkHelper sink ("ns3::TcpSocketFactory",
500  InetSocketAddress (Ipv4Address::GetAny (), servPort));
501 
502  ApplicationContainer apps = sink.Install (n2n3.Get (1));
503  apps.Start (Seconds (0.0));
504  apps.Stop (Seconds (5.4));
505 
506  // Create the socket for n0
507  Address sinkAddress (InetSocketAddress (ipInterfs.GetAddress (1), servPort));
508  Ptr<Socket> ns3TcpSocket = Socket::CreateSocket (n0n1.Get (0), TcpSocketFactory::GetTypeId ());
509  // Disable SACK because this test is testing NewReno behavior
510  ns3TcpSocket->SetAttribute ("Sack", BooleanValue (false));
511  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindowInflated", MakeCallback (&Ns3TcpCwndTestCase2::CwndChange, this));
512  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeCallback (&Ns3TcpCwndTestCase2::CwndChangeNotInflated, this));
513 
514  // Create and start the app for n0
515  Ptr<SimpleSource> app = CreateObject<SimpleSource> ();
516  app->Setup (ns3TcpSocket, sinkAddress, 1040, 1000, DataRate ("1Mbps"));
517  n0n1.Get (0)->AddApplication (app);
518  app->SetStartTime (Seconds (1.0));
519  app->SetStopTime (Seconds (4.1));
520 
521  if (m_writeResults)
522  {
523  // Write a pcap for tcp cwnd testcase with out-of-order delivery
525  pointToPoint.EnablePcapAll ("tcp-cwnd-ood");
526  }
527 
528  // Finally, set up the simulator to run.
529  Simulator::Stop (Seconds (4.1));
530  Simulator::Run ();
531  Simulator::Destroy ();
532 
533  //
534  // As new acks are received by the TCP under test, the congestion window
535  // should be opened up by one segment (MSS bytes) each time. This should
536  // trigger a congestion window change event which we hooked and saved above.
537  // We should now be able to look through the saved response vectors and follow
538  // the congestion window as it opens up when the ns-3 TCP under test
539  // transmits its bits
540  //
541  // From inspecting the results, we know that we should see N_EVENTS congestion
542  // window change events. On the tenth change event, the window should
543  // be cut from 5360 to 4288 due to 3 dup acks (NewReno behavior is to
544  // cut in half, and then add 3 segments (5360/2 + 3*536 = 4288)
545  //
546 
547  const uint32_t MSS = 536;
548  const uint32_t N_EVENTS = 38;
549 
550  CwndEvent event;
551 
552  NS_LOG_DEBUG ("Number of response events: " << m_responses.GetN ());
553  //NS_TEST_ASSERT_MSG_EQ (m_responses.GetN (), N_EVENTS, "Unexpected number of cwnd change events");
554 
555  // Ignore the first event logged (i=0) when m_cWnd goes from 0 to MSS bytes
556  VerifyCwndRun (1, 10, 2 * MSS, MSS);
557 
558  // At the point of loss, sndNxt = 15545; sndUna = 9113. FlightSize is 4824,
559  // so there are 9 segments outstanding. Cut ssthresh to 9/2 (2412) and
560  // cwnd to (9/2 + 3) = 4020
561  event = m_responses.Get (10);
562  NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, (MSS * 15)/2, "Wrong new cwnd value in cwnd change event " << 10);
563 
564  // Verify that cwnd increments by one for a few segments
565  // from 8.5 at index 11 to 12.5 at index 15
566  VerifyCwndRun (11, 15, (MSS * 17)/2, MSS);
567 
568  // partial ack at event 16, cwnd reset from 6700 (12.5*MSS) to 5092 (9.5*MSS)
569  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (16).m_newCwnd, (MSS * 19)/2, "Wrong new cwnd value in cwnd change event " << 16);
570 
571  // partial ack again of 3 segments after one more acks, cwnd reset to 7.5
572  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (18).m_newCwnd, (MSS * 15)/2, "Wrong new cwnd value in cwnd change event " << 18);
573 
574  //DUP ACKS in remaining fast recovery
575  VerifyCwndRun (18, 20, (MSS * 15)/2, MSS);
576 
577  // Process another partial ack
578  VerifyCwndRun (21, 24, (MSS * 13)/2, MSS);
579 
580  // Leaving fast recovery at event 25; set cwnd to 4 segments as per RFC 2582
581  // Sec. 3 para. 5 option 2 (sshthresh is 2412, 4.5 times MSS)
582  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (25).m_newCwnd, 2412, "Wrong new cwnd value in cwnd change event " << 25);
583 
584  //In CongAvoid each event will increase cwnd by (MSS * MSS / cwnd)
585  uint32_t cwnd = 2412;
586  for (uint32_t i = 26; i < N_EVENTS; ++i)
587  {
588  double adder = static_cast<double> (MSS * MSS) / cwnd;
589  adder = std::max (1.0, adder);
590  cwnd += static_cast<uint32_t> (adder);
591  NS_TEST_ASSERT_MSG_EQ (m_responses.Get (i).m_newCwnd, cwnd, "Wrong new cwnd value in cwnd change event " << i);
592  }
593  NS_LOG_DEBUG ("Reading out the cwnd event log");
594  for (uint32_t i = 0; i < N_EVENTS; ++i)
595  {
596  NS_LOG_DEBUG ("i: " << i << " newCwnd: " << m_responses.Get(i).m_newCwnd << " newCwnd segments " << static_cast<double> (m_responses.Get(i).m_newCwnd)/MSS);
597  }
598 }
599 
600 void
601 Ns3TcpCwndTestCase2::VerifyCwndRun (uint32_t beginIdx, uint32_t endIdx, uint32_t initialCwnd, uint32_t mss)
602 {
603 
604  CwndEvent event;
605 
606  for(uint32_t i = beginIdx, to = initialCwnd; i < endIdx; ++i, to += mss)
607  {
608  event = m_responses.Get (i);
609  NS_TEST_ASSERT_MSG_EQ (event.m_newCwnd, to, "Wrong new cwnd value in cwnd change event " << i);
610  }
611 }
612 
614 {
615 public:
617 };
618 
620  : TestSuite ("ns3-tcp-cwnd", SYSTEM)
621 {
622  AddTestCase (new Ns3TcpCwndTestCase1, TestCase::QUICK);
623  AddTestCase (new Ns3TcpCwndTestCase2, TestCase::QUICK);
624 }
625 
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:157
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:102
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)
A suite of tests to run.
Definition: test.h:1342
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:204
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1070
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:1155
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:388
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:249
stack
Definition: first.py:34
a polymophic address class
Definition: address.h:90
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1405
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:25
#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:1124
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
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:168
pointToPoint
Definition: first.py:28
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: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:37
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:242
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:272
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1062
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:810
interfaces
Definition: first.py:41
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:65
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:309
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
static const uint32_t packetSize
void CwndChange(uint32_t oldCwnd, uint32_t newCwnd)
devices
Definition: first.py:32
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:915
void SetStartTime(Time start)
Specify application start time.
Definition: application.cc:69
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.