sniproxy 0.9.19 (2026-02-06)
===============================

* Performance: SO_SPLICE zero-copy forwarding on OpenBSD eliminates user-space
  copies after the initial handshake; PCRE2 JIT compilation speeds backend regex
  matching 2-10x; HPACK dynamic table uses a ring buffer for O(1) inserts;
  TCP_NODELAY is set on both client and server sockets; table hostname cache
  grows from 256 to 1024 entries; redundant ev_io stop/start cycles and buffer
  zeroing on pool acquire are eliminated; TLS extension validation is merged
  into a single pass; per-backend single-entry match cache removed in favor of
  the table-level cache.
* Security: TLS extension count limit is now enforced consistently across all
  parsing paths including supported_versions; spliced connections are explicitly
  unspliced before idle timeout close to avoid kernel-side data leaks; SO_SPLICE
  cleanup failures are logged for debuggability.
* Bug fixes: Fix data corruption in buffer_coalesce optimization path, double
  close of file descriptors in ipc_crypto_recv_msg and logger LOGGER_CMD_DROP,
  errno clobbered before restart check in resolver_ipc_cb, reload_tables
  skipping consecutive table removals, accept_listener_arg returning success on
  invalid argument, listeners_reload ignoring init_listener failure, ambiguous
  prefix matching in accept_resolver_mode and lookup_syslog_facility, NULL
  pointer dereference in hpack_add_entry on malloc failure, overlapping memcpy
  in new_address port stripping, and blocking nanosleep retry loop in connect
  path.
* API: Getter/setter functions for connection header/idle timeouts, TLS
  extension limits, HTTP/2 frame and header count limits, and XMPP max header
  length allow programmatic tuning of protocol guardrails.

sniproxy 0.9.18 (2026-01-02)
===============================

* XMPP: Added `protocol = xmpp` listener support that parses the stream `to`
  attribute to route XMPP (including STARTTLS) connections by hostname; includes
  dedicated parser tests and a fuzz harness.
* Fuzzing: libFuzzer builds disable ASan ODR indicators and stub HTTP/TLS
  protocol pointers in the listener ACL fuzzer are weak so the real
  implementations can link without multiple-definition errors.

sniproxy 0.9.17 (2025-12-19)
===============================

* Security: IPC crypto rejects frames with generation jumps greater than 16,
  preventing attacker-crafted UINT32_MAX generations from forcing billions of
  rekey loops.
* Packaging/CI: release-packages workflow downloads autoconf 2.71 from GNU and
  kernel mirrors before falling back to ftp.gnu.org, reducing timeout failures
  when building release artifacts.

sniproxy 0.9.16 (2025-12-16)
===============================

* IPC crypto: Protocol bumped to IPC2 with an authenticated generation field,
  making rekey detection deterministic, auto-rekeying receivers after missed
  epochs, rejecting stale-generation frames to block replay-driven hangs, and
  keeping time-based rekeys working even when traffic is sparse.
* Tests: ipc_crypto debug and time-based rekey harnesses exercise the IPC2
  protocol and auto-resync behavior.

sniproxy 0.9.15 (2025-12-15)
===============================

* Security: Binder helper now validates AF_INET/AF_INET6/AF_UNIX stream socket
  requests against the listener allowlist, seccomp filters are
  process-specific, and IPC replay protection enforces strictly monotonic
  counters.
* TLS/DNS: DNS-over-TLS upstreams accept a configurable minimum TLS version
  (default tls1.2) and too-old ClientHello versions are rejected rather than
  routed to fallback backends.
* Reliability: Logger child health watchdog detects stalls, backend regex cache
  initialization failures no longer crash lookups, global ACL policy state is
  reset on reload, EINTR connect retries were fixed, and rate-limit OOM paths
  reject connections with exponential backoff.
* Documentation: README/man pages were refreshed and the splice(2) mention was
  removed.

sniproxy 0.9.14 (2025-12-03)
===============================

* Breaking change: DNS-over-TLS nameserver entries using IP literals now require
  either an explicit TLS hostname (`dot://IP/hostname`) or `/insecure`; bare
  IP-only DoT entries are rejected to avoid silent certificate skipping.
