A Discrete-Event Network Simulator
API
codel-vs-pfifo-basic-test.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2014 ResiliNets, ITTC, University of Kansas
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  * Author: Truc Anh N Nguyen <trucanh524@gmail.com>
19  * Modified by: Pasquale Imputato <p.imputato@gmail.com>
20  *
21  */
22 
23 /*
24  * This is a basic example that compares CoDel and PfifoFast queues using a simple, single-flow topology:
25  *
26  * source -------------------------- router ------------------------ sink
27  * 100 Mb/s, 0.1 ms pfifofast 5 Mb/s, 5ms
28  * or codel bottleneck
29  *
30  * The source generates traffic across the network using BulkSendApplication.
31  * The default TCP version in ns-3, TcpNewReno, is used as the transport-layer protocol.
32  * Packets transmitted during a simulation run are captured into a .pcap file, and
33  * congestion window values are also traced.
34  */
35 
36 #include <iostream>
37 #include <fstream>
38 #include <string>
39 
40 #include "ns3/core-module.h"
41 #include "ns3/network-module.h"
42 #include "ns3/internet-module.h"
43 #include "ns3/point-to-point-module.h"
44 #include "ns3/applications-module.h"
45 #include "ns3/error-model.h"
46 #include "ns3/tcp-header.h"
47 #include "ns3/udp-header.h"
48 #include "ns3/enum.h"
49 #include "ns3/event-id.h"
50 #include "ns3/ipv4-global-routing-helper.h"
51 #include "ns3/traffic-control-module.h"
52 
53 using namespace ns3;
54 
55 NS_LOG_COMPONENT_DEFINE ("CoDelPfifoFastBasicTest");
56 
57 static void
58 CwndTracer (Ptr<OutputStreamWrapper>stream, uint32_t oldval, uint32_t newval)
59 {
60  *stream->GetStream () << oldval << " " << newval << std::endl;
61 }
62 
63 static void
64 TraceCwnd (std::string cwndTrFileName)
65 {
66  AsciiTraceHelper ascii;
67  if (cwndTrFileName.compare ("") == 0)
68  {
69  NS_LOG_DEBUG ("No trace file for cwnd provided");
70  return;
71  }
72  else
73  {
74  Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream (cwndTrFileName.c_str ());
75  Config::ConnectWithoutContext ("/NodeList/1/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow",MakeBoundCallback (&CwndTracer, stream));
76  }
77 }
78 
79 int main (int argc, char *argv[])
80 {
81  std::string bottleneckBandwidth = "5Mbps";
82  std::string bottleneckDelay = "5ms";
83  std::string accessBandwidth = "100Mbps";
84  std::string accessDelay = "0.1ms";
85 
86  std::string queueDiscType = "PfifoFast"; //PfifoFast or CoDel
87  uint32_t queueDiscSize = 1000; //in packets
88  uint32_t queueSize = 10; //in packets
89  uint32_t pktSize = 1458; //in bytes. 1458 to prevent fragments
90  float startTime = 0.1f;
91  float simDuration = 60; //in seconds
92 
93  bool isPcapEnabled = true;
94  std::string pcapFileName = "pcapFilePfifoFast.pcap";
95  std::string cwndTrFileName = "cwndPfifoFast.tr";
96  bool logging = false;
97 
98  CommandLine cmd (__FILE__);
99  cmd.AddValue ("bottleneckBandwidth", "Bottleneck bandwidth", bottleneckBandwidth);
100  cmd.AddValue ("bottleneckDelay", "Bottleneck delay", bottleneckDelay);
101  cmd.AddValue ("accessBandwidth", "Access link bandwidth", accessBandwidth);
102  cmd.AddValue ("accessDelay", "Access link delay", accessDelay);
103  cmd.AddValue ("queueDiscType", "Bottleneck queue disc type: PfifoFast, CoDel", queueDiscType);
104  cmd.AddValue ("queueDiscSize", "Bottleneck queue disc size in packets", queueDiscSize);
105  cmd.AddValue ("queueSize", "Devices queue size in packets", queueSize);
106  cmd.AddValue ("pktSize", "Packet size in bytes", pktSize);
107  cmd.AddValue ("startTime", "Simulation start time", startTime);
108  cmd.AddValue ("simDuration", "Simulation duration in seconds", simDuration);
109  cmd.AddValue ("isPcapEnabled", "Flag to enable/disable pcap", isPcapEnabled);
110  cmd.AddValue ("pcapFileName", "Name of pcap file", pcapFileName);
111  cmd.AddValue ("cwndTrFileName", "Name of cwnd trace file", cwndTrFileName);
112  cmd.AddValue ("logging", "Flag to enable/disable logging", logging);
113  cmd.Parse (argc, argv);
114 
115  float stopTime = startTime + simDuration;
116 
117  if (logging)
118  {
119  LogComponentEnable ("CoDelPfifoFastBasicTest", LOG_LEVEL_ALL);
120  LogComponentEnable ("BulkSendApplication", LOG_LEVEL_INFO);
121  LogComponentEnable ("PfifoFastQueueDisc", LOG_LEVEL_ALL);
122  LogComponentEnable ("CoDelQueueDisc", LOG_LEVEL_ALL);
123  }
124 
125  // Enable checksum
126  if (isPcapEnabled)
127  {
128  GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));
129  }
130 
131  // Devices queue configuration
132  Config::SetDefault ("ns3::DropTailQueue<Packet>::MaxSize",
134 
135  // Create gateway, source, and sink
136  NodeContainer gateway;
137  gateway.Create (1);
138  NodeContainer source;
139  source.Create (1);
141  sink.Create (1);
142 
143  // Create and configure access link and bottleneck link
144  PointToPointHelper accessLink;
145  accessLink.SetDeviceAttribute ("DataRate", StringValue (accessBandwidth));
146  accessLink.SetChannelAttribute ("Delay", StringValue (accessDelay));
147 
148  PointToPointHelper bottleneckLink;
149  bottleneckLink.SetDeviceAttribute ("DataRate", StringValue (bottleneckBandwidth));
150  bottleneckLink.SetChannelAttribute ("Delay", StringValue (bottleneckDelay));
151 
153  stack.InstallAll ();
154 
155  // Access link traffic control configuration
156  TrafficControlHelper tchPfifoFastAccess;
157  tchPfifoFastAccess.SetRootQueueDisc ("ns3::PfifoFastQueueDisc", "MaxSize", StringValue ("1000p"));
158 
159  // Bottleneck link traffic control configuration
160  TrafficControlHelper tchPfifo;
161  tchPfifo.SetRootQueueDisc ("ns3::PfifoFastQueueDisc", "MaxSize",
162  StringValue (std::to_string(queueDiscSize) + "p"));
163 
164  TrafficControlHelper tchCoDel;
165  tchCoDel.SetRootQueueDisc ("ns3::CoDelQueueDisc");
166  Config::SetDefault ("ns3::CoDelQueueDisc::MaxSize", StringValue (std::to_string(queueDiscSize) + "p"));
167 
169  address.SetBase ("10.0.0.0", "255.255.255.0");
170 
171  // Configure the source and sink net devices
172  // and the channels between the source/sink and the gateway
173  Ipv4InterfaceContainer sinkInterface;
174 
175  NetDeviceContainer devicesAccessLink, devicesBottleneckLink;
176 
177  devicesAccessLink = accessLink.Install (source.Get (0), gateway.Get (0));
178  tchPfifoFastAccess.Install (devicesAccessLink);
179  address.NewNetwork ();
180  Ipv4InterfaceContainer interfaces = address.Assign (devicesAccessLink);
181 
182  devicesBottleneckLink = bottleneckLink.Install (gateway.Get (0), sink.Get (0));
183  address.NewNetwork ();
184 
185  if (queueDiscType.compare ("PfifoFast") == 0)
186  {
187  tchPfifo.Install (devicesBottleneckLink);
188  }
189  else if (queueDiscType.compare ("CoDel") == 0)
190  {
191  tchCoDel.Install (devicesBottleneckLink);
192  }
193  else
194  {
195  NS_ABORT_MSG ("Invalid queue disc type: Use --queueDiscType=PfifoFast or --queueDiscType=CoDel");
196  }
197  interfaces = address.Assign (devicesBottleneckLink);
198 
199  sinkInterface.Add (interfaces.Get (1));
200 
201  NS_LOG_INFO ("Initialize Global Routing.");
203 
204  uint16_t port = 50000;
205  Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
206  PacketSinkHelper sinkHelper ("ns3::TcpSocketFactory", sinkLocalAddress);
207 
208  // Configure application
209  AddressValue remoteAddress (InetSocketAddress (sinkInterface.GetAddress (0, 0), port));
210  Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (pktSize));
211  BulkSendHelper ftp ("ns3::TcpSocketFactory", Address ());
212  ftp.SetAttribute ("Remote", remoteAddress);
213  ftp.SetAttribute ("SendSize", UintegerValue (pktSize));
214  ftp.SetAttribute ("MaxBytes", UintegerValue (0));
215 
216  ApplicationContainer sourceApp = ftp.Install (source.Get (0));
217  sourceApp.Start (Seconds (0));
218  sourceApp.Stop (Seconds (stopTime - 3));
219 
220  sinkHelper.SetAttribute ("Protocol", TypeIdValue (TcpSocketFactory::GetTypeId ()));
221  ApplicationContainer sinkApp = sinkHelper.Install (sink);
222  sinkApp.Start (Seconds (0));
223  sinkApp.Stop (Seconds (stopTime));
224 
225  Simulator::Schedule (Seconds (0.00001), &TraceCwnd, cwndTrFileName);
226 
227  if (isPcapEnabled)
228  {
229  accessLink.EnablePcap (pcapFileName,source,true);
230  }
231 
233  Simulator::Run ();
234 
236  return 0;
237 }
Ptr< PacketSink > sink
Definition: wifi-tcp.cc:56
holds a vector of ns3::Application pointers.
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
Manage ASCII trace files for device models.
Definition: trace-helper.h:162
an Inet address class
static Ipv4Address GetAny(void)
AttributeValue implementation for Boolean.
Definition: boolean.h:36
QueueDiscContainer Install(NetDeviceContainer c)
Class for representing queue sizes.
Definition: queue-size.h:94
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
A helper to make it easier to instantiate an ns3::BulkSendApplication on a set of nodes...
holds a vector of std::pair of Ptr<Ipv4> and interface index.
static void PopulateRoutingTables(void)
Build a routing database and initialize the routing tables of the nodes in the simulation.
Hold variables of type string.
Definition: string.h:41
NetDeviceContainer Install(NodeContainer c)
void Add(const Ipv4InterfaceContainer &other)
Concatenate the entries in the other container with ours.
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Make Callbacks with one bound argument.
Definition: callback.h:1703
static void TraceCwnd(std::string cwndTrFileName)
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
aggregate IP/TCP/UDP functionality to existing Nodes.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes...
cmd
Definition: second.py:35
Ptr< OutputStreamWrapper > CreateFileStream(std::string filename, std::ios::openmode filemode=std::ios::out)
Create and initialize an output stream object we&#39;ll use to write the traced bits. ...
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.
stack
Definition: first.py:41
uint16_t port
Definition: dsdv-manet.cc:45
a polymophic address class
Definition: address.h:90
void LogComponentEnable(char const *name, enum LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:361
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
Hold an unsigned integer type.
Definition: uinteger.h:44
double startTime
Use number of packets for queue size.
Definition: queue-size.h:44
LOG_INFO and above.
Definition: log.h:107
holds a vector of ns3::NetDevice pointers
AttributeValue implementation for TypeId.
Definition: type-id.h:595
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:901
Build a set of QueueDisc objects.
static void Bind(std::string name, const AttributeValue &value)
Iterate over the set of GlobalValues until a matching name is found and then set its value with Globa...
Time stopTime
void Start(Time start)
Arrange for all of the Applications in this container to Start() at the Time given as a parameter...
Parse command-line arguments.
Definition: command-line.h:227
static void CwndTracer(Ptr< OutputStreamWrapper >stream, uint32_t oldval, uint32_t newval)
uint16_t SetRootQueueDisc(const std::string &type, Args &&... args)
Helper function used to set a root queue disc of the given type and with the given attributes...
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:136
static TypeId GetTypeId(void)
Get the type ID.
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
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
AttributeValue implementation for Address.
Definition: address.h:278
void Stop(Time stop)
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter...
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:180
#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:1289
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
interfaces
Definition: first.py:48
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
Print everything.
Definition: log.h:116
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
void EnablePcap(std::string prefix, Ptr< NetDevice > nd, bool promiscuous=false, bool explicitFilename=false)
Enable pcap output the indicated net device.
uint32_t pktSize
packet size used for the simulation (in bytes)
Definition: wifi-bianchi.cc:86
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.