TP6 Durchlauf 2 messbar machen: Sampler, gefuehrte Konsole, Treiber

Durchlauf 1 ist gemessen (Ergebnis folgt separat im Runbook). Fuer den Durchlauf
mit laufendem Videocall brauchte es Werkzeug, das es noch nicht gab:

- tp6-monitor-core.sh haengt EINE persistente SSH-Sitzung an den Core und laesst
  dort eine Console-Schleife laufen, die im 2-s-Takt CPU, WAN-Rate und die
  Registration-Table-Werte eines WLAN-Clients als CSV ausgibt. Nur Lesezugriffe.
  Unter CAPsMAN fuehrt der Manager die Tabelle, deshalb wird der Core abgefragt
  und nicht ap1/ap2. Zwei RouterOS-Fallen sind im Code kommentiert: die Console
  parst eine per SSH uebergebene Mehrzeilen-Eingabe zeilenweise, und in der
  Einzeiler-Form braucht jeder do={}-Block ein abschliessendes Semikolon.

- tp6-marker/server.py ist die Konsole fuer die Person am Telefon: Phasenkarte
  mit Klartext-Anweisung, Countdown, Fortschritt, Marker-Buttons und Not-Aus,
  bedienbar vom iPad. Die Buttons sind server-seitig gerenderte Formulare und
  die Anleitung aktualisiert sich notfalls per meta-refresh -- auf dem iPad ist
  das JavaScript ausgefallen, uebrig blieb nur der eine statische Button.

- tp6-call-run.sh fuehrt Durchlauf 2 mit denselben Messparametern wie Durchlauf 1
  (3 Flows x 430 KB/s, 24 Pings, 30 s Settle) und ergaenzt Ruhephasen davor und
  danach, Phasenmarken, eine PID-Datei fuer den Not-Aus und einen Heartbeat.
  Der Heartbeat ist kein Detail: ohne ihn geht der Start-Klick still ins Leere,
  der Call laeuft ohne Last, und "keine Probleme" liest sich wie ein Ergebnis,
  obwohl es eine Nicht-Messung ist -- genau so passiert, 5,5 Minuten lang.

- tp6-auswertung.py schneidet die Sampler-CSV an den Phasenmarken auf und meldet
  neben min/avg/max auch die Ereignisse, die im Mittelwert untergehen: Roaming,
  Re-Assoc und Verschwinden des Clients.

- tp6-bufferbloat-messung.sh schickt jetzt User-Agent und Referer mit. Ohne die
  beantwortet speed.cloudflare.com /__down mit 403 und einem Byte: die Flows
  sind sofort tot, die Ping-Reihe sieht sauber aus, und die Download-Seite gilt
  faelschlich als bufferbloat-frei. Aufgefallen ist es nur, weil der Sampler am
  Core 164 kbit statt 50 Mbit zeigte.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-20 22:51:11 +02:00
parent f3d8779c96
commit 3aac2eeb8a
6 changed files with 735 additions and 8 deletions

View File

