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.
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
# 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, 200ms–5s 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.
|
||||
Reference in New Issue
Block a user