A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
red-tests.cc
Go to the documentation of this file.
1/*
2 * SPDX-License-Identifier: GPL-2.0-only
3 *
4 * Authors: Marcos Talau <talau@users.sourceforge.net>
5 * Duy Nguyen <duy@soe.ucsc.edu>
6 * Modified by: Pasquale Imputato <p.imputato@gmail.com>
7 *
8 */
9
10/**
11 * These validation tests are detailed in http://icir.org/floyd/papers/redsims.ps
12 *
13 * In this code the tests 1, 3, 4 and 5 refer to the tests corresponding to
14 * Figure 1, 3, 4, and 5 respectively from the document mentioned above.
15 */
16
17/** Network topology
18 *
19 * 10Mb/s, 2ms 10Mb/s, 4ms
20 * n0--------------| |---------------n4
21 * | 1.5Mbps/s, 20ms |
22 * n2------------------n3
23 * 10Mb/s, 3ms | | 10Mb/s, 5ms
24 * n1--------------| |---------------n5
25 *
26 *
27 */
28
29#include "ns3/applications-module.h"
30#include "ns3/core-module.h"
31#include "ns3/flow-monitor-helper.h"
32#include "ns3/internet-module.h"
33#include "ns3/network-module.h"
34#include "ns3/point-to-point-module.h"
35#include "ns3/traffic-control-module.h"
36
37using namespace ns3;
38
39NS_LOG_COMPONENT_DEFINE("RedTests");
40
41uint32_t checkTimes; //!< Number of times the queues have been checked.
42double avgQueueSize; //!< Average Queue size.
43
44// The times
45double global_start_time; //!< Global start time
46double global_stop_time; //!< Global stop time.
47double sink_start_time; //!< Sink start time.
48double sink_stop_time; //!< Sink stop time.
49double client_start_time; //!< Client start time.
50double client_stop_time; //!< Client stop time.
51
52NodeContainer n0n2; //!< Nodecontainer n0 + n2.
53NodeContainer n1n2; //!< Nodecontainer n1 + n2.
54NodeContainer n2n3; //!< Nodecontainer n2 + n3.
55NodeContainer n3n4; //!< Nodecontainer n3 + n4.
56NodeContainer n3n5; //!< Nodecontainer n3 + n5.
57
58Ipv4InterfaceContainer i0i2; //!< IPv4 interface container i0 + i2.
59Ipv4InterfaceContainer i1i2; //!< IPv4 interface container i1 + i2.
60Ipv4InterfaceContainer i2i3; //!< IPv4 interface container i2 + i3.
61Ipv4InterfaceContainer i3i4; //!< IPv4 interface container i3 + i4.
62Ipv4InterfaceContainer i3i5; //!< IPv4 interface container i3 + i5.
63
64std::stringstream filePlotQueue; //!< Output file name for queue size.
65std::stringstream filePlotQueueAvg; //!< Output file name for queue average.
66
67/**
68 * Check the queue size and write its stats to the output files.
69 *
70 * @param queue The queue to check.
71 */
72void
74{
75 uint32_t qSize = queue->GetCurrentSize().GetValue();
76
78 checkTimes++;
79
80 // check queue size every 1/100 of a second
82
83 std::ofstream fPlotQueue(filePlotQueue.str(), std::ios::out | std::ios::app);
84 fPlotQueue << Simulator::Now().GetSeconds() << " " << qSize << std::endl;
85 fPlotQueue.close();
86
87 std::ofstream fPlotQueueAvg(filePlotQueueAvg.str(), std::ios::out | std::ios::app);
88 fPlotQueueAvg << Simulator::Now().GetSeconds() << " " << avgQueueSize / checkTimes << std::endl;
89 fPlotQueueAvg.close();
90}
91
92/**
93 * Setup the apps.
94 *
95 * @param test The test number.
96 */
97void
99{
100 if ((test == 1) || (test == 3))
101 {
102 // SINK is in the right side
103 uint16_t port = 50000;
105 PacketSinkHelper sinkHelper("ns3::TcpSocketFactory", sinkLocalAddress);
109
110 // Connection one
111 // Clients are in left side
112 /*
113 * Create the OnOff applications to send TCP to the server
114 * onoffhelper is a client that send data to TCP destination
115 */
116 OnOffHelper clientHelper1("ns3::TcpSocketFactory", Address());
117 clientHelper1.SetAttribute("OnTime",
118 StringValue("ns3::ConstantRandomVariable[Constant=1]"));
119 clientHelper1.SetAttribute("OffTime",
120 StringValue("ns3::ConstantRandomVariable[Constant=0]"));
121 clientHelper1.SetAttribute("DataRate", DataRateValue(DataRate("10Mb/s")));
122 clientHelper1.SetAttribute("PacketSize", UintegerValue(1000));
123
126 clientHelper1.SetAttribute("Remote", remoteAddress);
127 clientApps1.Add(clientHelper1.Install(n0n2.Get(0)));
130
131 // Connection two
132 OnOffHelper clientHelper2("ns3::TcpSocketFactory", Address());
133 clientHelper2.SetAttribute("OnTime",
134 StringValue("ns3::ConstantRandomVariable[Constant=1]"));
135 clientHelper2.SetAttribute("OffTime",
136 StringValue("ns3::ConstantRandomVariable[Constant=0]"));
137 clientHelper2.SetAttribute("DataRate", DataRateValue(DataRate("10Mb/s")));
138 clientHelper2.SetAttribute("PacketSize", UintegerValue(1000));
139
141 clientHelper2.SetAttribute("Remote", remoteAddress);
142 clientApps2.Add(clientHelper2.Install(n1n2.Get(0)));
143 clientApps2.Start(Seconds(3));
145 }
146 else // 4 or 5
147 {
148 // SINKs
149 // #1
150 uint16_t port1 = 50001;
152 PacketSinkHelper sinkHelper1("ns3::TcpSocketFactory", sinkLocalAddress1);
156 // #2
157 uint16_t port2 = 50002;
159 PacketSinkHelper sinkHelper2("ns3::TcpSocketFactory", sinkLocalAddress2);
163 // #3
164 uint16_t port3 = 50003;
166 PacketSinkHelper sinkHelper3("ns3::TcpSocketFactory", sinkLocalAddress3);
170 // #4
171 uint16_t port4 = 50004;
173 PacketSinkHelper sinkHelper4("ns3::TcpSocketFactory", sinkLocalAddress4);
177
178 // Connection #1
179 /*
180 * Create the OnOff applications to send TCP to the server
181 * onoffhelper is a client that send data to TCP destination
182 */
183 OnOffHelper clientHelper1("ns3::TcpSocketFactory", Address());
184 clientHelper1.SetAttribute("OnTime",
185 StringValue("ns3::ConstantRandomVariable[Constant=1]"));
186 clientHelper1.SetAttribute("OffTime",
187 StringValue("ns3::ConstantRandomVariable[Constant=0]"));
188 clientHelper1.SetAttribute("DataRate", DataRateValue(DataRate("10Mb/s")));
189 clientHelper1.SetAttribute("PacketSize", UintegerValue(1000));
190
193 clientHelper1.SetAttribute("Remote", remoteAddress1);
194 clientApps1.Add(clientHelper1.Install(n0n2.Get(0)));
197
198 // Connection #2
199 OnOffHelper clientHelper2("ns3::TcpSocketFactory", Address());
200 clientHelper2.SetAttribute("OnTime",
201 StringValue("ns3::ConstantRandomVariable[Constant=1]"));
202 clientHelper2.SetAttribute("OffTime",
203 StringValue("ns3::ConstantRandomVariable[Constant=0]"));
204 clientHelper2.SetAttribute("DataRate", DataRateValue(DataRate("10Mb/s")));
205 clientHelper2.SetAttribute("PacketSize", UintegerValue(1000));
206
209 clientHelper2.SetAttribute("Remote", remoteAddress2);
210 clientApps2.Add(clientHelper2.Install(n1n2.Get(0)));
211 clientApps2.Start(Seconds(2));
213
214 // Connection #3
215 OnOffHelper clientHelper3("ns3::TcpSocketFactory", Address());
216 clientHelper3.SetAttribute("OnTime",
217 StringValue("ns3::ConstantRandomVariable[Constant=1]"));
218 clientHelper3.SetAttribute("OffTime",
219 StringValue("ns3::ConstantRandomVariable[Constant=0]"));
220 clientHelper3.SetAttribute("DataRate", DataRateValue(DataRate("10Mb/s")));
221 clientHelper3.SetAttribute("PacketSize", UintegerValue(1000));
222
225 clientHelper3.SetAttribute("Remote", remoteAddress3);
226 clientApps3.Add(clientHelper3.Install(n3n4.Get(1)));
227 clientApps3.Start(Seconds(3.5));
229
230 // Connection #4
231 OnOffHelper clientHelper4("ns3::TcpSocketFactory", Address());
232 clientHelper4.SetAttribute("OnTime",
233 StringValue("ns3::ConstantRandomVariable[Constant=1]"));
234 clientHelper4.SetAttribute("OffTime",
235 StringValue("ns3::ConstantRandomVariable[Constant=0]"));
236 clientHelper4.SetAttribute("DataRate", DataRateValue(DataRate("40b/s")));
237 clientHelper4.SetAttribute("PacketSize", UintegerValue(5 * 8)); // telnet
238
241 clientHelper4.SetAttribute("Remote", remoteAddress4);
242 clientApps4.Add(clientHelper4.Install(n3n5.Get(1)));
243 clientApps4.Start(Seconds(1));
245 }
246}
247
248int
249main(int argc, char* argv[])
250{
251 LogComponentEnable("RedQueueDisc", LOG_LEVEL_INFO);
252
254 std::string redLinkDataRate = "1.5Mbps";
255 std::string redLinkDelay = "20ms";
256
257 std::string pathOut;
258 bool writeForPlot = false;
259 bool writePcap = false;
260 bool flowMonitor = false;
261
262 bool printRedStats = true;
263
264 global_start_time = 0.0;
265 global_stop_time = 11;
270
271 // Configuration and command line parameter parsing
272 redTest = 1;
273 // Will only save in the directory if enable opts below
274 pathOut = "."; // Current directory
276 cmd.AddValue("testNumber", "Run test 1, 3, 4 or 5", redTest);
277 cmd.AddValue("pathOut",
278 "Path to save results from --writeForPlot/--writePcap/--writeFlowMonitor",
279 pathOut);
280 cmd.AddValue("writeForPlot", "Write results for plot (gnuplot)", writeForPlot);
281 cmd.AddValue("writePcap", "Write results in pcapfile", writePcap);
282 cmd.AddValue("writeFlowMonitor", "Enable Flow Monitor and write their results", flowMonitor);
283
284 cmd.Parse(argc, argv);
285 if ((redTest != 1) && (redTest != 3) && (redTest != 4) && (redTest != 5))
286 {
287 NS_ABORT_MSG("Invalid test number. Supported tests are 1, 3, 4 or 5");
288 }
289
290 NS_LOG_INFO("Create nodes");
292 c.Create(6);
293 Names::Add("N0", c.Get(0));
294 Names::Add("N1", c.Get(1));
295 Names::Add("N2", c.Get(2));
296 Names::Add("N3", c.Get(3));
297 Names::Add("N4", c.Get(4));
298 Names::Add("N5", c.Get(5));
299 n0n2 = NodeContainer(c.Get(0), c.Get(2));
300 n1n2 = NodeContainer(c.Get(1), c.Get(2));
301 n2n3 = NodeContainer(c.Get(2), c.Get(3));
302 n3n4 = NodeContainer(c.Get(3), c.Get(4));
303 n3n5 = NodeContainer(c.Get(3), c.Get(5));
304
305 Config::SetDefault("ns3::TcpL4Protocol::SocketType", StringValue("ns3::TcpNewReno"));
306 // 42 = headers size
307 Config::SetDefault("ns3::TcpSocket::SegmentSize", UintegerValue(1000 - 42));
308 Config::SetDefault("ns3::TcpSocket::DelAckCount", UintegerValue(1));
309 GlobalValue::Bind("ChecksumEnabled", BooleanValue(false));
310
311 uint32_t meanPktSize = 500;
312
313 // RED params
314 NS_LOG_INFO("Set RED params");
315 Config::SetDefault("ns3::RedQueueDisc::MaxSize", StringValue("1000p"));
316 Config::SetDefault("ns3::RedQueueDisc::MeanPktSize", UintegerValue(meanPktSize));
317 Config::SetDefault("ns3::RedQueueDisc::Wait", BooleanValue(true));
318 Config::SetDefault("ns3::RedQueueDisc::Gentle", BooleanValue(true));
319 Config::SetDefault("ns3::RedQueueDisc::QW", DoubleValue(0.002));
320 Config::SetDefault("ns3::RedQueueDisc::MinTh", DoubleValue(5));
321 Config::SetDefault("ns3::RedQueueDisc::MaxTh", DoubleValue(15));
322
323 if (redTest == 3) // test like 1, but with bad params
324 {
325 Config::SetDefault("ns3::RedQueueDisc::MaxTh", DoubleValue(10));
326 Config::SetDefault("ns3::RedQueueDisc::QW", DoubleValue(0.003));
327 }
328 else if (redTest == 5) // test 5, same of test 4, but in byte mode
329 {
330 Config::SetDefault("ns3::RedQueueDisc::MaxSize",
331 QueueSizeValue(QueueSize(QueueSizeUnit::BYTES, 1000 * meanPktSize)));
332 Config::SetDefault("ns3::RedQueueDisc::Ns1Compat", BooleanValue(true));
333 Config::SetDefault("ns3::RedQueueDisc::MinTh", DoubleValue(5 * meanPktSize));
334 Config::SetDefault("ns3::RedQueueDisc::MaxTh", DoubleValue(15 * meanPktSize));
335 }
336
337 NS_LOG_INFO("Install internet stack on all nodes.");
339 internet.Install(c);
340
342 uint16_t handle = tchPfifo.SetRootQueueDisc("ns3::PfifoFastQueueDisc");
343 tchPfifo.AddInternalQueues(handle, 3, "ns3::DropTailQueue", "MaxSize", StringValue("1000p"));
344
346 tchRed.SetRootQueueDisc("ns3::RedQueueDisc",
347 "LinkBandwidth",
349 "LinkDelay",
351
352 NS_LOG_INFO("Create channels");
354
355 p2p.SetQueue("ns3::DropTailQueue");
356 p2p.SetDeviceAttribute("DataRate", StringValue("10Mbps"));
357 p2p.SetChannelAttribute("Delay", StringValue("2ms"));
359 tchPfifo.Install(devn0n2);
360
361 p2p.SetQueue("ns3::DropTailQueue");
362 p2p.SetDeviceAttribute("DataRate", StringValue("10Mbps"));
363 p2p.SetChannelAttribute("Delay", StringValue("3ms"));
365 tchPfifo.Install(devn1n2);
366
367 p2p.SetQueue("ns3::DropTailQueue");
368 p2p.SetDeviceAttribute("DataRate", StringValue(redLinkDataRate));
369 p2p.SetChannelAttribute("Delay", StringValue(redLinkDelay));
371 // only backbone link has RED queue disc
373
374 p2p.SetQueue("ns3::DropTailQueue");
375 p2p.SetDeviceAttribute("DataRate", StringValue("10Mbps"));
376 p2p.SetChannelAttribute("Delay", StringValue("4ms"));
378 tchPfifo.Install(devn3n4);
379
380 p2p.SetQueue("ns3::DropTailQueue");
381 p2p.SetDeviceAttribute("DataRate", StringValue("10Mbps"));
382 p2p.SetChannelAttribute("Delay", StringValue("5ms"));
384 tchPfifo.Install(devn3n5);
385
386 NS_LOG_INFO("Assign IP Addresses");
388
389 ipv4.SetBase("10.1.1.0", "255.255.255.0");
390 i0i2 = ipv4.Assign(devn0n2);
391
392 ipv4.SetBase("10.1.2.0", "255.255.255.0");
393 i1i2 = ipv4.Assign(devn1n2);
394
395 ipv4.SetBase("10.1.3.0", "255.255.255.0");
396 i2i3 = ipv4.Assign(devn2n3);
397
398 ipv4.SetBase("10.1.4.0", "255.255.255.0");
399 i3i4 = ipv4.Assign(devn3n4);
400
401 ipv4.SetBase("10.1.5.0", "255.255.255.0");
402 i3i5 = ipv4.Assign(devn3n5);
403
404 // Set up the routing
406
407 if (redTest == 5)
408 {
409 // like in ns2 test, r2 -> r1, have a queue in packet mode
410 Ptr<QueueDisc> queue = queueDiscs.Get(1);
411
412 queue->SetMaxSize(QueueSize("1000p"));
413 StaticCast<RedQueueDisc>(queue)->SetTh(5, 15);
414 }
415
417
418 if (writePcap)
419 {
421 std::stringstream stmp;
422 stmp << pathOut << "/red";
423 ptp.EnablePcapAll(stmp.str());
424 }
425
427 if (flowMonitor)
428 {
431 }
432
433 if (writeForPlot)
434 {
435 filePlotQueue << pathOut << "/"
436 << "red-queue.plotme";
437 filePlotQueueAvg << pathOut << "/"
438 << "red-queue_avg.plotme";
439
440 remove(filePlotQueue.str().c_str());
441 remove(filePlotQueueAvg.str().c_str());
442 Ptr<QueueDisc> queue = queueDiscs.Get(0);
444 }
445
448
449 if (flowMonitor)
450 {
451 std::stringstream stmp;
452 stmp << pathOut << "/red.flowmon";
453
454 flowmon->SerializeToXmlFile(stmp.str(), false, false);
455 }
456
457 if (printRedStats)
458 {
459 QueueDisc::Stats st = queueDiscs.Get(0)->GetStats();
460 std::cout << "*** RED stats from Node 2 queue disc ***" << std::endl;
461 std::cout << st << std::endl;
462
463 st = queueDiscs.Get(1)->GetStats();
464 std::cout << "*** RED stats from Node 3 queue disc ***" << std::endl;
465 std::cout << st << std::endl;
466 }
467
469
470 return 0;
471}
a polymophic address class
Definition address.h:90
AttributeValue implementation for Address.
Definition address.h:275
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 Add(ApplicationContainer other)
Append the contents of another ApplicationContainer to the end of this container.
AttributeValue implementation for Boolean.
Definition boolean.h:26
Parse command-line arguments.
Class for representing data rates.
Definition data-rate.h:78
AttributeValue implementation for DataRate.
Definition data-rate.h:285
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
Helper to enable IP flow monitoring on a set of Nodes.
Ptr< FlowMonitor > InstallAll()
Enable flow monitoring on all nodes.
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.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
static void Add(std::string name, Ptr< Object > object)
Add the association between the string "name" and the Ptr<Object> obj.
Definition names.cc:764
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.
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
void EnablePcapAll(std::string prefix, bool promiscuous=false)
Enable pcap output on each device (which is of the appropriate type) in the set of all nodes created ...
Build a set of PointToPointNetDevice objects.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
Holds a vector of ns3::QueueDisc pointers.
Class for representing queue sizes.
Definition queue-size.h:85
AttributeValue implementation for QueueSize.
Definition queue-size.h:210
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static void Run()
Run the simulation.
Definition simulator.cc:167
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:594
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
Hold variables of type string.
Definition string.h:45
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:392
Build a set of QueueDisc objects.
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:34
uint16_t port
Definition dsdv-manet.cc:33
std::ofstream fPlotQueue
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:883
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
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:291
@ LOG_LEVEL_INFO
LOG_INFO and above.
Definition log.h:93
-ns3 Test suite for the ns3 wrapper script
void BuildAppsTest()
Ipv4InterfaceContainer i0i2
IPv4 interface container i0 + i2.
Definition red-tests.cc:58
double client_start_time
Client start time.
Definition red-tests.cc:49
double sink_stop_time
Sink stop time.
Definition red-tests.cc:48
double sink_start_time
Sink start time.
Definition red-tests.cc:47
double global_stop_time
Global stop time.
Definition red-tests.cc:46
NodeContainer n2n3
Nodecontainer n2 + n3.
Definition red-tests.cc:54
double avgQueueSize
Average Queue size.
Definition red-tests.cc:42
NodeContainer n1n2
Nodecontainer n1 + n2.
Definition red-tests.cc:53
NodeContainer n3n4
Nodecontainer n3 + n4.
Definition red-tests.cc:55
std::stringstream filePlotQueueAvg
Output file name for queue average.
Definition red-tests.cc:65
void CheckQueueSize(Ptr< QueueDisc > queue)
Check the queue size and write its stats to the output files.
Definition red-tests.cc:73
std::stringstream filePlotQueue
Output file name for queue size.
Definition red-tests.cc:64
double global_start_time
Global start time.
Definition red-tests.cc:45
Ipv4InterfaceContainer i1i2
IPv4 interface container i1 + i2.
Definition red-tests.cc:59
Ipv4InterfaceContainer i3i4
IPv4 interface container i3 + i4.
Definition red-tests.cc:61
NodeContainer n0n2
Nodecontainer n0 + n2.
Definition red-tests.cc:52
double client_stop_time
Client stop time.
Definition red-tests.cc:50
uint32_t checkTimes
Number of times the queues have been checked.
Definition red-tests.cc:41
NodeContainer n3n5
Nodecontainer n3 + n5.
Definition red-tests.cc:56
Ipv4InterfaceContainer i3i5
IPv4 interface container i3 + i5.
Definition red-tests.cc:62
Ipv4InterfaceContainer i2i3
IPv4 interface container i2 + i3.
Definition red-tests.cc:60
Structure that keeps the queue disc statistics.
Definition queue-disc.h:177