Skip to main content

June 2026 Releases

This page archives releases published in June 2026.

2026-06

v1.4.0

Release Scope

  • Minor Release. v1.4.0 focuses on egress control, upstream diagnostics, and concurrent upstream decision making for complex network environments. It introduces network.outbound as a unified egress layer, adds the oxidns probe upstream diagnostics command, extends forward with configurable concurrent response selection, and improves cache behavior, DoH serving, WebUI upgrade flow, and query recorder read performance.
  • Existing configurations that do not set network.outbound.default usually upgrade directly. When a default outbound profile is configured, upstreams without explicit outbound inherit it. SOCKS5 proxying applies only to TCP, DoT, and DoH2; UDP, DoQ, and DoH3 upstreams ignore SOCKS5 proxy settings.

Changes

  • feat(network): add network.outbound for centralized resolver nameservers, default egress profiles, and SOCKS5 proxy settings. download, upgrade, http_request, forward upstreams, outbound resolvers, webhooks, and related network paths can now reuse the same egress policy.
  • feat(cli): add oxidns probe upstream <addr> for upstream reachability checks, resolved IP reporting, protocol handshake checks, TCP / DoT pipeline behavior detection, concurrent behavior classification, and human / JSON summaries. This is useful before enabling network.outbound, bootstrap, pipeline, or mixed-protocol upstreams.
  • feat(forward): add response_selection for concurrent upstreams, with fastest, balanced, prefer_positive, and consensus modes. forward.concurrent is raised to a bounded 1..=32 range and is clamped to the number of configured upstreams.
  • feat(cache) / perf(cache): add cache.min_positive_ttl to skip caching positive responses with low effective TTLs. Cache hit and TTL rewrite hot paths are optimized, and lazy refresh no longer removes newer cache entries when an older refresh returns a low-TTL response.
  • feat(server): DoH serving now supports HTTP/1.1 and HTTP/2 negotiation on the same listener. http_server.entries[] also supports entry-level json_api for name / type style DNS queries.
  • feat(webui) / fix(webui): WebUI can configure network.outbound profiles and show outbound runtime metrics. Upgrade flow now has status display and an overlay, restart / upgrade polling detects fresh backend instances, and HTML entry points use no-cache to avoid stale shells after upgrades.
  • feat(query_recorder): add a derived questions index table and reader_concurrency to improve qname / qtype filters, top qname / qtype / latency queries, and large SQLite recorder reads.
  • feat(sequence) / docs: reject supports named RCODEs such as reject NXDOMAIN and reject SERVFAIL; add explicit reject 0 soa; add a DNS code reference for common RCODE, QCLASS, and QTYPE values.
  • refactor / deps / ci: clarify upstream, transport, and forward module boundaries; update hotpath, jiff, bytes, h2, webpki-roots, and syn; update GitHub Actions to actions/checkout@v7.

Compatibility and Upgrade Notes

  • The root crate version is 1.4.0; oxidns-proto is updated to 0.1.3; the release tag should be v1.4.0.
  • Configurations from v1.3.0 usually upgrade directly if network.outbound.default is not set.
  • If network.outbound.default is configured, review all upstreams without explicit outbound, because they inherit the default profile.
  • SOCKS5 proxying applies only to TCP, DoT, and DoH2. UDP, DoQ, and DoH3 upstreams ignore SOCKS5 proxy settings.
  • Custom builds that use outbound resolver DoT / DoH / DoQ / DoH3 should enable the corresponding resolver-* features.
  • After upgrading, run oxidns probe upstream <addr> against critical upstreams, especially when using network.outbound, bootstrap, pipeline, DoH / DoQ / DoH3, or proxy egress.
  • forward.response_selection, cache.min_positive_ttl, and query_recorder.reader_concurrency are optional and keep default behavior when omitted.

v1.3.0

Release Scope

  • Minor Release. The headline change is turning black_hole into a full interceptor that covers every qtype, alongside broad hardening for upstream pools, bootstrap resolution, deadline / cancellation safety, and RouterOS integration. The Rust module layout is also reorganized around new cli and infra layers while core is narrowed to DNS execution semantics. Runtime configuration remains mostly compatible, but black_hole no-argument defaults and non-A/AAAA handling changed; Rust library embedders must migrate public module paths.

