Files
BARANTMail/ResolverThreadScope.h
Brad ArantandClaude Sonnet 5 407cc2e915 Add per-domain DKIM signing, admin console TLS, log rotation, and resolver timeout scoping
- DKIM signing was hardcoded to one domain; now keyed per-domain off
  the sending address, fixing mail for every domain but the original.
- Admin console (port 1027) is now TLS-wrapped instead of plaintext.
- barantmail.log now rotates by size (config-driven) instead of
  growing unbounded (previously hit 23GB).
- ResolverThreadScope.h: a <setenv> scoping fix for name resolution
  inside a <try> block that previously did not survive its own
  container.
- IMAPArgs.cpp: fixed "UID STORE 1:*" wrongly requiring UID 1 to
  exist, which silently made empty-folder operations delete nothing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-06 17:39:06 +00:00

52 lines
1.9 KiB
C++

#ifndef __ResolverThreadScope_h__
#define __ResolverThreadScope_h__
#include "ThreadScope.h"
#include <resolv.h>
namespace mail {
///
/// ResolverThreadScope
///
/// glibc's classic resolver state (_res, touched by res_query() and
/// getaddrinfo()) is thread-LOCAL, not process-global - confirmed
/// directly (a small standalone test program): a fresh thread's own
/// _res starts zeroed, and its first real resolver call lazily
/// auto-initializes it to glibc's own compiled-in defaults
/// (RES_TIMEOUT=5s, RES_DFLRETRY=2 tries - see /usr/include/resolv.h),
/// completely ignoring anything main() set beforehand. An earlier fix
/// attempt called res_init()+set _res.retrans/_res.retry once in
/// main() before EPoll::start() spawned its worker threads - that
/// only ever affected the MAIN thread's own copy, a pure no-op for
/// every one of the 4 worker threads that actually run
/// SPFChecker/DMARCChecker's res_query()/getaddrinfo() calls for real
/// inbound mail. Same shape as MysqlThreadScope's own reason to
/// exist (see its doc comment) - a client library keying off
/// per-thread state that nothing else in this stack initializes on
/// EPoll's worker threads.
///
/// Bounding these here is what actually keeps a single slow or
/// non-responding DNS server from blocking a worker thread long
/// enough to stall every OTHER connection on every listening port
/// too (SMTP/SMTPTLS/IMAP/POP3/admin all share these same 4 threads) -
/// SPF's own "include:" mechanism can chain up to 10 sequential
/// lookups for a single message, so the per-query bound matters more
/// here than it would for an isolated one-off query.
///
class ResolverThreadScope : public core::ThreadScope {
public:
void onThreadStart() override {
res_init();
_res.retrans = 2;
_res.retry = 1;
}
};
}
#endif