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.1;
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 
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::QueueBase::Mode", StringValue ("QUEUE_MODE_PACKETS"));
133  Config::SetDefault ("ns3::QueueBase::MaxPackets", UintegerValue (queueSize));
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", "Limit", UintegerValue (1000));
158 
159  // Bottleneck link traffic control configuration
160  TrafficControlHelper tchPfifo;
161  tchPfifo.SetRootQueueDisc ("ns3::PfifoFastQueueDisc", "Limit", UintegerValue (queueDiscSize));
162 
163  TrafficControlHelper tchCoDel;
164  tchCoDel.SetRootQueueDisc ("ns3::CoDelQueueDisc");
166  Config::SetDefault ("ns3::CoDelQueueDisc::MaxPackets", UintegerValue (queueDiscSize));
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 
232  Simulator::Stop (Seconds (stopTime));
233  Simulator::Run ();
234 
236  return 0;
237 }
Ptr< PacketSink > sink
Definition: wifi-tcp.cc:45
holds a vector of ns3::Application pointers.
Manage ASCII trace files for device models.
Definition: trace-helper.h:161
an Inet address class
static Ipv4Address GetAny(void)
std::pair< Ptr< Ipv4 >, uint32_t > Get(uint32_t i) const
Get the std::pair of an Ptr and interface stored at the location specified by the index...
AttributeValue implementation for Boolean.
Definition: boolean.h:36
QueueDiscContainer Install(NetDeviceContainer c)
#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 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:1686
static void TraceCwnd(std::string cwndTrFileName)
static void Run(void)
Run the simulation.
Definition: simulator.cc:226
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
aggregate IP/TCP/UDP functionality to existing Nodes.
LOG_INFO and above.
Definition: log.h:103
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:277
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes...
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. ...
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.
tuple cmd
Definition: second.py:35
double stopTime
uint16_t port
Definition: dsdv-manet.cc:44
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:369
Hold variables of type enum.
Definition: enum.h:54
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1375
void InstallAll(void) const
Aggregate IPv4, IPv6, UDP, and TCP stacks to all nodes in the simulation.
Hold an unsigned integer type.
Definition: uinteger.h:44
double startTime
tuple interfaces
Definition: first.py:41
holds a vector of ns3::NetDevice pointers
AttributeValue implementation for TypeId.
Definition: type-id.h:608
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:832
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...
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:205
static void CwndTracer(Ptr< OutputStreamWrapper >stream, uint32_t oldval, uint32_t newval)
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:190
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.
uint16_t SetRootQueueDisc(std::string type, std::string n01="", const AttributeValue &v01=EmptyAttributeValue(), std::string n02="", const AttributeValue &v02=EmptyAttributeValue(), std::string n03="", const AttributeValue &v03=EmptyAttributeValue(), std::string n04="", const AttributeValue &v04=EmptyAttributeValue(), std::string n05="", const AttributeValue &v05=EmptyAttributeValue(), std::string n06="", const AttributeValue &v06=EmptyAttributeValue(), std::string n07="", const AttributeValue &v07=EmptyAttributeValue(), std::string n08="", const AttributeValue &v08=EmptyAttributeValue(), std::string n09="", const AttributeValue &v09=EmptyAttributeValue(), std::string n10="", const AttributeValue &v10=EmptyAttributeValue(), std::string n11="", const AttributeValue &v11=EmptyAttributeValue(), std::string n12="", const AttributeValue &v12=EmptyAttributeValue(), std::string n13="", const AttributeValue &v13=EmptyAttributeValue(), std::string n14="", const AttributeValue &v14=EmptyAttributeValue(), std::string n15="", const AttributeValue &v15=EmptyAttributeValue())
Helper function used to set a root queue disc of the given type and with the given attributes...
tuple stack
Definition: first.py:34
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...
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
void AddValue(const std::string &name, const std::string &help, T &value)
Add a program argument, assigning to POD.
Definition: command-line.h:498
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:234
Ptr< Node > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:269
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:993
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:782
Print everything.
Definition: log.h:112
Ipv4Address NewNetwork(void)
Increment the network number and reset the IP address counter to the base value provided in the SetBa...
Use number of packets for maximum queue disc size.
void Parse(int argc, char *argv[])
Parse the program arguments.
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.
tuple address
Definition: first.py:37
void EnablePcap(std::string prefix, Ptr< NetDevice > nd, bool promiscuous=false, bool explicitFilename=false)
Enable pcap output the indicated net device.
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const