Changes

  • feat(executor): black_hole now supports mode (nxdomain, nodata, null, custom, refused) and applies across all qtypes. With no ips it defaults to nxdomain; legacy ips configurations continue as implicit custom.
  • feat(upstream): upstream pools gain min_conns for optional warm connections. max_conns now has documented range validation, with docs and WebUI schema updates.
  • fix(upstream): pipeline and reuse pools have stronger deadline handling, cancellation safety, slot reclamation, and unusable-connection pruning, reducing hangs and busy retries around connection close, timeout, replacement failure, and upstream recovery paths.
  • fix(upstream): bootstrap servers must be literal IP endpoints, bootstrap answer selection follows valid CNAME chains, and bootstrap queries respect deadlines. HTTP upstream requests also send an Accept header.
  • feat(executor): ros_address_list exposes connect_timeout, send_timeout, and receive_timeout; RouterOS startup scans and persistent-entry sync now run in the background so slow address lists do not block DNS startup, and cleanup revalidates rows before deletion.
  • fix(matcher): rule-file parsing preserves commas inside line expressions, fixing domain / matcher rules that legitimately contain commas.
  • refactor: add src/cli/ and src/infra/; move network, service, upgrade, build_info, errors, tasks, cache, and observability infrastructure under infra; keep core focused on context and rule_matcher.
  • zoneparser: parse more standard RDATA families directly, including A/AAAA, name records, MX/RT/AFSDB, TXT/SPF/AVC/RESINFO, SOA, SRV, and CAA, while keeping RFC3597 generic syntax fallback.
  • query_recorder / internals: extract RDATA JSON serialization and storage helpers to reduce complexity while keeping recorder output paths maintainable.
  • release: fix GitHub Actions release artifact uploads so already-packaged archives are not double-archived.
  • docs(ai): centralize maintainer-facing AI / agent notes under ai/, add a Chinese GitHub Release template, and make release prep explicitly hand off without automatic commit, tag, or push.

Compatibility and Upgrade Notes

  • Root crate version bumped to 1.3.0; oxidns-zoneparser bumped to 0.1.1; crates/macros, crates/proto, and crates/ripset do not need version bumps; the release tag should use v1.3.0.
  • v1.2.3 configs generally upgrade directly. Review black_hole usage carefully: legacy ips configs keep custom semantics, no-argument black_hole now returns NXDOMAIN, and null / custom return NODATA for non-A/AAAA instead of passing through.
  • Upstream bootstrap values must now be IP:port, not hostnames. The new min_conns option defaults to 0, so omitted configs keep lazy connection creation.
  • The new ros_address_list timeout fields are optional and default-compatible. Large shared RouterOS address lists should still be split into OxiDNS-owned lists to avoid expensive management-plane scans.
  • Rust library embedders must migrate public module paths: old top-level network / build_info / upgrade / service and the infrastructure modules previously under core now live under infra; core::context and core::rule_matcher remain.

v1.2.3

Release Scope

  • Patch Release focused on fixing a high-CPU path where TCP / DoT response writer tasks could spin after /api/reload, and on reducing busy retry loops in upstream pools while upstreams are unavailable or restarting. It also adds English WebUI i18n, GitHub token controls for the WebUI upgrade flow, and additional test plus CLI / plugin documentation hardening. No breaking configuration changes.

Changes

  • fix(server): TCP / DoT response writer tasks now exit when the per-connection response channel closes, preventing orphaned writers from spinning after /api/reload cancels connection handlers. A regression test covers the closed-channel path.
  • fix(upstream): Pipeline and reuse upstream pools now apply a short backoff when creating a replacement connection fails, avoiding yield-only retry loops during upstream outages or service restarts.
  • fix(upstream): Saturated pipeline pools still retry responsively with scheduler yielding only, so the new backoff stays limited to failed expansion paths.
  • feat(webui): Added English i18n resources and a localization provider for console pages, plugin definitions, help text, and primary WebUI components.
  • feat(webui): Upgrade checks and apply requests can include an optional GitHub token. The WebUI adds explicit persistence controls and risk guidance, while CLI previews avoid exposing tokens.
  • fix(webui): Hide the upgrade header action when the upgrade state is idle.
  • docs(cli): Documented the build-info command, including JSON output, capability-matrix fields, and release troubleshooting usage.
  • docs(plugin): Corrected documented default values and kept the Chinese and English plugin docs aligned.
  • test: Replaced fixed waits with deterministic synchronization, avoided a Windows cron timer flake, and flushed the query recorder writer before top-clients assertions.