* Reliability: Fatal exit paths now log the failure reason before terminating,
  covering daemonization, privilege drops, and child process handoff failures.

sniproxy 0.9.13 (2025-11-25)
===============================

* Packaging/CI: Release workflow now discovers Rocky Linux releases via mirrors
  and Docker tags, builds both latest and previous Rocky majors with consistent
  jobs, falls back to microdnf when dnf is missing, and the openSUSE autoconf
  download uses a mirrored source when ftp.gnu.org is unavailable.
* Testing: Buffer tests create/destroy a dedicated libev loop to stop leaks,
  Valgrind workflow runs from the tests directory and surfaces failures, and
  the buffer leak regression is fixed.
* Bug fixes: Resolved a use-after-free when config files have incorrect
  permissions.

sniproxy 0.9.12 (2025-11-24)
===============================

* Packaging: rpmbuild now preserves distribution `%{optflags}` while appending
  the libev include path, drops the unused perl dependency, ships the missing
  `hostname_sanitize.h` in release tarballs, and the release-packages workflow
  can be triggered manually to build RPM/DEB artifacts on demand.
* Installation: Remove the `sniproxy` wrapper so only the real daemon is
  installed under sbin, avoiding duplicate or stale binaries on PATH.
* Tests: Added a resolver response fuzz harness with fuzz-only resolver helpers,
  expanded the libev stub to cover timers/signals/loop lifecycle, and fixed a
  resolver fuzz leak to keep fuzz runs stable.

sniproxy 0.9.11 (2025-11-23)
===============================

* Security: HTTP parsing now enforces a configurable `http_max_headers` guard
  (default 100), TLS ClientHello parsing counts extensions before iterating
  through them, and IPC crypto rejects frames via constant-time dummy decrypts
  that use dedicated zero_tag buffers so failure timing and nonce contents stay
  hidden.
* Reliability: All absolute-path directives are canonicalized, the config
  parser wires typed cleanup hooks so repeated resolver/logger/listener ACL
  blocks free their previous allocations, resolver restart paths serialize the
  pending list, and assertions in address/table helpers were replaced with
  runtime guardrails to avoid crashes on malformed input.
* Tooling/Tests: The deprecated `sniproxy-cfg` binary/man page were removed, a
  hardened `scripts/sniproxy.service` unit now ships while the wrapper script
  is gone so the daemon only installs under sbin, GitHub releases build
  Debian/RPM packages, and the fuzzing suite gained address/table/listener
  ACL/ipc harnesses with quieter logging by default.

sniproxy 0.9.10 (2025-11-22)
===============================

* Security: Temporary-file directories now use lstat() checks for /var/run and
  /tmp fallbacks plus the existing O_NOFOLLOW open, closing the last symlink
  attack window before dump generation.
* Robustness: Unix-domain listener/target parsing forcibly null-terminates
  sun_path after strncpy(), and cfg_tokenizer always null-terminates buffers
  even when hitting EOF or buffer limits.
* DNS: Configuration reloads and startup both apply the per-client DNS query
  cap together with the global limit so resolver throttles stay in sync.

sniproxy 0.9.9 (2025-11-21)
==============================

* Security: PROXY header emission now checks buffer capacity, logs the client
  when the header cannot be appended, and aborts routing instead of silently
  continuing; sockaddr parsing validates sa_len bounds, copy_sockaddr_to_storage
  clamps copies to the destination size, and backend match caching rejects
  lengths that would overflow allocations.
* Networking: Per-client DNS concurrency limits stack on the existing global cap
  so abusive clients cannot starve other lookups, the defaults rise to 16 per
  client and 512 overall with resolver max_concurrent_queries(_per_client)
  options, and address parsing handles optional trailing ports iteratively with
  centralized apply_port_if_needed logic while enforcing a maximum parser
  recursion depth.
* Crypto: ipc_crypto_seal verifies header/tag overhead, halts once the send
  counter reaches UINT64_MAX, and refuses SIZE_MAX-topping frames; derive_key now
  rejects HKDF labels longer than 1024 bytes before allocating.
