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 
#define max(a, b)
Definition: 80211b.c:43
NodeContainer n2n3
NodeContainer n1n2
void CwndChange(uint32_t oldCwnd, uint32_t newCwnd)
virtual void DoRun(void)
Implementation to actually run this TestCase.
TestVectors< CwndEvent > m_responses
void CwndChange(uint32_t oldCwnd, uint32_t newCwnd)
virtual void DoRun(void)
Implementation to actually run this TestCase.
TestVectors< CwndEvent > m_responses
void CwndChangeNotInflated(uint32_t oldCwnd, uint32_t newCwnd)
void VerifyCwndRun(uint32_t beginIdx, uint32_t endIdx, uint32_t initialCwnd, uint32_t mss)
static TypeId GetTypeId(void)
Register this type.
virtual void StartApplication(void)
Application specific startup code.
Ptr< Socket > m_socket
virtual void StopApplication(void)
Application specific shutdown code.
void Setup(Ptr< Socket > socket, Address address, uint32_t packetSize, uint32_t nPackets, DataRate dataRate)
a polymophic address class
Definition: address.h:91
holds a vector of ns3::Application pointers.
void Start(Time start)
Arrange for all of the Applications in this container to Start() at the Time given as a parameter.
void Stop(Time stop)
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
The base class for all ns3 applications.
Definition: application.h:61
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Class for representing data rates.
Definition: data-rate.h:89
uint64_t GetBitRate() const
Get the underlying bitrate.
Definition: data-rate.cc:287
AttributeValue implementation for DataRate.
Definition: data-rate.h:298
An identifier for simulation events.
Definition: event-id.h:54
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:71
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
void InstallAll(void) const
Aggregate IPv4, IPv6, UDP, and TCP stacks to all nodes in the simulation.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
holds a vector of ns3::NetDevice pointers
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
void Add(NodeContainer other)
Append the contents of another NodeContainer to the end of this container.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:159
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:293
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
ApplicationContainer Install(NodeContainer c) const
Install an ns3::PacketSinkApplication on each node of the input container configured with all the att...
Build a set of PointToPointNetDevice objects.
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
NetDeviceContainer Install(NodeContainer c)
Class for representing queue sizes.
Definition: queue-size.h:95
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
virtual int Close(void)=0
Close a socket.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
Hold variables of type string.
Definition: string.h:41
encapsulates test code
Definition: test.h:1154
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1344
A simple way to store test vectors (for stimulus or from responses)
Definition: test.h:1407
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
AttributeValue implementation for Time.
Definition: nstime.h:1353
Build a set of QueueDisc objects.
void Uninstall(NetDeviceContainer c)
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
Hold an unsigned integer type.
Definition: uinteger.h:44
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
@ PACKETS
Use number of packets for queue size.
Definition: queue-size.h:44
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
#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
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1297
address
Definition: first.py:44
pointToPoint
Definition: first.py:35
devices
Definition: first.py:39
stack
Definition: first.py:41
nodes
Definition: first.py:32
interfaces
Definition: first.py:48
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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
Ns3TcpCwndTestSuite ns3TcpCwndTestSuite
static const uint32_t packetSize
Ptr< PacketSink > sink
Definition: wifi-tcp.cc:56
void SendPacket(Ptr< NetDevice > sourceDevice, Address &destination)
This example (inspired from tv-trans-example) enables to generate the transmitted spectra of Wi-Fi st...