examples for CoDel queue
This commit is contained in:
435
src/internet/examples/codel-vs-droptail-asymmetric.cc
Normal file
435
src/internet/examples/codel-vs-droptail-asymmetric.cc
Normal file
@@ -0,0 +1,435 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014 ResiliNets, ITTC, University of Kansas
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Truc Anh N Nguyen <trucanh524@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is an example that compares CoDel and DropTail queues using a
|
||||
* typical cable modem topology and delay
|
||||
* (total RTT 37 ms as measured by Measuring Broadband America)
|
||||
*
|
||||
* 10gigE 22 Mb/s gigE
|
||||
* 15 ms 1 ms 0.1 ms
|
||||
* -------- ------- (1) -------- -------
|
||||
* | |------>| |------>| |------->| |
|
||||
* |server| |CMTS | |Router| |Host |
|
||||
* | |<------| |<------| |<-------| |
|
||||
* -------- -------- (2)-------- -------
|
||||
* 10gigE 5 Mb/s gigE
|
||||
* 15 ms 6 ms 0.1 ms
|
||||
* -----------------
|
||||
* (1) DropTail queue , 256K bytes
|
||||
* (2) DropTail, CoDel, FqCoDel, SfqCoDel, etc.
|
||||
*
|
||||
* The server initiates a bulk send TCP transfer to the host.
|
||||
* The host initiates a bulk send TCP transfer to the server.
|
||||
* Also, isochronous traffic (VoIP-like) between server and host
|
||||
* The default TCP version in ns-3, TcpNewReno, is used as the transport-layer
|
||||
* protocol.
|
||||
* Packets transmitted during a simulation run are captured into a .pcap file,
|
||||
* and congestion window values are also traced.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/network-module.h"
|
||||
#include "ns3/internet-module.h"
|
||||
#include "ns3/point-to-point-module.h"
|
||||
#include "ns3/applications-module.h"
|
||||
#include "ns3/config-store-module.h"
|
||||
#include "ns3/error-model.h"
|
||||
#include "ns3/tcp-header.h"
|
||||
#include "ns3/udp-header.h"
|
||||
#include "ns3/enum.h"
|
||||
#include "ns3/event-id.h"
|
||||
#include "ns3/ipv4-global-routing-helper.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("CoDelDropTailAsymmetricTest");
|
||||
|
||||
static void
|
||||
CwndTracer (Ptr<OutputStreamWrapper>stream, uint32_t oldval, uint32_t newval)
|
||||
{
|
||||
*stream->GetStream () << oldval << " " << newval << std::endl;
|
||||
}
|
||||
|
||||
static void
|
||||
TraceCwnd (std::string cwndTrFileName)
|
||||
{
|
||||
AsciiTraceHelper ascii;
|
||||
if (cwndTrFileName.compare ("") == 0)
|
||||
{
|
||||
NS_LOG_DEBUG ("No trace file for cwnd provided");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream (cwndTrFileName.c_str ());
|
||||
Config::ConnectWithoutContext ("/NodeList/0/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow",MakeBoundCallback (&CwndTracer, stream));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SojournTracer (Ptr<OutputStreamWrapper>stream, Time oldval, Time newval)
|
||||
{
|
||||
*stream->GetStream () << oldval << " " << newval << std::endl;
|
||||
}
|
||||
|
||||
static void
|
||||
TraceSojourn (std::string sojournTrFileName)
|
||||
{
|
||||
AsciiTraceHelper ascii;
|
||||
if (sojournTrFileName.compare ("") == 0)
|
||||
{
|
||||
NS_LOG_DEBUG ("No trace file for sojourn provided");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream (sojournTrFileName.c_str ());
|
||||
Config::ConnectWithoutContext ("/NodeList/2/DeviceList/1/$ns3::PointToPointNetDevice/TxQueue/$ns3::CoDelQueue/Sojourn", MakeBoundCallback (&SojournTracer, stream));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
QueueLengthTracer (Ptr<OutputStreamWrapper>stream, uint32_t oldval, uint32_t newval)
|
||||
{
|
||||
*stream->GetStream () << oldval << " " << newval << std::endl;
|
||||
}
|
||||
|
||||
static void
|
||||
TraceQueueLength (std::string queueLengthTrFileName)
|
||||
{
|
||||
AsciiTraceHelper ascii;
|
||||
if (queueLengthTrFileName.compare ("") == 0)
|
||||
{
|
||||
NS_LOG_DEBUG ("No trace file for queue length provided");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream (queueLengthTrFileName.c_str ());
|
||||
Config::ConnectWithoutContext ("/NodeList/2/DeviceList/1/$ns3::PointToPointNetDevice/TxQueue/$ns3::CoDelQueue/BytesInQueue", MakeBoundCallback (&QueueLengthTracer, stream));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
EveryDropTracer (Ptr<OutputStreamWrapper>stream, Ptr<const Packet> p)
|
||||
{
|
||||
*stream->GetStream () << Simulator::Now ().GetSeconds () << " " << p << std::endl;
|
||||
}
|
||||
|
||||
static void
|
||||
TraceEveryDrop (std::string everyDropTrFileName)
|
||||
{
|
||||
AsciiTraceHelper ascii;
|
||||
if (everyDropTrFileName.compare ("") == 0)
|
||||
{
|
||||
NS_LOG_DEBUG ("No trace file for every drop event provided");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream (everyDropTrFileName.c_str ());
|
||||
Config::ConnectWithoutContext ("/NodeList/2/DeviceList/1/$ns3::PointToPointNetDevice/TxQueue/Drop", MakeBoundCallback (&EveryDropTracer, stream));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
DroppingStateTracer (Ptr<OutputStreamWrapper>stream, bool oldVal, bool newVal)
|
||||
{
|
||||
if (oldVal == false && newVal == true)
|
||||
{
|
||||
NS_LOG_INFO ("Entering the dropping state");
|
||||
*stream->GetStream () << Simulator::Now ().GetSeconds () << " ";
|
||||
}
|
||||
else if (oldVal == true && newVal == false)
|
||||
{
|
||||
NS_LOG_INFO ("Leaving the dropping state");
|
||||
*stream->GetStream () << Simulator::Now ().GetSeconds () << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
TraceDroppingState (std::string dropStateTrFileName)
|
||||
{
|
||||
AsciiTraceHelper ascii;
|
||||
if (dropStateTrFileName.compare ("") == 0)
|
||||
{
|
||||
NS_LOG_DEBUG ("No trace file for dropping state provided");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream (dropStateTrFileName.c_str ());
|
||||
Config::ConnectWithoutContext ("/NodeList/2/DeviceList/1/$ns3::PointToPointNetDevice/TxQueue/$ns3::CoDelQueue/DropState", MakeBoundCallback (&DroppingStateTracer, stream));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CreateBulkFlow (AddressValue remoteAddress, Ptr<Node> sender, uint32_t pktSize, float stopTime)
|
||||
{
|
||||
BulkSendHelper sourceHelper ("ns3::TcpSocketFactory", Address ());
|
||||
sourceHelper.SetAttribute ("Remote", remoteAddress);
|
||||
sourceHelper.SetAttribute ("SendSize", UintegerValue (pktSize));
|
||||
sourceHelper.SetAttribute ("MaxBytes", UintegerValue (0));
|
||||
ApplicationContainer sourceApp = sourceHelper.Install (sender);
|
||||
sourceApp.Start (Seconds (0));
|
||||
sourceApp.Stop (Seconds (stopTime - 3));
|
||||
}
|
||||
|
||||
void
|
||||
CreateOnOffFlow (AddressValue remoteAddress, Ptr<Node> sender, float stopTime)
|
||||
{
|
||||
OnOffHelper sourceHelper ("ns3::UdpSocketFactory", Address ());
|
||||
sourceHelper.SetAttribute ("PacketSize", UintegerValue (280));
|
||||
sourceHelper.SetAttribute ("Remote", remoteAddress);
|
||||
ApplicationContainer sourceApp = sourceHelper.Install (sender);
|
||||
sourceApp.Start (Seconds (0));
|
||||
sourceApp.Stop (Seconds (stopTime - 3));
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
std::string serverCmtsDelay = "15ms";
|
||||
std::string cmtsRouterDelay = "6ms";
|
||||
std::string routerHostDelay = "0.1ms";
|
||||
std::string serverLanDataRate = "10Gbps";
|
||||
std::string cmtsLanDataRate = "10Gbps";
|
||||
std::string cmtsWanDataRate = "22Mbps";
|
||||
std::string routerWanDataRate = "5Mbps";
|
||||
std::string routerLanDataRate = "10Gbps";
|
||||
std::string hostLanDataRate = "10Gbps";
|
||||
|
||||
std::string routerWanQueueType = "CoDel"; // outbound cable router queue
|
||||
uint32_t pktSize = 1458; // in bytes. 1458 to prevent fragments
|
||||
uint32_t queueSize = 1000; // in packets
|
||||
uint32_t numOfUpLoadBulkFlows = 1; // # of upload bulk transfer flows
|
||||
uint32_t numOfDownLoadBulkFlows = 1; // # of download bulk transfer flows
|
||||
uint32_t numOfUpLoadOnOffFlows = 1; // # of upload onoff flows
|
||||
uint32_t numOfDownLoadOnOffFlows = 1; // # of download onoff flows
|
||||
bool isPcapEnabled = true;
|
||||
|
||||
float startTime = 0.1;
|
||||
float simDuration = 60; //in seconds
|
||||
|
||||
std::string fileNamePrefix = "codel-vs-droptail-asymmetric";
|
||||
bool logging = true;
|
||||
|
||||
CommandLine cmd;
|
||||
cmd.AddValue ("serverCmtsDelay", "Link delay between server and CMTS", serverCmtsDelay);
|
||||
cmd.AddValue ("cmtsRouterDelay", "Link delay between CMTS and rounter", cmtsRouterDelay);
|
||||
cmd.AddValue ("routerHostDelay", "Link delay between router and host", routerHostDelay);
|
||||
cmd.AddValue ("serverLanDataRate", "Server LAN net device data rate", serverLanDataRate);
|
||||
cmd.AddValue ("cmtsLanDataRate", "CMTS LAN net device data rate", cmtsLanDataRate);
|
||||
cmd.AddValue ("cmtsWanDataRate", "CMTS WAN net device data rate", cmtsWanDataRate);
|
||||
cmd.AddValue ("routerWanDataRate", "Router WAN net device data rate", routerWanDataRate);
|
||||
cmd.AddValue ("routerLanDataRate", "Router LAN net device data rate", routerLanDataRate);
|
||||
cmd.AddValue ("hostLanDataRate", "Host LAN net device data rate", hostLanDataRate);
|
||||
cmd.AddValue ("routerWanQueueType", "Router WAN net device queue type", routerWanQueueType);
|
||||
cmd.AddValue ("queueSize", "Queue size in packets", queueSize);
|
||||
cmd.AddValue ("pktSize", "Packet size in bytes", pktSize);
|
||||
cmd.AddValue ("numOfUpLoadBulkFlows", "Number of upload bulk transfer flows", numOfUpLoadBulkFlows);
|
||||
cmd.AddValue ("numOfDownLoadBulkFlows", "Number of download bulk transfer flows", numOfDownLoadBulkFlows);
|
||||
cmd.AddValue ("numOfUpLoadOnOffFlows", "Number of upload OnOff flows", numOfUpLoadOnOffFlows);
|
||||
cmd.AddValue ("numOfDownLoadOnOffFlows", "Number of download OnOff flows", numOfDownLoadOnOffFlows);
|
||||
cmd.AddValue ("startTime", "Simulation start time", startTime);
|
||||
cmd.AddValue ("simDuration", "Simulation duration in seconds", simDuration);
|
||||
cmd.AddValue ("isPcapEnabled", "Flag to enable/disable pcap", isPcapEnabled);
|
||||
cmd.AddValue ("logging", "Flag to enable/disable logging", logging);
|
||||
cmd.Parse (argc, argv);
|
||||
|
||||
float stopTime = startTime + simDuration;
|
||||
|
||||
std::string pcapFileName = fileNamePrefix + "-" + routerWanQueueType;
|
||||
std::string cwndTrFileName = fileNamePrefix + "-" + routerWanQueueType + "-cwnd" + ".tr";
|
||||
std::string attributeFileName = fileNamePrefix + "-" + routerWanQueueType + ".attr";
|
||||
std::string sojournTrFileName = fileNamePrefix + "-" + routerWanQueueType + "-sojourn" + ".tr";
|
||||
std::string queueLengthTrFileName = fileNamePrefix + "-" + routerWanQueueType + "-length" + ".tr";
|
||||
std::string everyDropTrFileName = fileNamePrefix + "-" + routerWanQueueType + "-drop" + ".tr";
|
||||
std::string dropStateTrFileName = fileNamePrefix + "-" + routerWanQueueType + "-drop-state" + ".tr";
|
||||
if (logging)
|
||||
{
|
||||
//LogComponentEnable ("CoDelDropTailAsymmetricTest", LOG_LEVEL_ALL);
|
||||
//LogComponentEnable ("BulkSendApplication", LOG_LEVEL_INFO);
|
||||
//LogComponentEnable ("DropTailQueue", LOG_LEVEL_ALL);
|
||||
LogComponentEnable ("CoDelQueue", LOG_LEVEL_FUNCTION);
|
||||
}
|
||||
|
||||
// Queue defaults
|
||||
Config::SetDefault ("ns3::DropTailQueue::MaxPackets", UintegerValue (queueSize));
|
||||
Config::SetDefault ("ns3::CoDelQueue::MaxPackets", UintegerValue (queueSize));
|
||||
Config::SetDefault ("ns3::DropTailQueue::Mode", StringValue ("QUEUE_MODE_PACKETS"));
|
||||
Config::SetDefault ("ns3::CoDelQueue::Mode", StringValue ("QUEUE_MODE_PACKETS"));
|
||||
|
||||
// Create the nodes
|
||||
NS_LOG_INFO ("Create nodes");
|
||||
NodeContainer nodes;
|
||||
nodes.Create (4);
|
||||
// Descriptive names
|
||||
Names::Add ("server", nodes.Get (0));
|
||||
Names::Add ("cmts", nodes.Get (1));
|
||||
Names::Add ("router", nodes.Get (2));
|
||||
Names::Add ("host", nodes.Get (3));
|
||||
NodeContainer serverCmts;
|
||||
serverCmts = NodeContainer (nodes.Get (0), nodes.Get (1));
|
||||
NodeContainer cmtsRouter;
|
||||
cmtsRouter = NodeContainer (nodes.Get (1), nodes.Get (2));
|
||||
NodeContainer routerHost;
|
||||
routerHost = NodeContainer (nodes.Get (2), nodes.Get (3));
|
||||
|
||||
// Enable checksum
|
||||
if (isPcapEnabled)
|
||||
{
|
||||
GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));
|
||||
}
|
||||
|
||||
Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (pktSize));
|
||||
|
||||
NS_LOG_INFO ("Install Internet stack on all nodes");
|
||||
InternetStackHelper stack;
|
||||
stack.InstallAll ();
|
||||
|
||||
NS_LOG_INFO ("Create channels and install net devices on nodes");
|
||||
PointToPointHelper p2p;
|
||||
|
||||
p2p.SetChannelAttribute ("Delay", StringValue (serverCmtsDelay));
|
||||
NetDeviceContainer serverCmtsDev = p2p.Install (serverCmts);
|
||||
Names::Add ("server/lan", serverCmtsDev.Get (0));
|
||||
Names::Add ("cmts/lan", serverCmtsDev.Get (1));
|
||||
Ptr<PointToPointNetDevice> serverLanDev = DynamicCast<PointToPointNetDevice> (serverCmtsDev.Get (0));
|
||||
serverLanDev->SetAttribute ("DataRate", StringValue (serverLanDataRate));
|
||||
Ptr<PointToPointNetDevice> cmtsLanDev = DynamicCast<PointToPointNetDevice> (serverCmtsDev.Get (1));
|
||||
cmtsLanDev->SetAttribute ("DataRate", StringValue (cmtsLanDataRate));
|
||||
|
||||
p2p.SetChannelAttribute ("Delay", StringValue (cmtsRouterDelay));
|
||||
NetDeviceContainer cmtsRouterDev = p2p.Install (cmtsRouter);
|
||||
Names::Add ("cmts/wan", cmtsRouterDev.Get (0));
|
||||
Names::Add ("router/wan", cmtsRouterDev.Get (1));
|
||||
Ptr<PointToPointNetDevice> cmtsWanDev = DynamicCast<PointToPointNetDevice> (cmtsRouterDev.Get (0));
|
||||
cmtsWanDev->SetAttribute ("DataRate", StringValue (cmtsWanDataRate));
|
||||
Ptr<Queue> queue = cmtsWanDev->GetQueue ();
|
||||
DynamicCast<DropTailQueue> (queue)->SetMode (DropTailQueue::QUEUE_MODE_BYTES);
|
||||
DynamicCast<DropTailQueue> (queue)->SetAttribute ("MaxBytes", UintegerValue (256000));
|
||||
|
||||
Ptr<PointToPointNetDevice> routerWanDev = DynamicCast<PointToPointNetDevice> (cmtsRouterDev.Get (1));
|
||||
routerWanDev->SetAttribute ("DataRate", StringValue (routerWanDataRate));
|
||||
if (routerWanQueueType.compare ("DropTail") == 0)
|
||||
{
|
||||
Ptr<Queue> dropTail = CreateObject<DropTailQueue> ();
|
||||
routerWanDev->SetQueue (dropTail);
|
||||
}
|
||||
else if (routerWanQueueType.compare ("CoDel") == 0)
|
||||
{
|
||||
Ptr<Queue> codel = CreateObject<CoDelQueue> ();
|
||||
routerWanDev->SetQueue (codel);
|
||||
}
|
||||
|
||||
p2p.SetChannelAttribute ("Delay", StringValue (routerHostDelay));
|
||||
NetDeviceContainer routerHostDev = p2p.Install (routerHost);
|
||||
Names::Add ("router/lan", routerHostDev.Get (0));
|
||||
Names::Add ("host/lan", routerHostDev.Get (1));
|
||||
Ptr<PointToPointNetDevice> routerLanDev = DynamicCast<PointToPointNetDevice> (routerHostDev.Get (0));
|
||||
routerLanDev->SetAttribute ("DataRate", StringValue (routerLanDataRate));
|
||||
Ptr<PointToPointNetDevice> hostLanDev = DynamicCast<PointToPointNetDevice> (routerHostDev.Get (1));
|
||||
hostLanDev->SetAttribute ("DataRate", StringValue (hostLanDataRate));
|
||||
|
||||
NS_LOG_INFO ("Assign IP Addresses");
|
||||
Ipv4AddressHelper ipv4;
|
||||
ipv4.SetBase ("10.1.1.0", "255.255.255.0");
|
||||
Ipv4InterfaceContainer serverCmtsInterface = ipv4.Assign (serverCmtsDev);
|
||||
ipv4.SetBase ("10.1.2.0", "255.255.255.0");
|
||||
Ipv4InterfaceContainer cmtsRouterInterface = ipv4.Assign (cmtsRouterDev);
|
||||
ipv4.SetBase ("10.1.3.0", "255.255.255.0");
|
||||
Ipv4InterfaceContainer routerHostInterface = ipv4.Assign (routerHostDev);
|
||||
|
||||
NS_LOG_INFO ("Initialize Global Routing");
|
||||
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
|
||||
|
||||
NS_LOG_INFO ("Configure downstream");
|
||||
uint16_t port1 = 50000;
|
||||
Address sinkLocalAddress1 (InetSocketAddress (Ipv4Address::GetAny (), port1));
|
||||
PacketSinkHelper sinkHelper1 ("ns3::TcpSocketFactory", sinkLocalAddress1);
|
||||
ApplicationContainer sinkApp1 = sinkHelper1.Install (routerHost.Get (1));
|
||||
sinkApp1.Start (Seconds (0));
|
||||
sinkApp1.Stop (Seconds (stopTime));
|
||||
AddressValue remoteAddress1 (InetSocketAddress (routerHostInterface.GetAddress (1), port1));
|
||||
while (numOfDownLoadBulkFlows)
|
||||
{
|
||||
CreateBulkFlow (remoteAddress1, serverCmts.Get (0), pktSize, stopTime);
|
||||
numOfDownLoadBulkFlows--;
|
||||
}
|
||||
|
||||
while (numOfDownLoadOnOffFlows)
|
||||
{
|
||||
CreateOnOffFlow (remoteAddress1, serverCmts.Get (0), stopTime);
|
||||
numOfDownLoadOnOffFlows--;
|
||||
}
|
||||
|
||||
NS_LOG_INFO ("Configure upstream");
|
||||
uint16_t port2 = 50001;
|
||||
Address sinkLocalAddress2 (InetSocketAddress (Ipv4Address::GetAny (), port2));
|
||||
PacketSinkHelper sinkHelper2 ("ns3::TcpSocketFactory", sinkLocalAddress2);
|
||||
ApplicationContainer sinkApp2 = sinkHelper2.Install (serverCmts.Get (0));
|
||||
sinkApp2.Start (Seconds (0));
|
||||
sinkApp2.Stop (Seconds (stopTime));
|
||||
AddressValue remoteAddress2 (InetSocketAddress (serverCmtsInterface.GetAddress (0), port2));
|
||||
while (numOfUpLoadBulkFlows)
|
||||
{
|
||||
CreateBulkFlow (remoteAddress2, routerHost.Get (1), pktSize, stopTime);
|
||||
numOfUpLoadBulkFlows--;
|
||||
}
|
||||
|
||||
while (numOfUpLoadOnOffFlows)
|
||||
{
|
||||
CreateOnOffFlow (remoteAddress2, routerHost.Get (1), stopTime);
|
||||
numOfUpLoadOnOffFlows--;
|
||||
}
|
||||
|
||||
Simulator::Schedule (Seconds (0.00001), &TraceCwnd, cwndTrFileName);
|
||||
TraceEveryDrop (everyDropTrFileName);
|
||||
if (routerWanQueueType.compare ("CoDel") == 0)
|
||||
{
|
||||
TraceSojourn (sojournTrFileName);
|
||||
TraceQueueLength (queueLengthTrFileName);
|
||||
TraceDroppingState (dropStateTrFileName);
|
||||
}
|
||||
if (isPcapEnabled)
|
||||
{
|
||||
p2p.EnablePcapAll (pcapFileName);
|
||||
}
|
||||
|
||||
// Output config store to txt format
|
||||
Config::SetDefault ("ns3::ConfigStore::Filename", StringValue (attributeFileName));
|
||||
Config::SetDefault ("ns3::ConfigStore::FileFormat", StringValue ("RawText"));
|
||||
Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Save"));
|
||||
ConfigStore outputConfig;
|
||||
outputConfig.ConfigureDefaults ();
|
||||
outputConfig.ConfigureAttributes ();
|
||||
|
||||
Simulator::Stop (Seconds (stopTime));
|
||||
Simulator::Run ();
|
||||
|
||||
Simulator::Destroy ();
|
||||
return 0;
|
||||
}
|
||||
219
src/internet/examples/codel-vs-droptail-basic-test.cc
Normal file
219
src/internet/examples/codel-vs-droptail-basic-test.cc
Normal file
@@ -0,0 +1,219 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014 ResiliNets, ITTC, University of Kansas
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Truc Anh N Nguyen <trucanh524@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a basic example that compares CoDel and DropTail queues using a simple, single-flow topology:
|
||||
*
|
||||
* source -------------------------- router ------------------------ sink
|
||||
* 100 Mb/s, 0.1 ms droptail 5 Mb/s, 5ms
|
||||
* or codel bottleneck
|
||||
*
|
||||
* The source generates traffic across the network using BulkSendApplication.
|
||||
* The default TCP version in ns-3, TcpNewReno, is used as the transport-layer protocol.
|
||||
* Packets transmitted during a simulation run are captured into a .pcap file, and
|
||||
* congestion window values are also traced.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/network-module.h"
|
||||
#include "ns3/internet-module.h"
|
||||
#include "ns3/point-to-point-module.h"
|
||||
#include "ns3/applications-module.h"
|
||||
#include "ns3/error-model.h"
|
||||
#include "ns3/tcp-header.h"
|
||||
#include "ns3/udp-header.h"
|
||||
#include "ns3/enum.h"
|
||||
#include "ns3/event-id.h"
|
||||
#include "ns3/ipv4-global-routing-helper.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("CoDelDropTailBasicTest");
|
||||
|
||||
static void
|
||||
CwndTracer (Ptr<OutputStreamWrapper>stream, uint32_t oldval, uint32_t newval)
|
||||
{
|
||||
*stream->GetStream () << oldval << " " << newval << std::endl;
|
||||
}
|
||||
|
||||
static void
|
||||
TraceCwnd (std::string cwndTrFileName)
|
||||
{
|
||||
AsciiTraceHelper ascii;
|
||||
if (cwndTrFileName.compare ("") == 0)
|
||||
{
|
||||
NS_LOG_DEBUG ("No trace file for cwnd provided");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream (cwndTrFileName.c_str ());
|
||||
Config::ConnectWithoutContext ("/NodeList/1/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow",MakeBoundCallback (&CwndTracer, stream));
|
||||
}
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
std::string bottleneckBandwidth = "5Mbps";
|
||||
std::string bottleneckDelay = "5ms";
|
||||
std::string accessBandwidth = "100Mbps";
|
||||
std::string accessDelay = "0.1ms";
|
||||
|
||||
std::string queueType = "DropTail"; //DropTail or CoDel
|
||||
uint32_t queueSize = 1000; //in packets
|
||||
uint32_t pktSize = 1458; //in bytes. 1458 to prevent fragments
|
||||
float startTime = 0.1;
|
||||
float simDuration = 60; //in seconds
|
||||
|
||||
bool isPcapEnabled = true;
|
||||
std::string pcapFileName = "pcapFileDropTail.pcap";
|
||||
std::string cwndTrFileName = "cwndDropTail.tr";
|
||||
bool logging = false;
|
||||
|
||||
CommandLine cmd;
|
||||
cmd.AddValue ("bottleneckBandwidth", "Bottleneck bandwidth", bottleneckBandwidth);
|
||||
cmd.AddValue ("bottleneckDelay", "Bottleneck delay", bottleneckDelay);
|
||||
cmd.AddValue ("accessBandwidth", "Access link bandwidth", accessBandwidth);
|
||||
cmd.AddValue ("accessDelay", "Access link delay", accessDelay);
|
||||
cmd.AddValue ("queueType", "Queue type: DropTail, CoDel", queueType);
|
||||
cmd.AddValue ("queueSize", "Queue size in packets", queueSize);
|
||||
cmd.AddValue ("pktSize", "Packet size in bytes", pktSize);
|
||||
cmd.AddValue ("startTime", "Simulation start time", startTime);
|
||||
cmd.AddValue ("simDuration", "Simulation duration in seconds", simDuration);
|
||||
cmd.AddValue ("isPcapEnabled", "Flag to enable/disable pcap", isPcapEnabled);
|
||||
cmd.AddValue ("pcapFileName", "Name of pcap file", pcapFileName);
|
||||
cmd.AddValue ("cwndTrFileName", "Name of cwnd trace file", cwndTrFileName);
|
||||
cmd.AddValue ("logging", "Flag to enable/disable logging", logging);
|
||||
cmd.Parse (argc, argv);
|
||||
|
||||
float stopTime = startTime + simDuration;
|
||||
|
||||
if (logging)
|
||||
{
|
||||
LogComponentEnable ("CoDelDropTailBasicTest", LOG_LEVEL_ALL);
|
||||
LogComponentEnable ("BulkSendApplication", LOG_LEVEL_INFO);
|
||||
LogComponentEnable ("DropTailQueue", LOG_LEVEL_ALL);
|
||||
LogComponentEnable ("CoDelQueue", LOG_LEVEL_ALL);
|
||||
}
|
||||
|
||||
// Enable checksum
|
||||
if (isPcapEnabled)
|
||||
{
|
||||
GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));
|
||||
}
|
||||
|
||||
// Create gateway, source, and sink
|
||||
NodeContainer gateway;
|
||||
gateway.Create (1);
|
||||
NodeContainer source;
|
||||
source.Create (1);
|
||||
NodeContainer sink;
|
||||
sink.Create (1);
|
||||
|
||||
// Create and configure access link and bottleneck link
|
||||
PointToPointHelper accessLink;
|
||||
accessLink.SetDeviceAttribute ("DataRate", StringValue (accessBandwidth));
|
||||
accessLink.SetChannelAttribute ("Delay", StringValue (accessDelay));
|
||||
|
||||
PointToPointHelper bottleneckLink;
|
||||
bottleneckLink.SetDeviceAttribute ("DataRate", StringValue (bottleneckBandwidth));
|
||||
bottleneckLink.SetChannelAttribute ("Delay", StringValue (bottleneckDelay));
|
||||
|
||||
// Configure the queue
|
||||
if (queueType.compare ("DropTail") == 0)
|
||||
{
|
||||
bottleneckLink.SetQueue ("ns3::DropTailQueue",
|
||||
"Mode", StringValue ("QUEUE_MODE_PACKETS"),
|
||||
"MaxPackets", UintegerValue (queueSize));
|
||||
}
|
||||
else if (queueType.compare ("CoDel") == 0)
|
||||
{
|
||||
bottleneckLink.SetQueue ("ns3::CoDelQueue",
|
||||
"Mode", StringValue ("QUEUE_MODE_PACKETS"),
|
||||
"MaxPackets", UintegerValue (queueSize));
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("Invalid queue type");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
InternetStackHelper stack;
|
||||
stack.InstallAll ();
|
||||
|
||||
Ipv4AddressHelper address;
|
||||
address.SetBase ("10.0.0.0", "255.255.255.0");
|
||||
|
||||
// Configure the source and sink net devices
|
||||
// and the channels between the source/sink and the gateway
|
||||
Ipv4InterfaceContainer sinkInterface;
|
||||
|
||||
NetDeviceContainer devices;
|
||||
devices = accessLink.Install (source.Get (0), gateway.Get (0));
|
||||
address.NewNetwork ();
|
||||
Ipv4InterfaceContainer interfaces = address.Assign (devices);
|
||||
devices = bottleneckLink.Install (gateway.Get (0), sink.Get (0));
|
||||
address.NewNetwork ();
|
||||
interfaces = address.Assign (devices);
|
||||
|
||||
sinkInterface.Add (interfaces.Get (1));
|
||||
|
||||
NS_LOG_INFO ("Initialize Global Routing.");
|
||||
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
|
||||
|
||||
uint16_t port = 50000;
|
||||
Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
|
||||
PacketSinkHelper sinkHelper ("ns3::TcpSocketFactory", sinkLocalAddress);
|
||||
|
||||
// Configure application
|
||||
AddressValue remoteAddress (InetSocketAddress (sinkInterface.GetAddress (0, 0), port));
|
||||
Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (pktSize));
|
||||
BulkSendHelper ftp ("ns3::TcpSocketFactory", Address ());
|
||||
ftp.SetAttribute ("Remote", remoteAddress);
|
||||
ftp.SetAttribute ("SendSize", UintegerValue (pktSize));
|
||||
ftp.SetAttribute ("MaxBytes", UintegerValue (0));
|
||||
|
||||
ApplicationContainer sourceApp = ftp.Install (source.Get (0));
|
||||
sourceApp.Start (Seconds (0));
|
||||
sourceApp.Stop (Seconds (stopTime - 3));
|
||||
|
||||
sinkHelper.SetAttribute ("Protocol", TypeIdValue (TcpSocketFactory::GetTypeId ()));
|
||||
ApplicationContainer sinkApp = sinkHelper.Install (sink);
|
||||
sinkApp.Start (Seconds (0));
|
||||
sinkApp.Stop (Seconds (stopTime));
|
||||
|
||||
Simulator::Schedule (Seconds (0.00001), &TraceCwnd, cwndTrFileName);
|
||||
|
||||
if (isPcapEnabled)
|
||||
{
|
||||
accessLink.EnablePcap (pcapFileName,source,true);
|
||||
}
|
||||
|
||||
Simulator::Stop (Seconds (stopTime));
|
||||
Simulator::Run ();
|
||||
|
||||
Simulator::Destroy ();
|
||||
return 0;
|
||||
}
|
||||
@@ -7,3 +7,11 @@ def build(bld):
|
||||
obj = bld.create_ns3_program('main-simple',
|
||||
['network', 'internet', 'applications'])
|
||||
obj.source = 'main-simple.cc'
|
||||
|
||||
obj = bld.create_ns3_program('codel-vs-droptail-basic-test',
|
||||
['point-to-point','network', 'internet', 'applications'])
|
||||
obj.source = 'codel-vs-droptail-basic-test.cc'
|
||||
|
||||
obj = bld.create_ns3_program('codel-vs-droptail-asymmetric',
|
||||
['point-to-point','network', 'internet', 'applications'])
|
||||
obj.source = 'codel-vs-droptail-asymmetric.cc'
|
||||
|
||||
Reference in New Issue
Block a user