A Discrete-Event Network Simulator
API
cobalt-vs-codel.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2019 NITK Surathkal
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: Shefali Gupta <shefaligups11@ogmail.com>
19  * Jendaipou Palmei <jendaipoupalmei@gmail.com>
20  * Mohit P. Tahiliani <tahiliani@nitk.edu.in>
21  */
22 
23 #include "ns3/core-module.h"
24 #include "ns3/network-module.h"
25 #include "ns3/point-to-point-module.h"
26 #include "ns3/applications-module.h"
27 #include <fstream>
28 #include "ns3/ipv6-static-routing-helper.h"
29 #include "ns3/ipv6-routing-table-entry.h"
30 #include "ns3/internet-module.h"
31 #include "ns3/tcp-header.h"
32 #include "ns3/traffic-control-module.h"
33 #include <string>
34 
35 // Dumbbell topology with 7 senders and 1 receiver
36 // is used for this example. On successful completion,
37 // the Congestion window and Queue size traces get stored
38 // in MixTraffic/ directory, inside cwndTraces and
39 // queueTraces sub-directories, respectively.
40 
41 using namespace ns3;
42 
43 std::string dir = "MixTraffic/";
44 
45 void
46 CheckQueueSize (Ptr<QueueDisc> queue,std::string queue_disc_type)
47 {
48  double qSize = queue->GetCurrentSize ().GetValue ();
49  // check queue size every 1/10 of a second
50  Simulator::Schedule (Seconds (0.1), &CheckQueueSize, queue, queue_disc_type);
51 
52  std::ofstream fPlotQueue (dir + queue_disc_type + "/queueTraces/queue.plotme", std::ios::out | std::ios::app);
53  fPlotQueue << Simulator::Now ().GetSeconds () << " " << qSize << std::endl;
54  fPlotQueue.close ();
55 }
56 
57 static void
58 CwndTrace (Ptr<OutputStreamWrapper> stream, uint32_t oldCwnd, uint32_t newCwnd)
59 {
60  *stream->GetStream () << Simulator::Now ().GetSeconds () << " " << newCwnd / 1446.0 << std::endl;
61 }
62 
63 static void
64 TraceCwnd (std::string queue_disc_type)
65 {
66  for (uint8_t i = 0; i < 5; i++)
67  {
68  AsciiTraceHelper asciiTraceHelper;
69  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream (dir + queue_disc_type + "/cwndTraces/S1-" + std::to_string (i + 1) + ".plotme");
70  Config::ConnectWithoutContext ("/NodeList/" + std::to_string (i) + "/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow", MakeBoundCallback (&CwndTrace,stream));
71  }
72 }
73 
74 void experiment (std::string queue_disc_type)
75 {
76  // Set the simulation stop time in seconds
77  double stopTime = 101;
78  std::string queue_disc = std::string ("ns3::") + queue_disc_type;
79 
80  std::string bottleneckBandwidth = "10Mbps";
81  std::string bottleneckDelay = "50ms";
82 
83  std::string accessBandwidth = "10Mbps";
84  std::string accessDelay = "5ms";
85 
86  // Create sender
87  NodeContainer tcpSender;
88  tcpSender.Create (5);
89 
90  NodeContainer udpSender;
91  udpSender.Create (2);
92 
93  // Create gateway
94  NodeContainer gateway;
95  gateway.Create (2);
96 
97  // Create sink
99  sink.Create (1);
100 
101  Config::SetDefault ("ns3::TcpSocket::SndBufSize", UintegerValue (1 << 20));
102  Config::SetDefault ("ns3::TcpSocket::RcvBufSize", UintegerValue (1 << 20));
103  Config::SetDefault ("ns3::TcpSocket::DelAckTimeout", TimeValue (Seconds (0)));
104  Config::SetDefault ("ns3::TcpSocket::InitialCwnd", UintegerValue (1));
105  Config::SetDefault ("ns3::TcpSocketBase::LimitedTransmit", BooleanValue (false));
106  Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (1446));
107  Config::SetDefault ("ns3::TcpSocketBase::WindowScaling", BooleanValue (true));
108  Config::SetDefault (queue_disc + "::MaxSize", QueueSizeValue (QueueSize ("200p")));
109 
110  InternetStackHelper internet;
111  internet.InstallAll ();
112 
113  TrafficControlHelper tchPfifo;
114  uint16_t handle = tchPfifo.SetRootQueueDisc ("ns3::PfifoFastQueueDisc");
115  tchPfifo.AddInternalQueues (handle, 3, "ns3::DropTailQueue", "MaxSize", StringValue ("1000p"));
116 
118  tch.SetRootQueueDisc (queue_disc);
119 
120  PointToPointHelper accessLink;
121  accessLink.SetDeviceAttribute ("DataRate", StringValue (accessBandwidth));
122  accessLink.SetChannelAttribute ("Delay", StringValue (accessDelay));
123 
124  // Configure the senders and sinks net devices
125  // and the channels between the senders/sinks and the gateways
127  for (uint8_t i = 0; i < 5; i++)
128  {
129  devices [i] = accessLink.Install (tcpSender.Get (i), gateway.Get (0));
130  tchPfifo.Install (devices [i]);
131  }
132 
133  NetDeviceContainer devices_sink;
134  devices_sink = accessLink.Install (gateway.Get (1), sink.Get (0));
135  tchPfifo.Install (devices_sink);
136 
137  PointToPointHelper bottleneckLink;
138  bottleneckLink.SetDeviceAttribute ("DataRate", StringValue (bottleneckBandwidth));
139  bottleneckLink.SetChannelAttribute ("Delay", StringValue (bottleneckDelay));
140 
141  NetDeviceContainer devices_gateway;
142  devices_gateway = bottleneckLink.Install (gateway.Get (0), gateway.Get (1));
143  // Install QueueDisc at gateway
144  QueueDiscContainer queueDiscs = tch.Install (devices_gateway);
145 
147  address.SetBase ("10.0.0.0", "255.255.255.0");
148 
150  Ipv4InterfaceContainer interfaces_sink;
151  Ipv4InterfaceContainer interfaces_gateway;
152  Ipv4InterfaceContainer udpinterfaces [2];
153 
154  NetDeviceContainer udpdevices [2];
155 
156  for (uint8_t i = 0; i < 5; i++)
157  {
158  address.NewNetwork ();
159  interfaces [i] = address.Assign (devices [i]);
160  }
161 
162  for (uint8_t i = 0; i < 2; i++)
163  {
164  udpdevices [i] = accessLink.Install (udpSender.Get (i), gateway.Get (0));
165  address.NewNetwork ();
166  udpinterfaces [i] = address.Assign (udpdevices [i]);
167  }
168 
169  address.NewNetwork ();
170  interfaces_gateway = address.Assign (devices_gateway);
171 
172  address.NewNetwork ();
173  interfaces_sink = address.Assign (devices_sink);
174 
176 
177  uint16_t port = 50000;
178  uint16_t port1 = 50001;
179  Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
180  Address sinkLocalAddress1 (InetSocketAddress (Ipv4Address::GetAny (), port1));
181  PacketSinkHelper sinkHelper ("ns3::TcpSocketFactory", sinkLocalAddress);
182  PacketSinkHelper sinkHelper1 ("ns3::UdpSocketFactory", sinkLocalAddress1);
183 
184  AddressValue remoteAddress (InetSocketAddress (interfaces_sink.GetAddress (1), port));
185  AddressValue remoteAddress1 (InetSocketAddress (interfaces_sink.GetAddress (1), port1));
186 
187  BulkSendHelper ftp ("ns3::TcpSocketFactory", Address ());
188  ftp.SetAttribute ("Remote", remoteAddress);
189  ftp.SetAttribute ("SendSize", UintegerValue (1000));
190 
191  ApplicationContainer sourceApp = ftp.Install (tcpSender);
192  sourceApp.Start (Seconds (0));
193  sourceApp.Stop (Seconds (stopTime - 1));
194 
195  sinkHelper.SetAttribute ("Protocol", TypeIdValue (TcpSocketFactory::GetTypeId ()));
196  ApplicationContainer sinkApp = sinkHelper.Install (sink);
197  sinkApp.Start (Seconds (0));
198  sinkApp.Stop (Seconds (stopTime));
199 
200  OnOffHelper clientHelper6 ("ns3::UdpSocketFactory", Address ());
201  clientHelper6.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
202  clientHelper6.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
203  clientHelper6.SetAttribute ("DataRate", DataRateValue (DataRate ("10Mb/s")));
204  clientHelper6.SetAttribute ("PacketSize", UintegerValue (1000));
205 
206  ApplicationContainer clientApps6;
207  clientHelper6.SetAttribute ("Remote", remoteAddress1);
208  clientApps6.Add (clientHelper6.Install (udpSender.Get (0)));
209  clientApps6.Start (Seconds (0));
210  clientApps6.Stop (Seconds (stopTime - 1));
211 
212  OnOffHelper clientHelper7 ("ns3::UdpSocketFactory", Address ());
213  clientHelper7.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
214  clientHelper7.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
215  clientHelper7.SetAttribute ("DataRate", DataRateValue (DataRate ("10Mb/s")));
216  clientHelper7.SetAttribute ("PacketSize", UintegerValue (1000));
217 
218  ApplicationContainer clientApps7;
219  clientHelper7.SetAttribute ("Remote", remoteAddress1);
220  clientApps7.Add (clientHelper7.Install (udpSender.Get (1)));
221  clientApps7.Start (Seconds (0));
222  clientApps7.Stop (Seconds (stopTime - 1));
223 
224  sinkHelper1.SetAttribute ("Protocol", TypeIdValue (UdpSocketFactory::GetTypeId ()));
225  ApplicationContainer sinkApp1 = sinkHelper1.Install (sink);
226  sinkApp1.Start (Seconds (0));
227  sinkApp1.Stop (Seconds (stopTime));
228 
229  Ptr<QueueDisc> queue = queueDiscs.Get (0);
230  Simulator::ScheduleNow (&CheckQueueSize, queue,queue_disc_type);
231 
232  std::string dirToSave = "mkdir -p " + dir + queue_disc_type;
233  if (system ((dirToSave + "/cwndTraces/").c_str ()) == -1
234  || system ((dirToSave + "/queueTraces/").c_str ()) == -1)
235  {
236  exit (1);
237  }
238 
239  Simulator::Schedule (Seconds (0.1), &TraceCwnd,queue_disc_type);
240 
242  Simulator::Run ();
244 }
245 
246 int main (int argc, char **argv)
247 {
248  std::cout << "Simulation with COBALT QueueDisc: Start\n" << std::flush;
249  experiment ("CobaltQueueDisc");
250  std::cout << "Simulation with COBALT QueueDisc: End\n" << std::flush;
251  std::cout << "------------------------------------------------\n";
252  std::cout << "Simulation with CoDel QueueDisc: Start\n";
253  experiment ("CoDelQueueDisc");
254  std::cout << "Simulation with CoDel QueueDisc: End\n";
255 
256  return 0;
257 }
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
static TypeId GetTypeId(void)
Get the type ID.
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:161
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
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
uint32_t GetValue() const
Get the underlying value.
Definition: queue-size.cc:175
NetDeviceContainer Install(NodeContainer c)
void Add(ApplicationContainer other)
Append the contents of another ApplicationContainer to the end of this container. ...
QueueSize GetCurrentSize(void)
Get the current size of the queue disc in bytes, if operating in bytes mode, or packets, otherwise.
Definition: queue-disc.cc:523
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Make Callbacks with one bound argument.
Definition: callback.h:1703
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:380
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
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.
ApplicationContainer Install(NodeContainer c) const
Install an ns3::BulkSendApplication on each node of the input container configured with all the attri...
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&#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.
std::string dir
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
Definition: on-off-helper.h:42
static void TraceCwnd(std::string queue_disc_type)
uint16_t port
Definition: dsdv-manet.cc:45
a polymophic address class
Definition: address.h:90
Holds a vector of ns3::QueueDisc pointers.
void CheckQueueSize(Ptr< QueueDisc > queue, std::string queue_disc_type)
Class for representing data rates.
Definition: data-rate.h:88
ApplicationContainer Install(NodeContainer c) const
Install an ns3::OnOffApplication on each node of the input container configured with all the attribut...
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:588
AttributeValue implementation for Time.
Definition: nstime.h:1353
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
Hold an unsigned integer type.
Definition: uinteger.h:44
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.
Time stopTime
void Start(Time start)
Arrange for all of the Applications in this container to Start() at the Time given as a parameter...
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
Ptr< QueueDisc > Get(std::size_t i) const
Get the Ptr<QueueDisc> stored in this container at a given index.
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
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...
void experiment(std::string queue_disc_type)
AttributeValue implementation for DataRate.
Definition: data-rate.h:298
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:180
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.
void AddInternalQueues(uint16_t handle, uint16_t count, std::string type, Args &&... args)
Helper function used to add the given number of internal queues (of the given type and with the given...
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 SetAttribute(std::string name, const AttributeValue &value)
Helper function used to set the underlying application attributes, not the socket attributes...
devices
Definition: first.py:39
static void CwndTrace(Ptr< OutputStreamWrapper > stream, uint32_t oldCwnd, uint32_t newCwnd)
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
void SetAttribute(std::string name, const AttributeValue &value)
Helper function used to set the underlying application attributes.
void SetAttribute(std::string name, const AttributeValue &value)
Helper function used to set the underlying application attributes.