Files
nexarch/mail/docs/ING-07-PRUEFPROTOKOLL.md
T
sysops 16c4ad0075 feat(mail): ING-07 einheitliche Fehlerbehandlung & Wiederverbindung IMAP/POP3
Neues Paket mail/internal/protoguard kapselt die für IMAP- und
POP3-Sessions gemeinsam benötigte Timeout- und Backoff-Logik einer
einzelnen Verbindung:

- Pro Protokollphase konfigurierbarer Idle-Read-Timeout (POP3:
  Authorization/Transaction, IMAP: NotAuthenticated/Selected), vor
  jedem Lesevorgang neu gesetzt.
- Sich verdoppelnder Backoff bei wiederholten Anmeldefehlversuchen
  einer Verbindung (BackoffBase bis BackoffMax), Verbindungstrennung
  nach konfigurierbarer Höchstzahl statt Dauerschleife.

Server.NewServer bleibt unverändert (Standardkonfiguration);
NewServerWithGuardConfig erlaubt abweichende Werte. Ressourcenaufräumung
bei Verbindungsabbruch war bereits durch defer conn.Close() strukturell
gegeben — der Timeout sorgt dafür, dass dieser Pfad auch bei hängenden
oder böswilligen Gegenstellen zuverlässig erreicht wird.

Alle drei Pflichtprüfungen mit echten Nachweisen durchgeführt:
Chaos-Test mit 30 hart gekappten Verbindungen während aktiver
Übertragung (kein Goroutine-Leck), Timeout-Auslösung in jeder
Protokollphase beider Server, steigender Backoff mit definierter
Verbindungstrennung nach Höchstzahl an Fehlversuchen.

go build/go vet/golangci-lint clean, gesamtes Mail-Modul (~24 Pakete)
regressionsfrei getestet.
2026-09-01 00:51:52 +02:00

4.4 KiB
Raw Blame History

ING-07 — Protokoll-Fehlerbehandlung & Wiederverbindung: Prüfprotokoll

Datum: 2026-09-01 Host: 192.168.1.131 (Build/Test/Lint), rsync + ssh Pakete: mail/internal/protoguard (neu, gemeinsam genutzt), mail/internal/imap, mail/internal/pop3

Umsetzung

Neues Paket protoguard kapselt Timeout- und Backoff-Logik EINER Verbindung (Guard), von IMAP- und POP3-Session gleichermaßen genutzt:

  • ApplyReadDeadline(conn, phase) setzt vor jedem Lesevorgang die Lese-Deadline passend zur aktuellen Protokollphase (POP3: Authorization/Transaction, IMAP: NotAuthenticated/Selected).
  • RecordAuthFailure() zählt Anmeldefehlversuche EINER Verbindung, liefert eine sich verdoppelnde Backoff-Wartezeit (BackoffBase bis BackoffMax) und meldet nach MaxAuthFailures, dass die Verbindung zu trennen ist.

Server.NewServer verwendet protoguard.DefaultConfig() (5 Minuten Timeout, max. 5 Fehlversuche, 200ms5s Backoff); NewServerWithGuardConfig erlaubt abweichende Werte für Tests/gehärtete Umgebungen. Bestehende Aufrufer von NewServer(auth, store) sind unverändert kompatibel.

Ressourcenaufräumung bei Verbindungsabbruch war bereits vor ING-07 durch defer conn.Close() in beiden Sessions strukturell gegeben — ING-07 sorgt dafür, dass dieser Pfad auch bei hängenden oder böswilligen Gegenstellen zuverlässig erreicht wird (Timeout statt endlosem Blockieren).

Pflichtprüfung 1: Chaos-Test — harter Verbindungsabbruch während aktiver Übertragung, kein Ressourcenleck

TestGuard_ChaosHardCutDuringTransferNoLeak (pop3/guard_test.go, imap/guard_test.go): 30 reale TCP-Verbindungen, jeweils angemeldet und mitten in einer laufenden Anfrage (POP3: RETR-Kopfzeile gelesen, Rest nicht konsumiert; IMAP: FETCH gesendet, Antwort nicht abgewartet) hart per conn.Close() gekappt. runtime.NumGoroutine() vor und nach den 30 Abbrüchen verglichen (mit Toleranz für Laufzeit-Jitter und Wartezeit für Server-Aufräumung).

Ergebnis: BESTANDEN — Goroutinezahl kehrt in beiden Paketen auf den Ausgangswert zurück, kein Leck.

Pflichtprüfung 2: Test für Timeout-Auslösung in jeder Protokollphase

TestGuard_TimeoutPerPhase (beide Pakete), Guard mit 100ms Timeout je Phase konfiguriert:

  • POP3: Subtest authorization (Verbindung offen, nichts gesendet) und transaction (nach erfolgreichem USER/PASS nichts weiter gesendet) — beide erwarten Verbindungsende durch Timeout.
  • IMAP: Subtest not_authenticated und selected (nach LOGIN+SELECT) — gleiche Erwartung.

Ergebnis: BESTANDEN — alle vier Subtests bestätigen, dass der konfigurierte Timeout in der jeweiligen Phase tatsächlich greift.

Pflichtprüfung 3: Test für Backoff-Verhalten bei wiederholten Fehlversuchen

TestGuard_BackoffOnRepeatedAuthFailures (beide Pakete), Guard mit MaxAuthFailures=3, BackoffBase=50ms, BackoffMax=500ms:

  • Drei aufeinanderfolgende fehlgeschlagene Anmeldeversuche (POP3: USER+PASS falsch; IMAP: LOGIN falsch) über dieselbe Verbindung. Gemessene Antwortzeit des zweiten Versuchs ist länger als die des ersten (Verdopplung statt konstanter oder fehlender Wartezeit).
  • Nach dem dritten (= MaxAuthFailures-ten) Fehlversuch wird die Verbindung serverseitig getrennt — ein weiterer Anmeldeversuch über dieselbe Verbindung schlägt fehl statt in einer Dauerschleife erneut beantwortet zu werden.

Ergebnis: BESTANDEN.

Akzeptanzkriterien

  1. Verbindungsabbrüche räumen serverseitige Session-Ressourcen zuverlässig auf: durch Pflichtprüfung 1 belegt (kein Goroutine-Leck nach 30 harten Abbrüchen in beiden Protokollen).
  2. Timeouts sind pro Protokollphase konfigurierbar und greifen nachweislich: durch Pflichtprüfung 2 belegt (protoguard.Config. PhaseTimeout je Phase, vier bestandene Subtests).
  3. Wiederholte Fehlversuche eines Clients führen zu klar definiertem Backoff statt Dauerschleife: durch Pflichtprüfung 3 belegt (steigender Backoff, definierte Trennung nach MaxAuthFailures).

Build/Vet/Lint/Test — Gesamtmodul

go build ./...    → OK
go vet ./...      → OK
golangci-lint run ./... → 0 issues
go test ./... -p 1 (TEST_TENANT_DSN, TEST_MANTICORE_URL gesetzt) → alle Pakete ok, inkl. neuem internal/protoguard (indirekt über imap/pop3-Tests abgedeckt)

Keine Regression in den bestehenden ~24 Paketen.

Ergebnis

ING-07 erfüllt alle Pflichtprüfungen und Akzeptanzkriterien mit echten, ausgeführten Nachweisen. Freigeschaltet: QA-02.