A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
traffic-control.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2015 Universita' degli Studi di Napoli "Federico II"
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: Pasquale Imputato <p.imputato@gmail.com>
19  * Author: Stefano Avallone <stefano.avallone@unina.it>
20  */
21 
22 #include "ns3/core-module.h"
23 #include "ns3/network-module.h"
24 #include "ns3/internet-module.h"
25 #include "ns3/point-to-point-module.h"
26 #include "ns3/applications-module.h"
27 #include "ns3/traffic-control-module.h"
28 
29 // This simple example shows how to use TrafficControlHelper to install a
30 // QueueDisc on a device.
31 //
32 // The default QueueDisc is a pfifo_fast with max number of packets equal to
33 // 1000 (as in Linux). However, in this example, we change from the default
34 // to instead use a ns3::RedQueueDisc with a MaxPackets value of 10000.
35 //
36 // Network topology
37 //
38 // 10.1.1.0
39 // n0 -------------- n1
40 // point-to-point
41 //
42 // The output will consist of a number of traced changes to queue lengths
43 // such as:
44 //
45 // DevicePacketsInQueue 0 to 1
46 // TcPacketsInQueue 5 to 4
47 // TcPacketsInQueue 4 to 5
48 // DevicePacketsInQueue 1 to 0
49 //
50 // and an average throughput:
51 //
52 // Average throughput: 8.72854 Mbit/s
53 //
54 // The final output displays the number of drops at the TC layer and the
55 // netdevice layer. These statistics highlight the fact that for
56 // PointToPointNetDevice, the drops at the device layer are actually
57 // requeued at the TC layer, so the true packet drops (39 in this case)
58 // must be traced at the TC layer.
59 //
60 // *** Source stats ***
61 // Number of packets dropped by the TC layer: 39
62 // Number of packets dropped by the netdevice: 3914
63 // Number of packets requeued by the TC layer: 3914
64 // Number of actually lost packets: 39
65 //
66 // If one were to increase the size of the PointToPointNetDevice's
67 // DropTailQueue from 1 to a larger number (e.g. 1000), one would observe
68 // that the number of packets dropped would go to zero, but the latency
69 // and QoS would not be controllable. This is the so-called bufferbloat
70 // problem, and illustrates the importance of having a small device queue
71 // so that the standing queues build in the traffic control layer where
72 // they can be managed by advanced queue discs rather than in the
73 // device layer.
74 
75 using namespace ns3;
76 
77 NS_LOG_COMPONENT_DEFINE ("TrafficControlExample");
78 
79 void
80 TcPacketsInQueueTrace (uint32_t oldValue, uint32_t newValue)
81 {
82  std::cout << "TcPacketsInQueue " << oldValue << " to " << newValue << std::endl;
83 }
84 
85 void
86 DevicePacketsInQueueTrace (uint32_t oldValue, uint32_t newValue)
87 {
88  std::cout << "DevicePacketsInQueue " << oldValue << " to " << newValue << std::endl;
89 }
90 
91 int
92 main (int argc, char *argv[])
93 {
94  double simulationTime = 10; //seconds
95  std::string transportProt = "Tcp";
96  std::string socketType;
97 
99  cmd.AddValue ("transportProt", "Transport protocol to use: Tcp, Udp", transportProt);
100  cmd.Parse (argc, argv);
101 
102  if (transportProt.compare ("Tcp") == 0)
103  {
104  socketType = "ns3::TcpSocketFactory";
105  }
106  else
107  {
108  socketType = "ns3::UdpSocketFactory";
109  }
110 
112  nodes.Create (2);
113 
115  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("10Mbps"));
116  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
117  pointToPoint.SetQueue ("ns3::DropTailQueue", "Mode", StringValue ("QUEUE_MODE_PACKETS"), "MaxPackets", UintegerValue (1));
118 
120  devices = pointToPoint.Install (nodes);
121 
123  stack.Install (nodes);
124 
126  uint16_t handle = tch.SetRootQueueDisc ("ns3::RedQueueDisc");
127  // Add the internal queue used by Red
128  tch.AddInternalQueues (handle, 1, "ns3::DropTailQueue", "MaxPackets", UintegerValue (10000));
129  QueueDiscContainer qdiscs = tch.Install (devices);
130 
131  Ptr<QueueDisc> q = qdiscs.Get (1);
133 
134  Ptr<NetDevice> nd = devices.Get (1);
135  Ptr<PointToPointNetDevice> ptpnd = DynamicCast<PointToPointNetDevice> (nd);
136  Ptr<Queue> queue = ptpnd->GetQueue ();
137  queue->TraceConnectWithoutContext ("PacketsInQueue", MakeCallback (&DevicePacketsInQueueTrace));
138 
140  address.SetBase ("10.1.1.0", "255.255.255.0");
141 
142  Ipv4InterfaceContainer interfaces = address.Assign (devices);
143 
144  //Flow
145  uint16_t port = 7;
146  Address localAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
147  PacketSinkHelper packetSinkHelper (socketType, localAddress);
148  ApplicationContainer sinkApp = packetSinkHelper.Install (nodes.Get (0));
149 
150  sinkApp.Start (Seconds (0.0));
151  sinkApp.Stop (Seconds (simulationTime + 0.1));
152 
153  uint32_t payloadSize = 1448;
154  Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (payloadSize));
155 
156  OnOffHelper onoff (socketType, Ipv4Address::GetAny ());
157  onoff.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
158  onoff.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
159  onoff.SetAttribute ("PacketSize", UintegerValue (payloadSize));
160  onoff.SetAttribute ("DataRate", StringValue ("50Mbps")); //bit/s
162 
163  AddressValue remoteAddress (InetSocketAddress (interfaces.GetAddress (0), port));
164  onoff.SetAttribute ("Remote", remoteAddress);
165  apps.Add (onoff.Install (nodes.Get (1)));
166  apps.Start (Seconds (1.0));
167  apps.Stop (Seconds (simulationTime + 0.1));
168 
169  Simulator::Stop (Seconds (simulationTime + 0.1));
170  Simulator::Run ();
172 
173  double thr = 0;
174  uint32_t totalPacketsThr = DynamicCast<PacketSink> (sinkApp.Get (0))->GetTotalRx ();
175  thr = totalPacketsThr * 8 / (simulationTime * 1000000.0); //Mbit/s
176  std::cout << "Average throughput: " << thr << " Mbit/s" <<std::endl;
177  std::cout << "*** Source stats ***" << std::endl;
178  std::cout << "Number of packets dropped by the TC layer: " << q->GetTotalDroppedPackets () << std::endl;
179  std::cout << "Number of packets dropped by the netdevice: " << queue->GetTotalDroppedPackets () << std::endl;
180  std::cout << "Number of packets requeued by the TC layer: " << q->GetTotalRequeuedPackets () << std::endl;
181  std::cout << "Number of actually lost packets: " << q->GetTotalDroppedPackets ()
182  + queue->GetTotalDroppedPackets ()
183  - q->GetTotalRequeuedPackets () << std::endl;
184 
185  return 0;
186 }
holds a vector of ns3::Application pointers.
tuple pointToPoint
Definition: first.py:28
an Inet address class
static Ipv4Address GetAny(void)
Ptr< Queue > GetQueue(void) const
Get a copy of the attached Queue.
QueueDiscContainer Install(NetDeviceContainer c)
tuple devices
Definition: first.py:32
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Hold variables of type string.
Definition: string.h:41
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
NetDeviceContainer Install(NodeContainer c)
void Add(ApplicationContainer other)
Append the contents of another ApplicationContainer to the end of this container. ...
uint32_t GetTotalRequeuedPackets(void) const
Get the total number of requeued packets.
Definition: queue-disc.cc:271
void SetQueue(std::string type, std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue())
Each point to point net device must have a queue to pass packets through.
static void Run(void)
Run the simulation.
Definition: simulator.cc:200
#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.
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes...
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.
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
Definition: on-off-helper.h:42
tuple cmd
Definition: second.py:35
uint16_t port
Definition: dsdv-manet.cc:44
a polymophic address class
Definition: address.h:90
Holds a vector of ns3::QueueDisc pointers.
tuple nodes
Definition: first.py:25
Ptr< QueueDisc > Get(uint32_t i) const
Get the Ptr<QueueDisc> stored in this container at a given index.
Hold an unsigned integer type.
Definition: uinteger.h:44
tuple interfaces
Definition: first.py:41
holds a vector of ns3::NetDevice pointers
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
Build a set of QueueDisc objects.
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:201
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:164
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:299
keep track of a set of node pointers.
Ptr< Application > Get(uint32_t i) const
Get the Ptr<Application> stored in this container at a given index.
uint32_t GetTotalDroppedPackets(void) const
Get the total number of dropped packets.
Definition: queue-disc.cc:257
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...
void TcPacketsInQueueTrace(uint32_t oldValue, uint32_t newValue)
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
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.
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 AddInternalQueues(uint16_t handle, uint16_t count, 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())
Helper function used to add the given number of internal queues (of the given type and with the given...
void AddValue(const std::string &name, const std::string &help, T &value)
Add a program argument, assigning to POD.
Definition: command-line.h:491
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:208
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:774
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 DevicePacketsInQueueTrace(uint32_t oldValue, uint32_t newValue)
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