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:
@@ -29,12 +29,17 @@ func (s *Session) handleLogin(ctx context.Context, cmd command) bool {
|
||||
}
|
||||
|
||||
ok, err := s.auth.Authenticate(ctx, cmd.Args[0], cmd.Args[1])
|
||||
if err != nil {
|
||||
return s.writeErr(cmd.Tag, "NO", "LOGIN failed")
|
||||
}
|
||||
if !ok {
|
||||
return s.writeErr(cmd.Tag, "NO", "LOGIN failed")
|
||||
if err != nil || !ok {
|
||||
// Backoff statt Dauerschleife bei wiederholten Fehlversuchen
|
||||
// (Akzeptanzkriterium 3, ING-07).
|
||||
backoff, disconnect := s.guard.RecordAuthFailure()
|
||||
s.guard.Wait(ctx, backoff)
|
||||
if !s.writeErr(cmd.Tag, "NO", "LOGIN failed") {
|
||||
return false
|
||||
}
|
||||
return !disconnect
|
||||
}
|
||||
s.guard.ResetAuthFailures()
|
||||
s.state = Authenticated
|
||||
return s.writeErr(cmd.Tag, "OK", "LOGIN completed")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user