Compatibility and Upgrade Notes

  • Root crate version bumped to 1.2.3; no workspace crate under crates/ changed this cycle (crates/macros, crates/proto, crates/ripset, crates/zoneparser), so none need a version bump; the release tag should use v1.2.3.
  • v1.2.2 configs upgrade directly to v1.2.3 with no new required fields or YAML migration.
  • Long-running deployments that use TCP / DoT inbound servers, frequently call /api/reload, or observe high CPU while upstream DNS services are restarting or unavailable should upgrade.
  • The WebUI GitHub token is used only for GitHub requests in the upgrade check / apply flow. It can be used for a single session or persisted explicitly; leaving it unset preserves the anonymous-request behavior.

v1.2.2

Release Scope

  • Patch Release. The headline addition is an HTTP upgrade API (gated on the plugin-upgrade feature) with a WebUI real-time update-available notification, enabling users to detect new releases, compare versions, and trigger the upgrade flow directly from the WebUI. Also fixes the ${VAR} env-var expansion order (expand after YAML parse, not before) to prevent YAML comment and special-character interference, repairs two WebUI quote-wrap handling issues around ${VAR} form values, and reliably cleans up zombie connections on H2/H3/DoQ upstreams after the remote peer closes. No breaking configuration changes.

Changes

  • feat(upgrade): Added the HTTP upgrade API (behind the plugin-upgrade feature flag). The WebUI gains an update-notification banner that detects available GitHub releases, displays the current vs. latest version comparison, and provides an in-WebUI upgrade entry point.
  • feat(webui): The WebUI upgrade panel now uses the backend plugin-upgrade capability, integrating update detection, upgrade status display, and the upgrade action.
  • fix(upgrade): Fixed the apply state lifecycle and switched to sending all upgrade parameters through the POST body, improving reliability and parameter-passing safety.
  • fix(api): Scoped the upgrade module route registration behind the plugin-upgrade feature, preventing builds without the upgrade capability from exposing related endpoints.
  • fix(config): ${VAR} placeholder expansion now runs after YAML parsing instead of before, fixing interactions where YAML special characters or comment text could interfere with expansion. Also prevents YAML comment content from being treated as expandable text.
  • fix(config): Made expand_env_in_value_with_lookup public so external code can use it directly.
  • fix(webui): Fixed two related bugs where the WebUI was incorrectly stripping or preserving quote-wrapping around ${VAR} placeholder form values.
  • fix(upstream): Zombie H2 (DoH), H3 (DoH3), and DoQ connections are now reliably closed after the remote peer disconnects, preventing connection leaks on long-running deployments.
  • fix(tests): Replaced fixed-duration sleeps with polling in integration tests to reduce spurious flakiness.
  • fix(doc): Corrected the doc-comment formatting for ${qname}.

Compatibility and Upgrade Notes

  • Root crate version bumped to 1.2.2; no workspace crate under crates/ changed this cycle (crates/macros, crates/proto, crates/ripset, crates/zoneparser), so none need a version bump; the release tag should use v1.2.2.
  • v1.2.1 configs upgrade directly to v1.2.2 with no new required fields.
  • The HTTP upgrade API is gated on the plugin-upgrade feature and is available only in standard / full builds; minimal builds are unaffected.
  • Deployments using ${VAR} placeholders in configs where YAML comments appear near the placeholder should upgrade; no config changes are needed and behavior improves automatically.
  • Long-running deployments with H2/H3/DoQ upstreams should upgrade to fix potential connection leaks from zombie connections.

v1.2.1

Release Scope

  • Patch Release delivering a WebUI Basic Auth login flow with unified auth management, draggable plugin canvases, and several WebUI interaction fixes (unapplied-plugin warning, numeric type preservation for select fields, all sequence rules visible in the query record flow canvas). Also fixes an upstream connection-pool deadlock after network outage, makes ${VAR} expansion YAML-quote-aware, and improves ros_address_list concurrent write throughput. No breaking configuration changes.

