#!/usr/bin/env bash # loss.sh P drop P percent (may be fractional, e.g. 2.5) of packets in each direction on lo, port 4433, TCP and UDP # loss.sh P udp the same, UDP only (100 udp = a firewall that blocks QUIC) # loss.sh off remove the rules and restore the loopback MTU # Loopback MTU is 65536, so TCP would send 64 KiB segments while QUIC sends ~1.2 KB datagrams; a per-packet drop rate # would then be wildly unfair. While loss is on we set the loopback MTU to 1500 so both protocols use Ethernet-sized packets. # Kernel-level random drop (iptables -m statistic). This is NOT tc netem (netem was unavailable in the sandbox: # "Specified qdisc kind is unknown"), so it adds loss but no delay. Needs root / CAP_NET_ADMIN. set -euo pipefail CH=H3LOSS off() { ip link set dev lo mtu 65536; iptables -D INPUT -i lo -j $CH 2>/dev/null || true; iptables -F $CH 2>/dev/null || true; iptables -X $CH 2>/dev/null || true; } off [ "${1:?P or off}" = off ] && exit 0 P=$(python3 -c "print(float('$1')/100)") ip link set dev lo mtu 1500 iptables -N $CH for proto in ${2:-tcp udp}; do for side in --dport --sport; do iptables -A $CH -p $proto $side 4433 -m statistic --mode random --probability "$P" -j DROP done done iptables -A INPUT -i lo -j $CH