#!/bin/bash # ============================================================================ # line-speed-probe.sh — measure burst vs sustained inbound throughput. # # Why this exists: a single-stream download tops out around 180 Mbps on this # line, which reads convincingly as "the ISP shapes us to 180". It does not — # a many-connection swarm reaches 986 Mbps with zero retransmits. Only a # multi-stream probe reveals real line capacity, so this script runs both and # reports them separately. # # Baseline captured 2026-07-19 ~17:30 (Sunday evening, European peak): # geo.mirror.pkgbuild.com 1 stream PEAK 493 SUSTAINED 182 Mbps # ftp.icm.edu.pl 1 stream PEAK 308 SUSTAINED 164 Mbps # 4 mixed mirrors 4 streams PEAK 766 SUSTAINED 258 Mbps # # Downloads are discarded to /dev/null; only the report is written. Rates come # from the NIC's own counters, so competing traffic is included by design. # # Usage: line-speed-probe.sh [url] (default: probe the standard set) # ============================================================================ set -euo pipefail IFACE="${IFACE:-enp6s0}" DURATION="${DURATION:-90}" # seconds per probe STEP=5 # sample interval REPORT_DIR="${REPORT_DIR:-${HOME}/.local/share/line-speed-test}" MIRROR_PL="https://ftp.icm.edu.pl/pub/Linux/dist/archlinux/iso/latest/archlinux-x86_64.iso" MIRROR_GEO="https://geo.mirror.pkgbuild.com/iso/latest/archlinux-x86_64.iso" MIRROR_RACK="https://mirror.rackspace.com/archlinux/iso/latest/archlinux-x86_64.iso" MIRROR_KERNEL="https://mirrors.edge.kernel.org/archlinux/iso/latest/archlinux-x86_64.iso" PIDS=() REPORT="" # --- pure helpers (unit-tested by linux_configuration/tests) ---------------- bytes_to_mbps() { local delta="$1" secs="$2" (( secs > 0 )) || { printf '0'; return; } printf '%d' $(( delta * 8 / secs / 1000000 )) } # Sustained throughput = mean of the SECOND HALF of the samples. The first half # is discarded deliberately: it contains TCP slow start and any ISP burst # allowance, both of which inflate the figure we care about. sustained_of() { (( $# > 0 )) || { printf '0'; return; } local count=$# half=$(( $# / 2 )) sum=0 i=0 v for v in "$@"; do i=$(( i + 1 )) (( i > half )) && sum=$(( sum + v )) done printf '%d' $(( sum / (count - half) )) } max_of() { (( $# > 0 )) || { printf '0'; return; } local m=0 v for v in "$@"; do (( v > m )) && m=$v; done printf '%d' "$m" } # Interpret the best sustained figure seen across all probes. verdict_for() { local best="$1" if (( best >= 600 )); then printf 'LINE_OK' elif (( best >= 350 )); then printf 'PARTIAL' else printf 'SLOW' fi } # --- measurement ----------------------------------------------------------- cleanup() { local p for p in "${PIDS[@]:-}"; do if [[ -n "$p" ]]; then kill "$p" 2>/dev/null || true fi done wait 2>/dev/null || true } trap cleanup EXIT rx_bytes() { cat "/sys/class/net/${IFACE}/statistics/rx_bytes"; } emit() { printf '%s\n' "$1" | tee -a "$REPORT"; } # probe