Changes

  • ros_address_list performance: pipeline concurrent ROS API write operations and remove the post-add re-query step, reducing latency for large address-list updates.
  • upstream connection pool fix: prevent the pool from entering a deadlock state after a network outage, eliminating connection-acquisition stalls on recovery.
  • WebUI: new Basic Auth login flow with a unified auth management entry point; login state persists to localStorage with logout and session-restore support.
  • WebUI fix: show an explicit warning when a plugin is staged but not yet applied; suppress 404 noise.
  • Config fix: ${VAR} env-var substitution now correctly handles placeholders wrapped in YAML quotes, matching the behavior of bare placeholders.
  • WebUI fix: preserve the numeric type of select field values on save, preventing silent coercion to string that caused config validation failures.
  • WebUI: plugin canvases support content-keyed draggable layout; canvas positions are persisted per content key.
  • WebUI fix: the query record flow canvas now renders all sequence rules instead of only a subset.
  • Dependencies: batch patch-and-minor Cargo dependency upgrades (2 packages).
  • CI: build environment upgraded to Ubuntu 24.04; added a release artifact collection step.

Compatibility and Upgrade Notes

  • Root crate version bumped to 1.2.1; no workspace crate under crates/ changed this cycle (crates/macros, crates/proto, crates/ripset, crates/zoneparser), so none need a version bump; the release tag should use v1.2.1.
  • v1.2.0 configs upgrade directly to v1.2.1 with no new required fields.
  • Deployments with management API auth (auth) configured: the WebUI login flow automatically uses the existing Basic Auth credentials — no config changes needed, just refresh the WebUI after upgrading.
  • Deployments using ros_address_list with high-volume address writes will see improved concurrent write throughput with no config changes required.
  • Deployments that quote ${VAR} placeholders in YAML (e.g. value: "${MY_VAR}") will find that expansion now behaves identically to bare placeholders; any extra quoting added to work around the old behavior can be simplified, though the old form remains valid.

v1.2.0

Release Scope

  • Minor Release. The headline change is a full compile-time feature system (minimal / standard / full bundles plus granular flags) that gates DoQ / DoH3, DoT / DoH, api / webui / metrics, optional plugins, and TLS / HTTP dependencies behind opt-in features, and exposes the compiled capability set to the CLI, the API, and the WebUI. Two new plugins land in the same cycle: ip_selector (response-IP selection) and dynamic_domain_set + learn_domain (writable dynamic domain sets with online learning). The env matcher gains multi-condition support, the WebUI gets drag-and-drop card reordering and a dynamic_domain_set rule manager, and several memory / lifecycle bugs in the cache, DoH listener startup, and WebUI upgrade path are fixed. Multiple Cargo dependencies are bumped.
  • Contains one breaking change: the env matcher drops the legacy two-token "KEY" "VALUE" parsing. Configs that used the old form for equality matching must migrate to KEY=VALUE (see upgrade notes below).

