A Discrete-Event Network Simulator
API
codel-vs-pfifo-basic-test.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 ResiliNets, ITTC, University of Kansas
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Truc Anh N Nguyen <trucanh524@gmail.com>
18  * Modified by: Pasquale Imputato <p.imputato@gmail.com>
19  *
20  */
21 
22 /*
23  * This is a basic example that compares CoDel and PfifoFast queues using a simple, single-flow
24  * 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 "ns3/applications-module.h"
37 #include "ns3/core-module.h"
38 #include "ns3/enum.h"
39 #include "ns3/error-model.h"
40 #include "ns3/event-id.h"
41 #include "ns3/internet-module.h"
42 #include "ns3/ipv4-global-routing-helper.h"
43 #include "ns3/network-module.h"
44 #include "ns3/point-to-point-module.h"
45 #include "ns3/tcp-header.h"
46 #include "ns3/traffic-control-module.h"
47 #include "ns3/udp-header.h"
48 
49 #include <fstream>
50 #include <iostream>
51 #include <string>
52 
53 using namespace ns3;
54 
55 NS_LOG_COMPONENT_DEFINE("CoDelPfifoFastBasicTest");
56 
64 static void
65 CwndTracer(Ptr<OutputStreamWrapper> stream, uint32_t oldval, uint32_t newval)
66 {
67  *stream->GetStream() << oldval << " " << newval << std::endl;
68 }
69 
77 static void
78 TraceCwnd(std::string cwndTrFileName)
79 {
80  AsciiTraceHelper ascii;
81  if (cwndTrFileName.empty())
82  {
83  NS_LOG_DEBUG("No trace file for cwnd provided");
84  return;
85  }
86  else
87  {
88  Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream(cwndTrFileName);
90  "/NodeList/1/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow",
91  MakeBoundCallback(&CwndTracer, stream));
92  }
93 }
94 
95 int
96 main(int argc, char* argv[])
97 {
98  std::string bottleneckBandwidth = "5Mbps";
99  std::string bottleneckDelay = "5ms";
100  std::string accessBandwidth = "100Mbps";
101  std::string accessDelay = "0.1ms";
102 
103  std::string queueDiscType = "PfifoFast"; // PfifoFast or CoDel
104  uint32_t queueDiscSize = 1000; // in packets
105  uint32_t queueSize = 10; // in packets
106  uint32_t pktSize = 1458; // in bytes. 1458 to prevent fragments
107  float startTime = 0.1F;
108  float simDuration = 60; // in seconds
109 
110  bool isPcapEnabled = true;
111  std::string pcapFileName = "pcapFilePfifoFast.pcap";
112  std::string cwndTrFileName = "cwndPfifoFast.tr";
113  bool logging = false;
114 
115  CommandLine cmd(__FILE__);
116  cmd.AddValue("bottleneckBandwidth", "Bottleneck bandwidth", bottleneckBandwidth);
117  cmd.AddValue("bottleneckDelay", "Bottleneck delay", bottleneckDelay);
118  cmd.AddValue("accessBandwidth", "Access link bandwidth", accessBandwidth);
119  cmd.AddValue("accessDelay", "Access link delay", accessDelay);
120  cmd.AddValue("queueDiscType", "Bottleneck queue disc type: PfifoFast, CoDel", queueDiscType);
121  cmd.AddValue("queueDiscSize", "Bottleneck queue disc size in packets", queueDiscSize);
122  cmd.AddValue("queueSize", "Devices queue size in packets", queueSize);
123  cmd.AddValue("pktSize", "Packet size in bytes", pktSize);
124  cmd.AddValue("startTime", "Simulation start time", startTime);
125  cmd.AddValue("simDuration", "Simulation duration in seconds", simDuration);
126  cmd.AddValue("isPcapEnabled", "Flag to enable/disable pcap", isPcapEnabled);
127  cmd.AddValue("pcapFileName", "Name of pcap file", pcapFileName);
128  cmd.AddValue("cwndTrFileName", "Name of cwnd trace file", cwndTrFileName);
129  cmd.AddValue("logging", "Flag to enable/disable logging", logging);
130  cmd.Parse(argc, argv);
131 
132  float stopTime = startTime + simDuration;
133 
134  if (logging)
135  {
136  LogComponentEnable("CoDelPfifoFastBasicTest", LOG_LEVEL_ALL);
137  LogComponentEnable("BulkSendApplication", LOG_LEVEL_INFO);
138  LogComponentEnable("PfifoFastQueueDisc", LOG_LEVEL_ALL);
139  LogComponentEnable("CoDelQueueDisc", LOG_LEVEL_ALL);
140  }
141 
142  // Enable checksum
143  if (isPcapEnabled)
144  {
145  GlobalValue::Bind("ChecksumEnabled", BooleanValue(true));
146  }
147 
148  // Devices queue configuration
149  Config::SetDefault("ns3::DropTailQueue<Packet>::MaxSize",
150  QueueSizeValue(QueueSize(QueueSizeUnit::PACKETS, queueSize)));
151 
152  // Create gateway, source, and sink
153  NodeContainer gateway;
154  gateway.Create(1);
155  NodeContainer source;
156  source.Create(1);
158  sink.Create(1);
159 
160  // Create and configure access link and bottleneck link
161  PointToPointHelper accessLink;
162  accessLink.SetDeviceAttribute("DataRate", StringValue(accessBandwidth));
163  accessLink.SetChannelAttribute("Delay", StringValue(accessDelay));
164 
165  PointToPointHelper bottleneckLink;
166  bottleneckLink.SetDeviceAttribute("DataRate", StringValue(bottleneckBandwidth));
167  bottleneckLink.SetChannelAttribute("Delay", StringValue(bottleneckDelay));
168 
170  stack.InstallAll();
171 
172  // Access link traffic control configuration
173  TrafficControlHelper tchPfifoFastAccess;
174  tchPfifoFastAccess.SetRootQueueDisc("ns3::PfifoFastQueueDisc", "MaxSize", StringValue("1000p"));
175 
176  // Bottleneck link traffic control configuration
177  TrafficControlHelper tchPfifo;
178  tchPfifo.SetRootQueueDisc("ns3::PfifoFastQueueDisc",
179  "MaxSize",
180  StringValue(std::to_string(queueDiscSize) + "p"));
181 
182  TrafficControlHelper tchCoDel;
183  tchCoDel.SetRootQueueDisc("ns3::CoDelQueueDisc");
184  Config::SetDefault("ns3::CoDelQueueDisc::MaxSize",
185  StringValue(std::to_string(queueDiscSize) + "p"));
186 
188  address.SetBase("10.0.0.0", "255.255.255.0");
189 
190  // Configure the source and sink net devices
191  // and the channels between the source/sink and the gateway
192  Ipv4InterfaceContainer sinkInterface;
193 
194  NetDeviceContainer devicesAccessLink;
195  NetDeviceContainer devicesBottleneckLink;
196 
197  devicesAccessLink = accessLink.Install(source.Get(0), gateway.Get(0));
198  tchPfifoFastAccess.Install(devicesAccessLink);
199  address.NewNetwork();
200  Ipv4InterfaceContainer interfaces = address.Assign(devicesAccessLink);
201 
202  devicesBottleneckLink = bottleneckLink.Install(gateway.Get(0), sink.Get(0));
203  address.NewNetwork();
204 
205  if (queueDiscType == "PfifoFast")
206  {
207  tchPfifo.Install(devicesBottleneckLink);
208  }
209  else if (queueDiscType == "CoDel")
210  {
211  tchCoDel.Install(devicesBottleneckLink);
212  }
213  else
214  {
215  NS_ABORT_MSG(
216  "Invalid queue disc type: Use --queueDiscType=PfifoFast or --queueDiscType=CoDel");
217  }
218  interfaces = address.Assign(devicesBottleneckLink);
219 
220  sinkInterface.Add(interfaces.Get(1));
221 
222  NS_LOG_INFO("Initialize Global Routing.");
224 
225  uint16_t port = 50000;
226  Address sinkLocalAddress(InetSocketAddress(Ipv4Address::GetAny(), port));
227  PacketSinkHelper sinkHelper("ns3::TcpSocketFactory", sinkLocalAddress);
228 
229  // Configure application
230  AddressValue remoteAddress(InetSocketAddress(sinkInterface.GetAddress(0, 0), port));
231  Config::SetDefault("ns3::TcpSocket::SegmentSize", UintegerValue(pktSize));
232  BulkSendHelper ftp("ns3::TcpSocketFactory", Address());
233  ftp.SetAttribute("Remote", remoteAddress);
234  ftp.SetAttribute("SendSize", UintegerValue(pktSize));
235  ftp.SetAttribute("MaxBytes", UintegerValue(0));
236 
237  ApplicationContainer sourceApp = ftp.Install(source.Get(0));
238  sourceApp.Start(Seconds(0));
239  sourceApp.Stop(Seconds(stopTime - 3));
240 
241  sinkHelper.SetAttribute("Protocol", TypeIdValue(TcpSocketFactory::GetTypeId()));
242  ApplicationContainer sinkApp = sinkHelper.Install(sink);
243  sinkApp.Start(Seconds(0));
244  sinkApp.Stop(Seconds(stopTime));
245 
246  Simulator::Schedule(Seconds(0.00001), &TraceCwnd, cwndTrFileName);
247 
248  if (isPcapEnabled)
249  {
250  accessLink.EnablePcap(pcapFileName, source, true);
251  }
252 
254  Simulator::Run();
255 
257  return 0;
258 }
a polymophic address class
Definition: address.h:101
holds a vector of ns3::Application pointers.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
Manage ASCII trace files for device models.
Definition: trace-helper.h:174
Ptr< OutputStreamWrapper > CreateFileStream(std::string filename, std::ios::openmode filemode=std::ios::out)
Create and initialize an output stream object we'll use to write the traced bits.
A helper to make it easier to instantiate an ns3::BulkSendApplication on a set of nodes.
Parse command-line arguments.
Definition: command-line.h:232
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...
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
static Ipv4Address GetAny()
static void PopulateRoutingTables()
Build a routing database and initialize the routing tables of the nodes in the simulation.
holds a vector of std::pair of Ptr<Ipv4> and interface index.
void Add(const Ipv4InterfaceContainer &other)
Concatenate the entries in the other container with ours.
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.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
std::ostream * GetStream()
Return a pointer to an ostream previously set in the wrapper.
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
void EnablePcap(std::string prefix, Ptr< NetDevice > nd, bool promiscuous=false, bool explicitFilename=false)
Enable pcap output the indicated net device.
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:96
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
Hold variables of type string.
Definition: string.h:56
static TypeId GetTypeId()
Get the type ID.
Build a set of QueueDisc objects.
QueueDiscContainer Install(NetDeviceContainer c)
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.
Hold an unsigned integer type.
Definition: uinteger.h:45
static void TraceCwnd(std::string cwndTrFileName)
Function to enable the Congestion window tracing.
static void CwndTracer(Ptr< OutputStreamWrapper > stream, uint32_t oldval, uint32_t newval)
Function called when Congestion Window is changed.
uint16_t port
Definition: dsdv-manet.cc:44
Time stopTime
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:950
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Definition: callback.h:765
@ PACKETS
Use number of packets for queue size.
Definition: queue-size.h:45
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
address
Definition: first.py:47
stack
Definition: first.py:44
interfaces
Definition: first.py:50
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.h:25255
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void LogComponentEnable(const std::string &name, LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:302
@ LOG_LEVEL_ALL
Print everything.
Definition: log.h:116
@ LOG_LEVEL_INFO
LOG_INFO and above.
Definition: log.h:104
cmd
Definition: second.py:40
std::ofstream queueSize
uint32_t pktSize
packet size used for the simulation (in bytes)
Ptr< PacketSink > sink
Pointer to the packet sink application.
Definition: wifi-tcp.cc:55