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.outboundas a unified egress layer, adds theoxidns probe upstreamdiagnostics command, extendsforwardwith 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.defaultusually upgrade directly. When a default outbound profile is configured, upstreams without explicitoutboundinherit it. SOCKS5 proxying applies only to TCP, DoT, and DoH2; UDP, DoQ, and DoH3 upstreams ignore SOCKS5 proxy settings.
Changes
feat(network): addnetwork.outboundfor 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): addoxidns 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 enablingnetwork.outbound,bootstrap,pipeline, or mixed-protocol upstreams.feat(forward): addresponse_selectionfor concurrent upstreams, withfastest,balanced,prefer_positive, andconsensusmodes.forward.concurrentis raised to a bounded1..=32range and is clamped to the number of configured upstreams.feat(cache)/perf(cache): addcache.min_positive_ttlto 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-leveljson_apiforname/typestyle DNS queries.feat(webui)/fix(webui): WebUI can configurenetwork.outboundprofiles 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 useno-cacheto avoid stale shells after upgrades.feat(query_recorder): add a derivedquestionsindex table andreader_concurrencyto improve qname / qtype filters, top qname / qtype / latency queries, and large SQLite recorder reads.feat(sequence)/docs:rejectsupports named RCODEs such asreject NXDOMAINandreject SERVFAIL; add explicitreject 0 soa; add a DNS code reference for common RCODE, QCLASS, and QTYPE values.refactor/deps/ci: clarify upstream, transport, and forward module boundaries; updatehotpath,jiff,bytes,h2,webpki-roots, andsyn; update GitHub Actions toactions/checkout@v7.
Compatibility and Upgrade Notes
- The root crate version is
1.4.0;oxidns-protois updated to0.1.3; the release tag should bev1.4.0. - Configurations from
v1.3.0usually upgrade directly ifnetwork.outbound.defaultis not set. - If
network.outbound.defaultis configured, review all upstreams without explicitoutbound, 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 usingnetwork.outbound,bootstrap,pipeline, DoH / DoQ / DoH3, or proxy egress. forward.response_selection,cache.min_positive_ttl, andquery_recorder.reader_concurrencyare optional and keep default behavior when omitted.
v1.3.0
Release Scope
- Minor Release. The headline change is turning
black_holeinto 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 newcliandinfralayers whilecoreis narrowed to DNS execution semantics. Runtime configuration remains mostly compatible, butblack_holeno-argument defaults and non-A/AAAA handling changed; Rust library embedders must migrate public module paths.
Changes
feat(executor):black_holenow supportsmode(nxdomain,nodata,null,custom,refused) and applies across all qtypes. With noipsit defaults tonxdomain; legacyipsconfigurations continue as implicitcustom.feat(upstream): upstream pools gainmin_connsfor optional warm connections.max_connsnow 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 anAcceptheader.feat(executor):ros_address_listexposesconnect_timeout,send_timeout, andreceive_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: addsrc/cli/andsrc/infra/; move network, service, upgrade, build_info, errors, tasks, cache, and observability infrastructure underinfra; keepcorefocused oncontextandrule_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 underai/, 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-zoneparserbumped to0.1.1;crates/macros,crates/proto, andcrates/ripsetdo not need version bumps; the release tag should usev1.3.0. v1.2.3configs generally upgrade directly. Reviewblack_holeusage carefully: legacyipsconfigs keepcustomsemantics, no-argumentblack_holenow returnsNXDOMAIN, andnull/customreturn NODATA for non-A/AAAA instead of passing through.- Upstream
bootstrapvalues must now beIP:port, not hostnames. The newmin_connsoption defaults to0, so omitted configs keep lazy connection creation. - The new
ros_address_listtimeout 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/serviceand the infrastructure modules previously undercorenow live underinfra;core::contextandcore::rule_matcherremain.
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/reloadcancels 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 thebuild-infocommand, 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 undercrates/changed this cycle (crates/macros,crates/proto,crates/ripset,crates/zoneparser), so none need a version bump; the release tag should usev1.2.3. v1.2.2configs upgrade directly tov1.2.3with 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-upgradefeature) 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 theplugin-upgradefeature 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 theplugin-upgradefeature, 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): Madeexpand_env_in_value_with_lookuppublic 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 undercrates/changed this cycle (crates/macros,crates/proto,crates/ripset,crates/zoneparser), so none need a version bump; the release tag should usev1.2.2. v1.2.1configs upgrade directly tov1.2.2with no new required fields.- The HTTP upgrade API is gated on the
plugin-upgradefeature and is available only instandard/fullbuilds;minimalbuilds 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 improvesros_address_listconcurrent write throughput. No breaking configuration changes.
Changes
ros_address_listperformance: pipeline concurrent ROS API write operations and remove the post-add re-query step, reducing latency for large address-list updates.upstreamconnection 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
localStoragewith 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
selectfield 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 undercrates/changed this cycle (crates/macros,crates/proto,crates/ripset,crates/zoneparser), so none need a version bump; the release tag should usev1.2.1. v1.2.0configs upgrade directly tov1.2.1with 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_listwith 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/fullbundles 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) anddynamic_domain_set+learn_domain(writable dynamic domain sets with online learning). Theenvmatcher gains multi-condition support, the WebUI gets drag-and-drop card reordering and adynamic_domain_setrule 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
envmatcher drops the legacy two-token"KEY" "VALUE"parsing. Configs that used the old form for equality matching must migrate toKEY=VALUE(see upgrade notes below).
Changes
- Compile-time feature system: new
minimal/standard(recommended default) /fullbundles coveringserver-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. Theminimalrelease binary is ~8.9 MB (vs ~21 MB forfull, ~58% smaller). - Release artifacts are bundle-aware: CI and release flows split per bundle, adding Linux musl
minimal/standardarchives (thefullarchive name is unchanged).upgradeand the installer scripts can resolve a specific bundle.standardnow bundlesapi,webui,query_recorder, andupgrade. - Runtime capability reflection: the CLI and
system/healthAPI 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_domainwrites 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 fordynamic_domain_set. envmatcher: each argument is now parsed as an independent expression, so a single matcher can express multiple conditions.KEY=VALUEis the recommended exact-match syntax;KEY:VALUEremains a documented alias; values containing separators stay supported. Breaking: the legacy["KEY", "VALUE"]two-token form now means "both env varsKEYandVALUEexist" instead ofKEY == VALUE.- WebUI drag-and-drop card reordering on both the dashboard and the plugin center. The plugin center rewrites the config file's
pluginsorder (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 tolocalStorageand never touches the config file. ConfigFieldgains afullWidthflag (applied todynamic_domain_set.path); fixes uneven config form columns caused by@containerqueries being unable to style their own container.sequencestep recording is now behind an internal_sequence-step-recordingfeature opted into byquery_recorder, so builds without the recorder compile the step fields and capture calls out entirely.- Cache fixes: treat
sizeas 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.
upgradefix: infer the WebUI asset path from the runtime config so it works correctly with--working-diroverrides.- Config fix: disambiguate runtime placeholders (
{...}) fromenvplaceholders during expansion. dynamic_domain_setprovider 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 theapifeature is off.- Documentation: new
PLUGIN_DEV.mdplugin development and registration guide, newSECURITY.mdpolicy, 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:
IpSelectorCacheConfigdenies unknown fields; fix a runtime test serialization deadlock; clean up cancelledip_selectorprobes; CI fixes covering minimal / standard / full feature combinations and Windows tests; add a reusable custom-build workflow and a minimalbuild.config.ymlexample.
Compatibility and Upgrade Notes
- Root crate version bumped to
1.2.0; nocrates/workspace crate changed this cycle (crates/macros,crates/proto,crates/ripset,crates/zoneparser), so none need a version bump; the release tag should usev1.2.0. v1.1.4configs upgrade directly on the default (full) orstandardbundle. If you chooseminimalor 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 —
envmatcher: the legacy two-token formenv: ["KEY", "VALUE"](meaning$KEY == VALUE) must be migrated toenv: ["KEY=VALUE"]orenv: ["KEY:VALUE"]. If you intentionally want the new semantics, confirm that you really mean "both env vars exist". See the migration note indocs/docs/migrate-from-mosdns.mdx. - For minimized deployments you can build with
--no-default-features --features minimal(orstandard); the release channel now shipsminimal/standard/fullLinux musl archives, andupgrade/ the installer scripts support explicit bundle selection. Deployments that need WebUI,query_recorder, orupgradeshould stay onstandardorfull. - 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_domainare gated behind the optionalplugin-dynamic-domainfeature andip_selectorbehindplugin-ip-selector. Both are included instandard/full; for custom minimal builds enable the corresponding features explicitly.