A Discrete-Event Network Simulator
QKDNetSim v2.0 (NS-3 v3.41) @ (+)
API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
tcp-linux-reno.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 NITK Surathkal
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  * Authors: Apoorva Bhargava <apoorvabhargava13@gmail.com>
18  */
19 
20 // Network topology
21 //
22 // n0 ---------- n1 ---------- n2 ---------- n3
23 // 10 Mbps 1 Mbps 10 Mbps
24 // 1 ms 10 ms 1 ms
25 //
26 // - TCP flow from n0 to n3 using BulkSendApplication.
27 // - The following simulation output is stored in results/ in ns-3 top-level directory:
28 // - cwnd traces are stored in cwndTraces folder
29 // - queue length statistics are stored in queue-size.dat file
30 // - pcaps are stored in pcap folder
31 // - queueTraces folder contain the drop statistics at queue
32 // - queueStats.txt file contains the queue stats and config.txt file contains
33 // the simulation configuration.
34 // - The cwnd and queue length traces obtained from this example were tested against
35 // the respective traces obtained from Linux Reno by using ns-3 Direct Code Execution.
36 // See internet/doc/tcp.rst for more details.
37 
38 #include "ns3/applications-module.h"
39 #include "ns3/core-module.h"
40 #include "ns3/internet-module.h"
41 #include "ns3/network-module.h"
42 #include "ns3/point-to-point-module.h"
43 #include "ns3/traffic-control-module.h"
44 
45 #include <fstream>
46 #include <iostream>
47 #include <string>
48 #include <sys/stat.h>
49 
50 using namespace ns3;
51 std::string dir = "results/";
53 uint32_t segmentSize = 524;
54 
55 std::ofstream fPlotQueue;
56 std::ofstream fPlotCwnd;
57 
58 // Function to check queue length of Router 1
59 void
61 {
62  uint32_t qSize = queue->GetCurrentSize().GetValue();
63 
64  // Check queue size every 1/100 of a second
66  fPlotQueue << Simulator::Now().GetSeconds() << " " << qSize << std::endl;
67 }
68 
69 // Function to trace change in cwnd at n0
70 static void
71 CwndChange(uint32_t oldCwnd, uint32_t newCwnd)
72 {
73  fPlotCwnd << Simulator::Now().GetSeconds() << " " << newCwnd / segmentSize << std::endl;
74 }
75 
76 // Function to calculate drops in a particular Queue
77 static void
79 {
80  *stream->GetStream() << Simulator::Now().GetSeconds() << " 1" << std::endl;
81 }
82 
83 // Trace Function for cwnd
84 void
85 TraceCwnd(uint32_t node, uint32_t cwndWindow, Callback<void, uint32_t, uint32_t> CwndTrace)
86 {
87  Config::ConnectWithoutContext("/NodeList/" + std::to_string(node) +
88  "/$ns3::TcpL4Protocol/SocketList/" +
89  std::to_string(cwndWindow) + "/CongestionWindow",
90  CwndTrace);
91 }
92 
93 // Function to install BulkSend application
94 void
97  uint16_t port,
98  std::string socketFactory,
99  uint32_t nodeId,
100  uint32_t cwndWindow,
102 {
103  BulkSendHelper source(socketFactory, InetSocketAddress(address, port));
104  source.SetAttribute("MaxBytes", UintegerValue(0));
105  ApplicationContainer sourceApps = source.Install(node);
106  sourceApps.Start(Seconds(10.0));
107  Simulator::Schedule(Seconds(10.0) + Seconds(0.001), &TraceCwnd, nodeId, cwndWindow, CwndTrace);
108  sourceApps.Stop(stopTime);
109 }
110 
111 // Function to install sink application
112 void
113 InstallPacketSink(Ptr<Node> node, uint16_t port, std::string socketFactory)
114 {
116  ApplicationContainer sinkApps = sink.Install(node);
117  sinkApps.Start(Seconds(10.0));
118  sinkApps.Stop(stopTime);
119 }
120 
121 int
122 main(int argc, char* argv[])
123 {
124  uint32_t stream = 1;
125  std::string socketFactory = "ns3::TcpSocketFactory";
126  std::string tcpTypeId = "ns3::TcpLinuxReno";
127  std::string qdiscTypeId = "ns3::FifoQueueDisc";
128  bool isSack = true;
129  uint32_t delAckCount = 1;
130  std::string recovery = "ns3::TcpClassicRecovery";
131 
133  cmd.AddValue("tcpTypeId",
134  "TCP variant to use (e.g., ns3::TcpNewReno, ns3::TcpLinuxReno, etc.)",
135  tcpTypeId);
136  cmd.AddValue("qdiscTypeId", "Queue disc for gateway (e.g., ns3::CoDelQueueDisc)", qdiscTypeId);
137  cmd.AddValue("segmentSize", "TCP segment size (bytes)", segmentSize);
138  cmd.AddValue("delAckCount", "Delayed ack count", delAckCount);
139  cmd.AddValue("enableSack", "Flag to enable/disable sack in TCP", isSack);
140  cmd.AddValue("stopTime",
141  "Stop time for applications / simulation time will be stopTime",
142  stopTime);
143  cmd.AddValue("recovery", "Recovery algorithm type to use (e.g., ns3::TcpPrrRecovery", recovery);
144  cmd.Parse(argc, argv);
145 
146  TypeId qdTid;
148  "TypeId " << qdiscTypeId << " not found");
149 
150  // Set recovery algorithm and TCP variant
151  Config::SetDefault("ns3::TcpL4Protocol::RecoveryType",
152  TypeIdValue(TypeId::LookupByName(recovery)));
153  TypeId tcpTid;
155  "TypeId " << tcpTypeId << " not found");
156  Config::SetDefault("ns3::TcpL4Protocol::SocketType",
157  TypeIdValue(TypeId::LookupByName(tcpTypeId)));
158 
159  // Create nodes
160  NodeContainer leftNodes;
161  NodeContainer rightNodes;
162  NodeContainer routers;
163  routers.Create(2);
164  leftNodes.Create(1);
165  rightNodes.Create(1);
166 
167  std::vector<NetDeviceContainer> leftToRouter;
168  std::vector<NetDeviceContainer> routerToRight;
169 
170  // Create the point-to-point link helpers and connect two router nodes
171  PointToPointHelper pointToPointRouter;
172  pointToPointRouter.SetDeviceAttribute("DataRate", StringValue("1Mbps"));
173  pointToPointRouter.SetChannelAttribute("Delay", StringValue("10ms"));
174  NetDeviceContainer r1r2ND = pointToPointRouter.Install(routers.Get(0), routers.Get(1));
175 
176  // Create the point-to-point link helpers and connect leaf nodes to router
177  PointToPointHelper pointToPointLeaf;
178  pointToPointLeaf.SetDeviceAttribute("DataRate", StringValue("10Mbps"));
179  pointToPointLeaf.SetChannelAttribute("Delay", StringValue("1ms"));
180  leftToRouter.push_back(pointToPointLeaf.Install(leftNodes.Get(0), routers.Get(0)));
181  routerToRight.push_back(pointToPointLeaf.Install(routers.Get(1), rightNodes.Get(0)));
182 
183  InternetStackHelper internetStack;
184 
185  internetStack.Install(leftNodes);
186  internetStack.Install(rightNodes);
187  internetStack.Install(routers);
188 
189  // Assign IP addresses to all the network devices
190  Ipv4AddressHelper ipAddresses("10.0.0.0", "255.255.255.0");
191 
192  Ipv4InterfaceContainer r1r2IPAddress = ipAddresses.Assign(r1r2ND);
193  ipAddresses.NewNetwork();
194 
195  std::vector<Ipv4InterfaceContainer> leftToRouterIPAddress;
196  leftToRouterIPAddress.push_back(ipAddresses.Assign(leftToRouter[0]));
197  ipAddresses.NewNetwork();
198 
199  std::vector<Ipv4InterfaceContainer> routerToRightIPAddress;
200  routerToRightIPAddress.push_back(ipAddresses.Assign(routerToRight[0]));
201 
203 
204  // Set default sender and receiver buffer size as 1MB
205  Config::SetDefault("ns3::TcpSocket::SndBufSize", UintegerValue(1 << 20));
206  Config::SetDefault("ns3::TcpSocket::RcvBufSize", UintegerValue(1 << 20));
207 
208  // Set default initial congestion window as 10 segments
209  Config::SetDefault("ns3::TcpSocket::InitialCwnd", UintegerValue(10));
210 
211  // Set default delayed ack count to a specified value
212  Config::SetDefault("ns3::TcpSocket::DelAckCount", UintegerValue(delAckCount));
213 
214  // Set default segment size of TCP packet to a specified value
215  Config::SetDefault("ns3::TcpSocket::SegmentSize", UintegerValue(segmentSize));
216 
217  // Enable/Disable SACK in TCP
218  Config::SetDefault("ns3::TcpSocketBase::Sack", BooleanValue(isSack));
219 
220  // Create directories to store dat files
221  struct stat buffer;
222  int retVal [[maybe_unused]];
223  if ((stat(dir.c_str(), &buffer)) == 0)
224  {
225  std::string dirToRemove = "rm -rf " + dir;
226  retVal = system(dirToRemove.c_str());
227  NS_ASSERT_MSG(retVal == 0, "Error in return value");
228  }
229 
231  SystemPath::MakeDirectories(dir + "/pcap/");
232  SystemPath::MakeDirectories(dir + "/queueTraces/");
233  SystemPath::MakeDirectories(dir + "/cwndTraces/");
234 
235  // Set default parameters for queue discipline
236  Config::SetDefault(qdiscTypeId + "::MaxSize", QueueSizeValue(QueueSize("100p")));
237 
238  // Install queue discipline on router
240  tch.SetRootQueueDisc(qdiscTypeId);
242  tch.Uninstall(routers.Get(0)->GetDevice(0));
243  qd.Add(tch.Install(routers.Get(0)->GetDevice(0)).Get(0));
244 
245  // Enable BQL
246  tch.SetQueueLimits("ns3::DynamicQueueLimits");
247 
248  // Open files for writing queue size and cwnd traces
249  fPlotQueue.open(dir + "queue-size.dat", std::ios::out);
250  fPlotCwnd.open(dir + "cwndTraces/n0.dat", std::ios::out);
251 
252  // Calls function to check queue size
254 
255  AsciiTraceHelper asciiTraceHelper;
256  Ptr<OutputStreamWrapper> streamWrapper;
257 
258  // Create dat to store packets dropped and marked at the router
259  streamWrapper = asciiTraceHelper.CreateFileStream(dir + "/queueTraces/drop-0.dat");
260  qd.Get(0)->TraceConnectWithoutContext("Drop", MakeBoundCallback(&DropAtQueue, streamWrapper));
261 
262  // Install packet sink at receiver side
263  uint16_t port = 50000;
264  InstallPacketSink(rightNodes.Get(0), port, "ns3::TcpSocketFactory");
265 
266  // Install BulkSend application
267  InstallBulkSend(leftNodes.Get(0),
268  routerToRightIPAddress[0].GetAddress(1),
269  port,
270  socketFactory,
271  2,
272  0,
274 
275  // Enable PCAP on all the point to point interfaces
276  pointToPointLeaf.EnablePcapAll(dir + "pcap/ns-3", true);
277 
279  Simulator::Run();
280 
281  // Store queue stats in a file
282  std::ofstream myfile;
283  myfile.open(dir + "queueStats.txt", std::fstream::in | std::fstream::out | std::fstream::app);
284  myfile << std::endl;
285  myfile << "Stat for Queue 1";
286  myfile << qd.Get(0)->GetStats();
287  myfile.close();
288 
289  // Store configuration of the simulation in a file
290  myfile.open(dir + "config.txt", std::fstream::in | std::fstream::out | std::fstream::app);
291  myfile << "qdiscTypeId " << qdiscTypeId << "\n";
292  myfile << "stream " << stream << "\n";
293  myfile << "segmentSize " << segmentSize << "\n";
294  myfile << "delAckCount " << delAckCount << "\n";
295  myfile << "stopTime " << stopTime.As(Time::S) << "\n";
296  myfile.close();
297 
299 
300  fPlotQueue.close();
301  fPlotCwnd.close();
302 
303  return 0;
304 }
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.
void SetAttribute(std::string name, const AttributeValue &value)
Helper function used to set the underlying application attributes, not the socket attributes.
ApplicationContainer Install(NodeContainer c) const
Install an ns3::BulkSendApplication on each node of the input container configured with all the attri...
Callback template class.
Definition: callback.h:438
Parse command-line arguments.
Definition: command-line.h:232
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
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.
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.
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:152
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:315
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 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.
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)
Holds a vector of ns3::QueueDisc pointers.
void Add(QueueDiscContainer other)
Append the contents of another QueueDiscContainer to the end of this container.
Ptr< QueueDisc > Get(std::size_t i) const
Get the Ptr<QueueDisc> stored in this container at a given index.
QueueSize GetCurrentSize() const
Get the current size of the queue disc in bytes, if operating in bytes mode, or packets,...
Definition: queue-disc.cc:515
const Stats & GetStats()
Retrieve all the collected statistics.
Definition: queue-disc.cc:412
Class for representing queue sizes.
Definition: queue-size.h:96
uint32_t GetValue() const
Get the underlying value.
Definition: queue-size.cc:183
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 Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static void Run()
Run the simulation.
Definition: simulator.cc:178
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:605
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
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
@ S
second
Definition: nstime.h:116
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.
void SetQueueLimits(std::string type, Args &&... args)
Helper function used to add a queue limits object to the transmission queues of the devices.
void Uninstall(NetDeviceContainer c)
a unique identifier for an interface.
Definition: type-id.h:59
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition: type-id.cc:835
static bool LookupByNameFailSafe(std::string name, TypeId *tid)
Get a TypeId by name.
Definition: type-id.cc:844
Hold an unsigned integer type.
Definition: uinteger.h:45
static void CwndTrace(Ptr< OutputStreamWrapper > stream, uint32_t oldCwnd, uint32_t newCwnd)
uint16_t port
Definition: dsdv-manet.cc:44
void InstallBulkSend(Ptr< Node > node, Ipv4Address address, uint16_t port, std::string socketFactory, uint32_t nodeId, uint32_t cwndWindow, Callback< void, uint32_t, uint32_t > CwndTrace)
void TraceCwnd(uint32_t node, uint32_t cwndWindow, Callback< void, uint32_t, uint32_t > CwndTrace)
uint32_t segmentSize
void InstallPacketSink(Ptr< Node > node, uint16_t port, std::string socketFactory)
std::ofstream fPlotCwnd
static void DropAtQueue(Ptr< OutputStreamWrapper > stream, Ptr< const QueueDiscItem > item)
void CheckQueueSize(Ptr< QueueDisc > queue)
Time stopTime
std::ofstream fPlotQueue
static void CwndChange(uint32_t oldCwnd, uint32_t newCwnd)
std::string dir
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
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_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Definition: callback.h:765
void MakeDirectories(std::string path)
Create all the directories leading to path.
Definition: system-path.cc:350
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
address
Definition: first.py:47
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.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
cmd
Definition: second.py:40
Ptr< PacketSink > sink
Pointer to the packet sink application.
Definition: wifi-tcp.cc:55