## 5 Experimental Evaluation
### Evaluation and Benchmarking of AQM Algorithms  
In our evaluations, we compare our L4S algorithm with other AQM congestion control algorithms implemented in the FreeBSD kernel, specifically CoDel, PIE, FQ-CoDel, FQ-PIE, and L4S. Our experimental testbed is based on virtual machines operating within VirtualBox. The testbed features a client and a server connected via a single router, thus simulating a single-path network, as depicted in Figure 3. Multiple TCP streams were deployed at the router to simulate real-world network congestion. To evaluate the algorithms' performance across different network conditions, we conducted tests in both high-bandwidth and low-bandwidth environments, specifically at 10 Mbps and 1 Mbps. This comprehensive approach ensures that our L4S algorithm is robust and effective across various operational scenarios. Congestion window size and smoothed RTT data were recorded using the 'Statistical Information For TCP Research (SIFTR)' [34] kernel module. The'siftr' ([[https://man.freebsd.org/cgi/man.cgi?query=siftr&apropos=0&sektion=4&manpath=FreeBSD+13.1-RELEASE+and+Ports&arch=default&format=html](https://man.freebsd.org/cgi/man.cgi?query=siftr&apropos=0&sektion=4&manpath=FreeBSD+13.1-RELEASE+and+Ports&arch=default&format=html)]([https://man.freebsd.org/cgi/man.cgi?query=siftr&apropos=0&sektion=4&manpath=FreeBSD+13.1-RELEASE+and+Ports&arch=default&format=html](https://man.freebsd.org/cgi/man.cgi?query=siftr&apropos=0&sektion=4&manpath=FreeBSD+13.1-RELEASE+and+Ports&arch=default&format=html)) accessed on 18 July 2024) tool rests between the IPv4 and TCP/IP layers and intercepts the TCP packets as they traverse the network stack within the kernel. On interception, it generates a log file containing highly granular measurements of each packet in the TCP session. The filename for the logfile can be configured using the 'net.inet.siftr.logfile' variable through the'sysctl' interface. Additionally, the recording session can be initiated or terminated by setting the net.inet.siftr.enabled' variable to 0 or 1. The log file records the congestion window size in bytes, and the smoothed RTT in units of TCP_RTT_SCALE * HZ, where TCP_RTT_SCALE is defined in tcp_var.h and HZ is the kernel's tick timer. To acquire the smoothed RTT in seconds, dividing the recorded value by (TCP_RTT_SCALE * HZ ) is necessary. To expedite the 'throughput' measuring process, we employ the 'tcpdump' [35] utility to capture packet data and save it as a 'pcap' file. This file is then analyzed using the 'dpkt' python library [36] to filter for TCP packets heading to a specific port connected to its respective TCP stream. The results are then immediately visualized using the'matplotlib' library. Readers familiar with 'Wireshark' [37] can replicate these throughput graphs by selecting _throughput_ in the _TCP stream graphs_ section under the statistics tab, using the pcap files in the referenced repository. **NewReno TCP congestion control**: Our experiments utilize NewReno as the primary TCP congestion control mechanism. NewReno, implemented in FreeBSD, commences with the slow-start phase, starting with a conservative congestion window (_cvnd_) size of several segments, exponentially scaling until it detects potential congestion, after which it transitions into the congestion avoidance phase, where it increases the _cvnd_ linearly. Suppose the congestion control mechanism detects any packet loss, in that case, it enters into fast recovery mode, where it decreases its _cvnd_ size by half and prioritizes retransmitting lost packets till it receives an acknowledgment for retransmitted packets. Subsequently, it transitions back into the congestion avoidance phase and repeats the process when it encounters packet loss or after an idle timeout; it enters the slow-start phase again to probe the optimal _cvnd_ size. In the following Figure 2, we observe the total data transferred for each case in our experiment.