Changes

  • Compile-time feature system: new minimal / standard (recommended default) / full bundles covering server-doq / server-doh3 / server-dot / server-doh, upstream-doq / upstream-doh3 / upstream-dot / upstream-doh, api / webui / metrics, plus granular plugin flags (plugin-mikrotik, query-recorder, ipset, cron, script, download, http-request, reverse-lookup, upgrade, arbitrary, plugin-ip-selector, plugin-dynamic-domain) and provider flags (provider-protobuf, adguard-rule). Disabled protocols / plugins referenced from a config now fail with a clear "not compiled in; rebuild with --features ..." error. The minimal release binary is ~8.9 MB (vs ~21 MB for full, ~58% smaller).
  • Release artifacts are bundle-aware: CI and release flows split per bundle, adding Linux musl minimal / standard archives (the full archive name is unchanged). upgrade and the installer scripts can resolve a specific bundle. standard now bundles api, webui, query_recorder, and upgrade.
  • Runtime capability reflection: the CLI and system/health API report the active bundle and supported plugin kinds; the WebUI disables unsupported plugin kinds in create, reference picker, card, and detail views.
  • New plugin ip_selector (executor): A / AAAA response-IP sorting / filtering with bounded TCP / ping probing, score caching, in-flight probe coalescing, DNSSEC-safe handling, and fail-open fallback. Rejects compatibility aliases and unknown config fields — only native OxiDNS configuration is exposed.
  • New plugins dynamic_domain_set (provider) + learn_domain (executor): file-backed writable provider with hot snapshots, deduplication, API rule management, and explicit reload; learn_domain writes filtered queries / responses into a dynamic domain set without SQLite persistence or a full reload. The WebUI gains a Detail tab to list / add / remove / clear rules for dynamic_domain_set.
  • env matcher: each argument is now parsed as an independent expression, so a single matcher can express multiple conditions. KEY=VALUE is the recommended exact-match syntax; KEY:VALUE remains a documented alias; values containing separators stay supported. Breaking: the legacy ["KEY", "VALUE"] two-token form now means "both env vars KEY and VALUE exist" instead of KEY == VALUE.
  • WebUI drag-and-drop card reordering on both the dashboard and the plugin center. The plugin center rewrites the config file's plugins order (staged then saved via the 应用更改 pill), as a subset reorder inside the active type tab that preserves other types' relative positions; disabled while a search query is active. Dashboard pinned-card order is a frontend-only preference persisted to localStorage and never touches the config file.
  • ConfigField gains a fullWidth flag (applied to dynamic_domain_set.path); fixes uneven config form columns caused by @container queries being unable to style their own container.
  • sequence step recording is now behind an internal _sequence-step-recording feature opted into by query_recorder, so builds without the recorder compile the step fields and capture calls out entirely.
  • Cache fixes: treat size as an entry limit instead of startup map capacity (no more large up-front allocations for high cache limits); enforce the configured limit immediately after startup and after API dump loads; regression coverage for oversized large-cache dumps.
  • Server fix: pre-flight HTTP/3 feature and TLS requirements before spawning the HTTP/2 listener and clean up partially started HTTP server tasks when startup fails, preventing leaked DoH listener handles.
  • upgrade fix: infer the WebUI asset path from the runtime config so it works correctly with --working-dir overrides.
  • Config fix: disambiguate runtime placeholders ({...}) from env placeholders during expansion.
  • dynamic_domain_set provider hardening: serialize append staging, write each new rule on its own line, validate rules before writing to disk, keep in-memory structures consistent with file state; skip API route registration when the api feature is off.
  • Documentation: new PLUGIN_DEV.md plugin development and registration guide, new SECURITY.md policy, custom-build docs (zh) and a preset capability matrix in quickstart; a roadmap timeline component; install docs no longer reference GHCR; TLS configuration doc formatting fix.
  • Dependencies: socket2 0.6.3 → 0.6.4, jiff 0.2.24 → 0.2.28, wincode 0.5.4 → 0.5.5, http 1.4.0 → 1.4.1, hyper 1.9.0 → 1.10.1, rusqlite 0.39 → 0.40, windows-service 0.6 → 0.8.1.
  • Misc: IpSelectorCacheConfig denies unknown fields; fix a runtime test serialization deadlock; clean up cancelled ip_selector probes; CI fixes covering minimal / standard / full feature combinations and Windows tests; add a reusable custom-build workflow and a minimal build.config.yml example.

Compatibility and Upgrade Notes

  • Root crate version bumped to 1.2.0; no crates/ workspace crate changed this cycle (crates/macros, crates/proto, crates/ripset, crates/zoneparser), so none need a version bump; the release tag should use v1.2.0.
  • v1.1.4 configs upgrade directly on the default (full) or standard bundle. If you choose minimal or a custom feature subset, references to plugins / protocols that were not compiled in fail at startup with "not compiled in; rebuild with --features ..." — add the missing feature or remove the corresponding config entry.
  • Breaking — env matcher: the legacy two-token form env: ["KEY", "VALUE"] (meaning $KEY == VALUE) must be migrated to env: ["KEY=VALUE"] or env: ["KEY:VALUE"]. If you intentionally want the new semantics, confirm that you really mean "both env vars exist". See the migration note in docs/docs/migrate-from-mosdns.mdx.
  • For minimized deployments you can build with --no-default-features --features minimal (or standard); the release channel now ships minimal / standard / full Linux musl archives, and upgrade / the installer scripts support explicit bundle selection. Deployments that need WebUI, query_recorder, or upgrade should stay on standard or full.
  • Large-cache deployments (e.g. size > 200000) should upgrade: previous builds pre-allocated an oversized map and did not strictly enforce the limit after API dump loads; memory now stays aligned with the configured cap.
  • Deployments running DoH without DoH3, or DoH3 without the required TLS configuration, should upgrade: previously a failed HTTP/3 init could leave the HTTP/2 DoH listener leaked. The startup path now pre-validates and cleans up partially spawned tasks.
  • dynamic_domain_set / learn_domain are gated behind the optional plugin-dynamic-domain feature and ip_selector behind plugin-ip-selector. Both are included in standard / full; for custom minimal builds enable the corresponding features explicitly.

Back to the Release Notes index