* Reliability: Buffer helpers assert read/write offsets never exceed capacity and
  setup_write_iov bails out when a buffer reports a larger length than it
  allocated, preventing corruption before data hits the socket.

sniproxy 0.9.8 (2025-11-20)
==============================

* Security: libpcre2 is now the sole supported regex backend across runtime,
  fuzzers, and packaging; all builds fail fast if the legacy PCRE1 headers or
  libraries are missing.
* Security: HKDF info buffers are wiped before free, oversized labels are
  rejected, DNS resolver cancellation uses an explicit memory fence, and
  temporary connection dumps rely on `mkostemp()` with CLOEXEC/NOFOLLOW.
* Networking: Resolver blocks can now use DNS-over-TLS upstreams via
  `dot://address/hostname` entries, verifying upstream certificates with the
  system trust store.
* Hardening: configuration reloads re-check file permissions, path directives
  require absolute paths, and resolver search domains are treated as literal
  suffixes instead of being parsed as hostnames.
* Tooling/Docs: README, ARCHITECTURE.md, Debian/RPM metadata, and tests now
  describe the libpcre2 dependency and other behavioral refinements for 0.9.8.

sniproxy 0.9.7 (2025-11-19)
==============================

* DNS: resolver blocks now default to `dnssec_validation relaxed`, enabling AD
  bit enforcement whenever upstream supports DNSSEC without requiring manual
  configuration tweaks.
* Security: sniproxy refuses to load configuration files that
  are group/world accessible by validating permissions on the opened descriptor,
  ensuring both initial startup and reloads uphold the guardrail.
* Documentation: README, architecture notes, and man pages were refreshed to
  describe the DNSSEC default, resolver requirements, and stricter configuration
  permission enforcement.

sniproxy 0.9.6 (2025-11-18)
==============================

* Security: Harden per-IP rate limiting and parser guardrails with FNV-1a hashes,
  collision cutoffs, HTTP header caps, TLS extension limits, and IPC payload clamps
  to block CPU or memory exhaustion attempts.
* DNS: arc4random()-seeded query IDs, leak-resistant handle tracking, and
  mutex-protected restarts prevent counter drift, leaks, or use-after-free in
  resolver lifecycle transitions.
* Reliability: shrink candidate queues now cap at 4096 entries with active
  trimming, buffer growth failures close connections explicitly, and log
  duration math clamps wraparound to 0.0.
* Hardening: secure memory wiping, PID file sanity checks, and buffer pool magic
  numbers detect corruption and ensure sensitive state never lingers in RAM.

sniproxy 0.9.5 (2025-11-15)
==============================

* Performance: cached ev_now() readings and idle hysteresis reduce needless wakeups and buffer thrash.
* Reliability: resolver crash logging avoids noisy write/writev warnings on Linux builds.
* CI: fuzz workflow auto-selects a libFuzzer-capable clang and surfaces compiler diagnostics.

sniproxy 0.9.4 (2025-11-14)
==============================

* Resource: connection_buffer_limit/client_buffer_limit/server_buffer_limit cap per-connection buffering.
* Security: configs with group/world permissions now abort startup instead of warning.
* IPC: helper children close all inherited descriptors other than their IPC socket.

sniproxy 0.9.3 (2025-11-12)
==============================

* Security: privilege dropping now verifies real/effective UID and aborts if root.
* Security: sniproxy warns when config files are readable or executable by group/others.
* IPC: binder/logger/resolver channels now encrypt control traffic and tighten validation/error reporting.
* Performance: idle connection buffers shrink proactively once a soft memory budget is exceeded.
* Resource: new connection_buffer_limit/client_buffer_limit/server_buffer_limit directives cap per-connection buffering.

sniproxy 0.9.2 (2025-11-10)
==============================

* Reliability: resolver restarts keep pending DNS queries and
  automatically retry after the child process respawns.
* Reliability: binder helper respawns on IPC failures and uses
  length-prefixed framing to handle partial reads safely.
* Networking: outbound connects retry transient EADDRNOTAVAIL
  errors to smooth bursts of transparent proxy traffic.
