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.
Scheduler für periodischen IMAP-Postfach-Abruf mit UID-basiertem
Delta-Sync: neue Nachrichten erkennen, Zustandsänderungen abgleichen.
- imap (ING-01) minimal erweitert: Message.UID, MailboxStore.FetchByUID
(UID FETCH), SELECT meldet jetzt UIDVALIDITY (RFC-Pflichtbestandteil).
Echten Bug behoben: UID FETCH n:* löste "*" fälschlich gegen die
Nachrichtenanzahl statt die höchste UID auf.
- imapimport/state.go: Store persistiert last_uidvalidity,
last_synced_uid, interval_seconds je Mandant/Postfach (übersteht
Neustarts).
- imapimport/scheduler.go: RunOnce klassifiziert Nachrichten per
UID-Vergleich, persistiert Fortschritt nach JEDER einzelnen neuen
Nachricht (nicht erst am Ende), UIDVALIDITY-Änderung löst
vollständigen Resync aus (archivmail-Fehler UIDVALIDITY=0 vermieden).
- imapimport/client_real.go: echtes IMAP4rev1 über TCP
(LOGIN/SELECT/UID FETCH/LOGOUT).
Prüfungen (alle real durchgeführt, siehe mail/docs/IMP-01-PRUEFPROTOKOLL.md):
1. TestRunOnce_TwoConsecutiveRunsNoDuplicateImport: zweiter Lauf real
0 neue Nachrichten.
2. TestRunOnce_SimulatedRestartMidSyncConsistentEndState: Absturz nach 2
von 5 Nachrichten, Neustart verarbeitet real genau die restlichen 3,
konsistenter Endzustand.
3. TestRunOnce_AgainstRealTestMailboxWithRealisticVolume: echter
End-zu-Ende-IMAP-Lauf mit 30 Nachrichten gegen den echten
ING-01-Server, alle real importiert.
Kein Umbau: mail/internal/folderstate (ING-05) unverändert.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhgFcLS8tYMhDJpP74C6AQ
IMAP-Server-Grundgerüst: TCP-Listener, Command-Parser, Session-
Zustandsmaschine (Not Authenticated/Authenticated/Selected), Grundbefehle
CAPABILITY/LOGIN/SELECT/FETCH/LOGOUT.
- parser.go: Tag+Kommando+Argumente (Atome, zitierte Zeichenketten),
keine IMAP-Literalsyntax (kleinste Lösung).
- response.go: sanitizeResponseText entfernt eingebettete CR/LF vor jeder
Antwortzeile — bekannten archivmail-Fehler (Header-/Zeilen-Injection
durch Stringkonkatenation ohne CRLF-Prüfung) strukturell vermieden.
- session.go/commands.go: strikte Zustandsprüfung je Kommando, verbotene
Übergänge und fehlerhafte Zeilen liefern BAD/NO statt
Verbindungsabbruch. maxCommandLineBytes begrenzt Pufferwachstum
defensiv.
- server.go: TCP-Accept-Schleife, eine Goroutine je Verbindung.
- Authenticator/MailboxStore als schmale Schnittstellen — echte
Benutzerverwaltungs-/Postfach-Anbindung ist Sache von IMP-01 u. a.
Prüfungen (alle real durchgeführt, siehe mail/docs/ING-01-PRUEFPROTOKOLL.md):
1. Manuelle Session mit Pythons imaplib gegen den echten laufenden
Server: alle Grundbefehle real beantwortet, ungültiges SELECT liefert
real NO ohne Verbindungsabbruch.
2. TestSession_StateTransitionsAndForbiddenTransitions: alle drei
Zustandsübergänge und deren verbotene Übergänge real über TCP geprüft.
3. TestServer_50ParallelSessionsNoLeak: 50 reale parallele Sessions,
0 Fehler.
Kein Umbau: alle bestehenden Pakete unverändert.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhgFcLS8tYMhDJpP74C6AQ