fix: IPv4 preference + DNS cache fallback for stable POP3/IMAP connections

- Add DNS_CACHE_FALLBACK_ENABLED setting (default: true)
- Add in-process DNS cache (_dns_cache, _dns_cache_lock, _get/_set_cached_ipv4)
- Add _resolve_ipv4 (async) and _resolve_ipv4_sync: AF_INET lookup, cache on
  success, return cached IP on EAI_AGAIN when fallback enabled
- Add _IMAP4SSLwithSNI: connects to pre-resolved IPv4 but uses original
  hostname for TLS SNI/cert verification
- Add _POP3SSLWithIPv4Pref / _POP3WithIPv4Pref: override _create_socket to
  use pre-resolved IPv4 while keeping original host for POP3_SSL SNI
- Add _make_pop3_conn factory and _make_imap_client async factory
- Wire IPv4/cache helpers into all 6 connection call-sites (IMAP x3, POP3 x3)
- Distinguish transient DNS (EAI_AGAIN) from permanent in _format_connection_error
- Replace asyncio.get_event_loop() with get_running_loop() in 4 async sites
- All 75 existing unit tests pass unchanged

Agent-Logs-Url: https://github.com/christianlouis/InboxConverge/sessions/be0a3bbd-1af1-408e-b918-84753723154b

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-05-03 20:49:51 +00:00
committed by GitHub
parent 89ebdd2b79
commit 45a2dd8be2
4 changed files with 366 additions and 71 deletions
+9
View File
@@ -95,6 +95,15 @@ class Settings(BaseSettings):
# Apprise (notifications)
APPRISE_ENABLED: bool = True
# Mail connectivity resilience
# When True the app caches the last successfully resolved IPv4 address for
# every mail host and uses that address as a fallback if DNS subsequently
# fails (e.g. EAI_AGAIN / Temporary failure in name resolution). This also
# makes every outgoing POP3/IMAP connection prefer IPv4, avoiding
# ENETUNREACH errors on Docker hosts where IPv6 is not routed to the
# internet.
DNS_CACHE_FALLBACK_ENABLED: bool = True
# Logging
LOG_LEVEL: str = "INFO"