TOPIC: Wired Networks & Point-to-Point
TITLE: Study the effect of RED vs. DropTail queue management in a dumbbell topology
QUEUE MANAGEMENT TECHNIQUES AND ITS TYPES – INTRODUCTION
Queue management plays a critical role in controlling congestion in computer networks. In packet-switched networks, routers maintain queues to temporarily store packets before forwarding them. When network traffic increases beyond capacity, congestion occurs, leading to packet loss, increased delay, and reduced throughput.
Two widely used queue management techniques are DropTail Queue Management and Random Early Detection (RED). DropTail is a simple First-In-First-Out (FIFO) mechanism where packets are dropped only when the queue becomes full.
On the other hand, RED is an active queue management algorithm that proactively drops packets based on the average queue size before the queue becomes full. This helps in early congestion detection and improves overall network performance.
In this assignment, a dumbbell topology is implemented using NS-3.43 to simulate multiple TCP flows passing through a bottleneck link. The performance of RED and DropTail queue management techniques is analyzed and compared based on key metrics such as throughput, packet loss, and delay.
WHAT DO WE WANT TO IMPLEMENT?
To implement a dumbbell network topology using NS-3.43.
To simulate network traffic using TCP flows across a bottleneck link.
To analyze the behavior of DropTail Queue Management and Random Early Detection (RED) under congestion.
To evaluate performance metrics such as:
Throughput
Packet loss
End-to-end delay
To compare the efficiency of RED and DropTail in handling congestion.
IMPLEMENTATION:
We have used Mermaid live editor to create a visualization of the network we are creating to observe both the techniques:
The above diagram represents the dumbbell topology implemented in the NS-3 simulation. It consists of two sender nodes (Node 0 and Node 1) on the left side and two receiver nodes (Node 2 and Node 3) on the right side, connected through two intermediate routers.
The access links between the end nodes and routers have a high bandwidth of 100 Mbps with low delay, ensuring that they do not become bottlenecks. The central link between Router 0 and Router 1 is configured as the bottleneck link with a bandwidth of 1 Mbps and higher delay. This link is where congestion occurs and where the queue management algorithms—RED and DropTail—are applied.
Multiple TCP flows are generated from the sender nodes to the receiver nodes, all passing through the bottleneck link. This setup creates network congestion, allowing the performance of RED and DropTail queue management techniques to be effectively analyzed in terms of congestion control, packet loss, queue occupancy, and throughput.
SOURCE CODE:
#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/traffic-control-module.h"
#include "ns3/flow-monitor-module.h"
#include "ns3/netanim-module.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE("Dumbbell_RED_DropTail");
//CWND Trace
static void CwndChange(Ptr<OutputStreamWrapper> stream,
uint32_t oldCwnd, uint32_t newCwnd)
{
*stream->GetStream() << Simulator::Now().GetSeconds() << " " << newCwnd << std::endl;
}
//Queue tracing function
static void QueueSizeTrace(Ptr<OutputStreamWrapper> stream,
uint32_t oldVal, uint32_t newVal)
{
*stream->GetStream() << Simulator::Now().GetSeconds()
<< " " << newVal << std::endl;
}
//Packet Drop tracing function
static void DropTracer(Ptr<OutputStreamWrapper> stream, Ptr<const QueueDiscItem> item)
{
*stream->GetStream() << Simulator::Now().GetSeconds() << " 1" << std::endl;
}
int main(int argc, char *argv[])
{
bool useRed = false;
CommandLine cmd;
cmd.AddValue("useRed", "Enable RED queue", useRed);
cmd.Parse(argc, argv);
std::string prefix = useRed ? "red" : "droptail";
std::string animFile = prefix + ".xml";
std::string cwndFile = prefix + "_cwnd.tr";
std::string dropFile = prefix + "_drops.tr";
// -----------------------------
// Create Nodes
// -----------------------------
NodeContainer leftNodes, rightNodes, routers;
leftNodes.Create(2);
rightNodes.Create(2);
routers.Create(2);
InternetStackHelper stack;
stack.Install(leftNodes);
stack.Install(rightNodes);
stack.Install(routers);
// -----------------------------
// Link Configurations
// -----------------------------
PointToPointHelper accessLink;
accessLink.SetDeviceAttribute("DataRate", StringValue("100Mbps"));
accessLink.SetChannelAttribute("Delay", StringValue("2ms"));
PointToPointHelper bottleneck;
bottleneck.SetDeviceAttribute("DataRate", StringValue("1Mbps"));
bottleneck.SetChannelAttribute("Delay", StringValue("10ms"));
// -----------------------------
// Install Links
// -----------------------------
NetDeviceContainer d0 = accessLink.Install(leftNodes.Get(0), routers.Get(0));
NetDeviceContainer d1 = accessLink.Install(leftNodes.Get(1), routers.Get(0));
NetDeviceContainer d2 = accessLink.Install(routers.Get(1), rightNodes.Get(0));
NetDeviceContainer d3 = accessLink.Install(routers.Get(1), rightNodes.Get(1));
NetDeviceContainer bottleneckDevices = bottleneck.Install(routers.Get(0), routers.Get(1));
// -----------------------------
// Queue Configuration
// -----------------------------
TrafficControlHelper tch;
if (useRed)
{
std::cout << "Using RED Queue\n";
tch.SetRootQueueDisc("ns3::RedQueueDisc",
"MinTh", DoubleValue(5),
"MaxTh", DoubleValue(15),
"MaxSize", QueueSizeValue(QueueSize("20p")));
}
else
{
std::cout << "Using DropTail Queue\n";
tch.SetRootQueueDisc("ns3::PfifoFastQueueDisc",
"MaxSize", QueueSizeValue(QueueSize("5p")));
}
QueueDiscContainer qdiscs = tch.Install(bottleneckDevices);
AsciiTraceHelper asciiDrop;
Ptr<OutputStreamWrapper> dropStream = asciiDrop.CreateFileStream(prefix + "_drops_exact.dat");
for (uint32_t i = 0; i < qdiscs.GetN(); i++)
{
qdiscs.Get(i)->TraceConnectWithoutContext("Drop", MakeBoundCallback(&DropTracer, dropStream));
}
AsciiTraceHelper asciiQueue;
Ptr<OutputStreamWrapper> queueStream =
asciiQueue.CreateFileStream(prefix + "_queue.tr");
for (uint32_t i = 0; i < qdiscs.GetN(); i++)
{
qdiscs.Get(i)->TraceConnectWithoutContext(
"PacketsInQueue",
MakeBoundCallback(&QueueSizeTrace, queueStream));
}
// -----------------------------
// Assign IP Addresses
// -----------------------------
Ipv4AddressHelper address;
address.SetBase("10.1.1.0", "255.255.255.0");
address.Assign(d0);
address.SetBase("10.1.2.0", "255.255.255.0");
address.Assign(d1);
address.SetBase("10.1.3.0", "255.255.255.0");
address.Assign(d2);
address.SetBase("10.1.4.0", "255.255.255.0");
address.Assign(d3);
address.SetBase("10.1.5.0", "255.255.255.0");
address.Assign(bottleneckDevices);
Ipv4GlobalRoutingHelper::PopulateRoutingTables();
// -----------------------------
// Applications
// -----------------------------
uint16_t port = 8080;
Address sinkAddress(InetSocketAddress(Ipv4Address("10.1.3.2"), port));
PacketSinkHelper sinkHelper("ns3::TcpSocketFactory", sinkAddress);
ApplicationContainer sinkApp = sinkHelper.Install(rightNodes.Get(0));
sinkApp.Start(Seconds(0.0));
sinkApp.Stop(Seconds(20.0));
BulkSendHelper source1("ns3::TcpSocketFactory", sinkAddress);
source1.SetAttribute("MaxBytes", UintegerValue(0));
ApplicationContainer srcApp1 = source1.Install(leftNodes.Get(0));
srcApp1.Start(Seconds(1.0));
srcApp1.Stop(Seconds(20.0));
BulkSendHelper source2("ns3::TcpSocketFactory", sinkAddress);
source2.SetAttribute("MaxBytes", UintegerValue(0));
ApplicationContainer srcApp2 = source2.Install(leftNodes.Get(1));
srcApp2.Start(Seconds(1.0));
srcApp2.Stop(Seconds(20.0));
// -----------------------------
// Flow Monitor
// -----------------------------
FlowMonitorHelper flowmon;
Ptr<FlowMonitor> monitor = flowmon.InstallAll();
// -----------------------------
// ADD THIS: TraceMetrics ASCII trace
// -----------------------------
AsciiTraceHelper asciiTrace;
accessLink.EnableAsciiAll(asciiTrace.CreateFileStream(prefix + "_trace.tr"));
bottleneck.EnableAsciiAll(asciiTrace.CreateFileStream(prefix + "_trace.tr"));
// -----------------------------
//CWND tracing (delayed)
// -----------------------------
AsciiTraceHelper ascii;
Ptr<OutputStreamWrapper> cwndStream = ascii.CreateFileStream(cwndFile);
Simulator::Schedule(Seconds(1.1), [&]() {
Config::ConnectWithoutContext(
"/NodeList/*/$ns3::TcpL4Protocol/SocketList/*/CongestionWindow",
MakeBoundCallback(&CwndChange, cwndStream));
});
// -----------------------------
// Wireshark (PCAP)
// -----------------------------
bottleneck.EnablePcapAll(prefix);
// -----------------------------
// Animation
// -----------------------------
AnimationInterface anim(animFile);
anim.SetConstantPosition(leftNodes.Get(0), 0, 10);
anim.SetConstantPosition(leftNodes.Get(1), 0, 0);
anim.SetConstantPosition(routers.Get(0), 20, 5);
anim.SetConstantPosition(routers.Get(1), 40, 5);
anim.SetConstantPosition(rightNodes.Get(0), 60, 10);
anim.SetConstantPosition(rightNodes.Get(1), 60, 0);
// -----------------------------
// Run Simulation
// -----------------------------
Simulator::Stop(Seconds(20.0));
Simulator::Run();
// -----------------------------
// Results
// -----------------------------
monitor->CheckForLostPackets();
std::map<FlowId, FlowMonitor::FlowStats> stats = monitor->GetFlowStats();
for (auto &flow : stats)
{
std::cout << "\nFlow ID: " << flow.first << std::endl;
std::cout << "Tx Packets: " << flow.second.txPackets << std::endl;
std::cout << "Rx Packets: " << flow.second.rxPackets << std::endl;
std::cout << "Lost Packets: "
<< flow.second.txPackets - flow.second.rxPackets << std::endl;
double throughput = flow.second.rxBytes * 8.0 /
(flow.second.timeLastRxPacket.GetSeconds() -
flow.second.timeFirstTxPacket.GetSeconds()) / 1000;
std::cout << "Throughput: " << throughput << " Kbps\n";
}
Simulator::Destroy();
return 0;
}
PROMPT USED:
Generate an ns-3 C++ program to study the effect of RED vs DropTail queue management in a dumbbell topology. As suggested by you we'll consider a 2-sender,2-reciever topology.For the bottleneck link accordingly set the packet size, no of packets as well as bandwidth so that packet dropping and difference in both techniques can be observed clearly.
The program should allow switching between RED and DropTail and enable observation of packet drops and performance.
The code should contain Netanim, FlowMonitor, Tracemetrics snippets to view dropping of packets and compare but make sure to add an if-else to store names according to technique,that is RED.tr and DropTail.tr as well as pcap files to be enabled for Wireshark
Also generate gnuplot codes to clearly visualize efficiency,queue occupancy, throughput, packet drop rate in the two methods RED vs DropTail techniques
DROPTAIL QUEUE MANAGEMENT TECHNOLOGY
COMMAND PROMPT- FLOW MONITOR:
EXPLANATION:
The FlowMonitor captures end-to-end performance by tracking every packet from the source (Left nodes) to the sink (Right nodes) across the bottleneck link. Under DropTail, the throughput often fluctuates as observed above. Because the network waits for the buffer to be 100% full before dropping, it causes a "bursty" loss pattern. This leads to lower link utilization compared to smoother algorithms, as the source repeatedly hits a wall and has to restart its transmission ramp-up.
TRACEMETRICS:
TraceMetrics parses the .tr (trace) file generated by ns-3 to visualize how individual packet arrival times vary over the 20-second simulation. In the below attached images, you see a "sawtooth" pattern in delay. As the queue fills up, delay increases linearly. When the "Tail Drop" occurs and the queue empties, the delay drops sharply. This confirms that DropTail suffers from high bufferbloat (unnecessary queuing delay) right before a packet loss event.
TRACEMETRICS GRAPH GENERATION :
NETWORK ANIMATION:
NetAnim provides a graphical representation of the dumbbell topology, showing nodes (0, 1, 2, 3) and routers (4, 5) with packets moving across links. It visualizes Packet Flow and Link Congestion via colored dots representing data packets. The animation shows a high density of packets at Router 4. This visually identifies the bottleneck link. Under DropTail, you can observe "bursts" of packets being forwarded followed by gaps where the sender has slowed down due to a drop, illustrating the lack of steady-state flow.
WIRESHARK:
EXPLANATION:
The simulation generates .pcap files for the point-to-point devices, which are opened in Wireshark to inspect the TCP handshake and data transfer. The DropTail Wireshark trace reveals "TCP Fast Retransmit" or "Timeout" events. When the tail of the queue is dropped, multiple packets from the same window are often lost. This causes the sender to enter a "Slow Start" phase, which is visible in Wireshark as a sudden halt in sequence number progression followed by a slow recovery.
RED QUEUE MANAGEMENT TECHNOLOGY:
COMMAND PROMPT - FLOW MONITOR
EXPLANATION:
RED monitors the average queue size and begins dropping or marking packets based on statistical probability before the buffer is full.In the RED images, you will notice that packet losses are often more distributed rather than occurring in one giant block. The inference is that RED maintains a more consistent throughput. By proactively dropping packets, it prevents the bottleneck link from staying 100% saturated with "stale" data, allowing for a steadier flow and avoiding the "all-or-nothing" behavior seen in DropTail.
TRACEMETRICS:
EXPLANATION:
The simulation uses thresholds (MinTh = 5, MaxTh = 15) to manage the queue. The algorithm calculates an average queue size to decide the drop probability.It measures Mean Delay and Packet Arrival Consistency. The graph shows fewer extreme spikes in delay compared to DropTail. Because RED avoids keeping the buffer completely full, the average delay experienced by packets is lower. This demonstrates RED's ability to combat "bufferbloat"—the high latency caused by excessively large buffers.
NETWORK ANIMATION:
The visualizer displays the movement of packets between the nodes and routers, colored by flow ID. Visual Flow Density and Congestion Points.In the RED simulation images, the traffic appears more fluid. You can observe that packets are being processed and cleared from Router 4 more regularly. This reflects RED's goal of "Global Synchronization Avoidance," meaning different TCP flows don't all slow down at the exact same time, leading to better overall link utilization.
WIRESHARK:
EXPLANATION:
Wireshark captures the specific packet sequence numbers as they exit the router interface.The RED trace shows "Early Drops" where a single packet might be missing even while others continue to arrive. This allows the sender (TCP) to detect congestion early via "Triple Duplicate ACKs" and reduce its window size gracefully. The inference is a much smoother "Congestion Window" (CWND) adjustment, which prevents the connection from timing out and falling into the slow-start recovery phase.
RED vs. DropTail
Now, we have implemented both the techniques and obtained the throughput data as well as stored the packet drop data and the queue size data according to its respective functions. Lets create some graphs using GNUPLOT tool
EFFICIENCY COMPARISON
GNUPLOT CODE:
set title "RED vs DropTail - TCP Congestion Window Comparison"
set xlabel "Time (seconds)"
set ylabel "CWND (KB)"
set grid
set terminal png size 900,600
set output "comparison.png"
plot "droptail_cwnd.tr" using 1:($2/1024) with lines lw 2 title "DropTail", \
"red_cwnd.tr" using 1:($2/1024) with lines lw 2 title "RED"
OUTPUT:
EXPLANATION:
The CWND graph shows the variation of TCP congestion window over time for both RED and DropTail. Both algorithms exhibit the typical TCP behavior of increase followed by sudden drops due to packet loss. DropTail shows sharper and more abrupt drops due to buffer overflow, while RED shows comparatively smoother reductions due to early packet dropping. Hence, RED provides slightly better congestion control, although the difference is not very large due to the limited number of flows in the simulation.
PACKET DROP COMPARISON
GNUPLOT CODE:
set terminal pngcairo font "arial,12" size 1000,600
set output 'drop_rate_final.png'
set title "Packet Drop Intensity over Time (RED vs DropTail)"
set xlabel "Time (Seconds)"
set ylabel "Packet Drops per 0.1s Interval"
set grid
set xrange [4:16]
set yrange [0:*]
set style line 1 lc rgb '#d62728' lw 2 pt 7 ps 0.8 # Red
set style line 2 lc rgb '#1f77b4' lw 2 pt 7 ps 0.8 # Blue
binwidth = 0.1
bin(x) = binwidth * floor(x/binwidth)
plot "droptail_drops_exact.dat" using (bin($1)):2 smooth frequency with lines ls 1 title "DropTail", \
"red_drops_exact.dat" using (bin($1)):2 smooth frequency with lines ls 2 title "RED"
OUTPUT:
EXPLANATION:
The packet drop graph shows that DropTail experiences sudden spikes in packet drops when the queue becomes full. In contrast, RED distributes packet drops more gradually over time due to early congestion detection. This prevents burst losses and improves network stability. However, since only two flows are used, the difference between RED and DropTail is moderate rather than highly significant.
QUEUE SIZE COMPARISON
GNUPLOT CODE:
set terminal pngcairo font "arial,12" size 1000,600
set output 'queue_comparison.png'
set title "QUEUE OCCUPANCY: RED vs DropTail"
set xlabel "Time (Seconds)"
set ylabel "Average Packets in Queue"
set grid
set tics nomirror
set xrange [4:18]
set yrange [0:22]
set style line 1 lc rgb '#d62728' lw 3 # Red
set style line 2 lc rgb '#1f77b4' lw 3 # Blue
plot "droptail_queue.tr" using 1:2:(1.0) smooth acsplines ls 1 title "DropTail", \
"red_queue.tr" using 1:2:(1.0) smooth acsplines ls 2 title "RED"
OUTPUT:
EXPLANATION:
The queue size graph shows that RED maintains a higher queue occupancy compared to DropTail. This behavior is due to the configuration used in the simulation, where the RED queue has a maximum size of 20 packets, while the DropTail queue is limited to only 5 packets. As a result, DropTail cannot build up a large queue and drops packets earlier, whereas RED allows more packets to be buffered before applying congestion control. Therefore, the observed behavior is a result of unequal queue sizes rather than the inherent superiority of either algorithm.
THROUGHPUT COMPARISOn
GNUPLOT CODE:
set title "Throughput Comparison (TraceMetrics)"
set xlabel "Time (seconds)"
set ylabel "Throughput (Kbps)"
set grid
set terminal png size 900,600
set output "throughput.png"
plot "droptail_tp.txt" using 1:2 with lines lw 2 title "DropTail", \
"red_tp.txt" using 1:2 with lines lw 2 title "RED"
OUTPUT:
EXPLANATION:
The throughput graph shows that both RED and DropTail achieve similar throughput values over time. This is because the simulation uses only two TCP flows and a moderate bottleneck bandwidth, resulting in limited congestion. As a result, both queue management techniques perform similarly in terms of throughput, and no significant difference is observed between them.
INFERENCE
The simulation results show noticeable differences between RED and DropTail queue management techniques, but these differences are influenced by the configuration used in the implementation. The congestion window (CWND) graph indicates that both RED and DropTail follow standard TCP behavior, with periods of growth followed by sudden reductions due to packet loss. DropTail exhibits sharper drops, while RED shows relatively smoother variations due to early packet dropping.
The packet drop graph demonstrates that DropTail experiences burst packet losses when the queue becomes full, whereas RED distributes packet drops more evenly over time. This confirms that RED performs proactive congestion control compared to the reactive behavior of DropTail. However, the queue size graph shows that RED maintains a higher queue occupancy than DropTail. This behavior is due to the configuration in the simulation, where the RED queue has a larger maximum size (20 packets) compared to the DropTail queue (5 packets). As a result, DropTail cannot accumulate a large number of packets and drops them earlier, while RED allows more packets to be buffered.
The throughput graph indicates that both RED and DropTail achieve similar throughput values. This is because the simulation uses only two TCP flows and a moderate bottleneck bandwidth, resulting in limited congestion. Hence, the performance difference in throughput is not very significant. Overall, the results indicate that while RED provides smoother congestion control and more evenly distributed packet drops, the observed behavior is partially influenced by unequal queue sizes and limited traffic load rather than purely algorithmic differences.
CONCLUSION
This project successfully demonstrates the impact of queue management techniques on network performance using a dumbbell topology in NS-3.43. The results show that DropTail Queue Management, while simple to implement, is not efficient under heavy traffic conditions due to its reactive nature. It leads to higher delay, burst packet losses, and synchronization issues among flows. On the other hand, Random Early Detection (RED) provides better congestion control by proactively managing queue size. It reduces packet loss, maintains stable throughput, and improves overall network performance. Therefore, RED is a more effective queue management technique compared to DropTail, especially in scenarios involving high traffic and multiple concurrent flows.