@@ -21,6 +21,13 @@ SETTLE=30 # Sekunden, die die Sättigung stabil läuft, bevor ge
UPLOAD_RATE_KB=430 # ~430 KB/s je Flow × 3 = ~10,3 Mbit (wie 2026-06-16)
UPLOAD_FILE="$(mktemp -t tp6-upload).bin"
# 🔴 speed.cloudflare.com blockt curl mit Default-User-Agent: /__down antwortet dann mit
# 403 und 1 Byte — die Flows sind sofort tot, die Ping-Reihe sieht sauber aus, und man
# haelt eine NICHT-Messung fuer "kein Bufferbloat". Deshalb UA + Referer mitschicken.
# (Am 2026-08-20 genau so passiert; /__up war davon nicht betroffen.)
CF_UA="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15"
CF_REF="https://speed.cloudflare.com/"
say() { printf '\n\033[1;36m== %s ==\033[0m\n' "$*"; }
warn() { printf '\033[1;33m⚠️ %s\033[0m\n' "$*"; }
@@ -50,7 +57,7 @@ mkfile 200M "$UPLOAD_FILE" 2>/dev/null || dd if=/dev/zero of="$UPLOAD_FILE" bs=1
# Linerate-Probe: wie schnell ist der Upload wirklich? (Runbook §2.3/§5.4)
say "Linerate-Probe (10 s voller Upload)"
curl -s -o /dev/null --max-time 10 \
curl -s -o /dev/null --max-time 10 -A "$CF_UA" -e "$CF_REF" \
-w " Upload-Linerate: %{speed_upload} B/s\n" \
--data-binary @"$UPLOAD_FILE" "https://speed.cloudflare.com/__up" || true
echo " (Referenz 2026-06-16: ~1,28 MB/s = 10,3 Mbit. Deutlich mehr = Tarif geändert → Rate unten anpassen.)"
@@ -61,9 +68,9 @@ ping -c "$PINGS" "$TARGET"
# 2. Upload-Sättigung + Ping unter Last
say "2. Upload-Sättigung (3 Flows × ${UPLOAD_RATE_KB} KB/s) — ${SETTLE}s stabilisieren"
curl -s -o /dev/null --limit-rate "${UPLOAD_RATE_KB}K" --data-binary @"$UPLOAD_FILE" "https://speed.cloudflare.com/__up" & UP1=$!
curl -s -o /dev/null --limit-rate "${UPLOAD_RATE_KB}K" --data-binary @"$UPLOAD_FILE" "https://speed.cloudflare.com/__up" & UP2=$!
curl -s -o /dev/null --limit-rate "${UPLOAD_RATE_KB}K" --data-binary @"$UPLOAD_FILE" "https://speed.cloudflare.com/__up" & UP3=$!
curl -s -o /dev/null -A "$CF_UA" -e "$CF_REF" --limit-rate "${UPLOAD_RATE_KB}K" --data-binary @"$UPLOAD_FILE" "https://speed.cloudflare.com/__up" & UP1=$!
curl -s -o /dev/null -A "$CF_UA" -e "$CF_REF" --limit-rate "${UPLOAD_RATE_KB}K" --data-binary @"$UPLOAD_FILE" "https://speed.cloudflare.com/__up" & UP2=$!
curl -s -o /dev/null -A "$CF_UA" -e "$CF_REF" --limit-rate "${UPLOAD_RATE_KB}K" --data-binary @"$UPLOAD_FILE" "https://speed.cloudflare.com/__up" & UP3=$!
sleep "$SETTLE"
say "2a. Ping unter Upload-Last"
ping -c "$PINGS" "$TARGET"
@@ -71,9 +78,9 @@ kill "$UP1" "$UP2" "$UP3" 2>/dev/null; wait 2>/dev/null
# 3. Download-Sättigung + Ping unter Last
say "3. Download-Sättigung (3 parallele Downloads) — ${SETTLE}s stabilisieren"
curl -s -o /dev/null "https://speed.cloudflare.com/__down?bytes=2000000000" & DL1=$!
curl -s -o /dev/null "https://speed.cloudflare.com/__down?bytes=2000000000" & DL2=$!
curl -s -o /dev/null "https://speed.cloudflare.com/__down?bytes=2000000000" & DL3=$!
curl -s -o /dev/null -A "$CF_UA" -e "$CF_REF" "https://speed.cloudflare.com/__down?bytes=2000000000" & DL1=$!
curl -s -o /dev/null -A "$CF_UA" -e "$CF_REF" "https://speed.cloudflare.com/__down?bytes=2000000000" & DL2=$!
curl -s -o /dev/null -A "$CF_UA" -e "$CF_REF" "https://speed.cloudflare.com/__down?bytes=2000000000" & DL3=$!
sleep "$SETTLE"
say "3a. Ping unter Download-Last"
ping -c "$PINGS" "$TARGET"