Release Notes
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.
2026-05
v1.1.4
Release Scope
- Patch Release reducing memory footprint and reload cost on the provider and rule-matching paths, plus WebUI fixes for mobile config-editor and plugin-filter usability, query-recorder chart labels, and self-hosting the Monaco editor. Also adds a "Migrate from mosdns" guide. This release introduces no breaking configuration changes and leaves the query hot path unchanged.
Changes
- The
client_ip/resp_ip/ptr_ipinline IP matchers now compile viafinalize_compact, so compiled matchers no longer retain a duplicate copy of the source IP ranges (ip_set/geoipalready did this). finalize_compactnow moves the merged IPv6 ranges into the compiled matcher instead of cloning them.geoipfeeds CIDR bytes straight into the matcher viaadd_v4_network/add_v6_network, skipping the per-entryStringformat + reparse round trip and speeding up load and reload.adguard_rulebadfilterresolution uses a HashSet built once instead of an O(n²) rescan that reallocated the cache key on every comparison.- Fixed the WebUI config editor and plugin filters being unusable on mobile.
- Fixed Top-N labels being truncated in the WebUI query-recorder charts.
- The WebUI Monaco editor is now self-hosted instead of loaded from the jsdelivr CDN, working in offline or restricted-network environments.
- Docs: added a "Migrate from mosdns" guide.
Compatibility and Upgrade Notes
- Root crate version bumped to
1.1.4; nocrates/workspace crate changed, so none need a version bump; release tag should usev1.1.4. v1.1.3configs upgrade directly tov1.1.4with no new required fields.- The provider / matcher optimizations are internal implementation changes; they do not alter matching semantics or the query hot path and require no config changes.
- Deployments using the WebUI config editor in restricted or offline networks benefit from the self-hosted Monaco editor and no longer need external CDN access.
v1.1.3
Release Scope
- Patch Release fixing a Linux
nftsetinterval-set ADD/DEL that was rejected by real kernels with EINVAL, anipsetbyte-order bug inhashsize/maxelem, and a WebUIquery_recordertabs overflow. Also adds an upfront notice on theblack_holeplugin documentation describing an upcoming behavior redesign. This release does not introduce breaking configuration changes.
Changes
- Fixed
nftsetADD / DEL / TEST encoding on interval sets: ADD / DEL now send the two-element list formnftuserspace uses, resolving the EINVAL rejection observed on real kernels (issue #127); TEST sends only the start key and lets the kernel's interval tree resolve containment. Also fixed the per-element timeout byte order and relaxed dump parsing to tolerate unpairedINTERVAL_ENDanchors. - Fixed
ipsetcreate writinghashsize/maxelemin native byte order: on little-endian hosts the kernel would readhashsize=2048as524288. Also removed the strayIPSET_ATTR_LINENO=0nested attribute, aligning with libipset. - Significantly expanded
ripsetwire-format unit and ipset integration test coverage. - Fixed a vertical overflow in the WebUI
query_recorderdetail panel tabs list. - Docs: added a prominent notice to the
black_holeexecutor section announcing the upcomingmodefield (nxdomain/nodata/null/custom/refused) that will cover every qtype, and explaining the motivation; current behavior is unchanged.
Compatibility and Upgrade Notes
- Root crate version bumped to
1.1.3;oxidns-ripsetbumped to0.1.2; release tag should usev1.1.3. v1.1.2configs upgrade directly tov1.1.3with no new required fields.- Linux deployments using the
nftsetplugin againstflags intervalsets should upgrade promptly; without this fix, ADD / DEL is rejected by real kernels with EINVAL. - Linux deployments that let OxiDNS create
ipsetsets with explicithashsize/maxelemshould upgrade; sets pre-created by the externalipsetCLI are unaffected by this fix. black_holebehavior is unchanged in this release, but the upcoming semantic redesign is worth tracking. For domain-level blocking today, prefer configuring both IPv4 and IPv6 fallback addresses (e.g.black_hole 0.0.0.0 :: short_circuit) or usereject 3.
v1.1.2
Release Scope
- Patch Release fixing a Linux
nftsetwrite failure onflags intervalsets, repairing the Windows service installer, and polishing systemd working-directory semantics, the WebUI run log viewer, andquery_recorderranking views. This release does not introduce breaking configuration changes.
Changes
- Fixed
nftsetdecoding set flags with native byte order, which leftis_intervalalways false on little-endian hosts and caused every CIDR add against aflags intervalset to fail withUnsupported entry for set type. Flags are now decoded as big-endian, with a byte-order regression test. - The
nftsetwriter now processes each prefix independently, treatsIpSetError::ElementExistsas a skipped no-op, and aggregates ok / skipped / failed counts into a structured warn log instead of disabling the plugin on a single EEXIST. - Fixed the packaged Debian
systemdunit failing pre-start because of an unwritableWorkingDirectory; runtime-relative paths (including WebUI assets) now use-d/--working-diras the single base. - Fixed Windows install/uninstall scripts: reworked service management, binary path handling, and uninstall ordering to avoid orphaned processes or stale paths.
- WebUI run log viewer adds a wrap toggle, and
LogEntry.timestampnow carries millisecond precision so the UI can show localHH:MM:SS.mmmalongside the existingT+elapsedcolumn for easier correlation with external timelines. - WebUI JSON responses and
query_recorderSSE streams now tolerate non-JSON errors, heartbeat frames, empty payloads, and malformed events, so transient network hiccups no longer surface console errors. query_recorderremoves the fixed 200-row cap on top-client, top-qname, and slow-query stats endpoints; the WebUI rankings and slow-query list gain a “load more” control to navigate larger result sets.- WebUI plugin field documentation is resynced with the Rust plugin configuration.
- Documentation site adds a Hero component, refreshes installation steps and the Docker run command, and adds multi-platform quickstart guidance; also documents the Debian
/etc/oxidnsand/var/lib/oxidnslayout, WebUI symlink behavior, andclient_iptroubleshooting.
Compatibility and Upgrade Notes
- Root crate version bumped to
1.1.2;oxidns-ripsetbumped to0.1.1; release tag should usev1.1.2. v1.1.1configs upgrade directly tov1.1.2with no new required fields.- Linux deployments using the
nftsetplugin againstflags intervalsets should upgrade promptly; without this fix, those sets cannot accept any add on little-endian architectures. - Deb-package upgrades no longer set systemd
WorkingDirectory. If you relied on that value to resolve relative paths, set-d/--working-direxplicitly instead. - Clients of
query_recorderranking APIs can now request largerlimitvalues; existing 200-row responses parse unchanged, so behavior remains compatible.
v1.1.1
Release Scope
- Patch Release adding
query_recorderhistory clearing and tightening the WebUI plugin-deletion workflow. This release does not introduce breaking configuration changes.
Changes
- Added
DELETE /api/plugins/<tag>/recordsforquery_recorder, clearing persisted query records, execution-pathsteps, and the in-memory tail after flushing the background write queue. The response reportscleared_records. - Added a “Clear history” action to the WebUI query records panel with a confirmation dialog, clearing-state feedback, and automatic refresh of records, selected detail, and plugin-hit stats after completion.
- Polished the WebUI plugin delete dialog: wider dependency-impact layout, wrapping for long fields, and clearer source / expected-target / removal-blocker details.
- Fixed delete-dialog cancellation bubbling into plugin cards and opening the plugin detail sheet.
- Fixed “repair in editor” removing the plugin before the user edits config; it now only switches to the editor for manual reference handling.
- Fixed delete icons becoming permanently visible and unclickable when config validation errors are present; the dialog can now open and show the error reason.
Compatibility and Upgrade Notes
- Root crate version bumped to
1.1.1; release tag should usev1.1.1. v1.1.0configs upgrade directly tov1.1.1with no new required fields.query_recorderhistory clearing is optional and does not affect existing record capture, retention cleanup, or stats query behavior.- Clearing history is irreversible and removes persisted query records plus path events for the selected recorder; on production systems, confirm the audit data is no longer needed before using it.
v1.1.0
Release Scope
- Minor Release focused on safer configuration loading, upgrade and restart handling,
query_recorderanalytics, WebUI operations, and refreshed plugin documentation/navigation. This release includes a breakingupgradeconfiguration change; review related configs or automation before upgrading.
Breaking Change
upgraderestart configuration changed from enum-stylerestart: none|serviceand CLI--restart <none|service>to booleanno_restart: trueand--no-restart.- The default behavior changed as well: successful
upgrade applynow restarts the service automatically. To keep the old “do not restart after upgrade” behavior, explicitly setno_restart: trueor pass--no-restart.
Changes
- Configuration loading now supports YAML environment placeholders:
${VAR},${VAR:-default}, and$${...}. Expansion runs during startup,oxidns check, management API validation, and save-time validation, includesincludepaths, and reports missing variables or syntax errors with variable name, line, and column. - Reworked
upgrade applyinto a cross-platform flow. Windows now supports.ziparchive extraction, binary replacement, and WebUI directory upgrades; zip extraction rejects unsafe paths to prevent zip-slip. - Added GitHub token support for upgrades, useful for higher API rate limits or private repositories. CLI uses
--github-token; plugin configuration usesgithub_token. - Successful upgrades now restart by default. CLI upgrades restart the installed service through the platform service manager, while plugin-triggered upgrades request a graceful in-process restart that loads the new binary. To skip restart, use CLI
--no-restartor plugin configno_restart: true. - Added management control
POST /restart. On Unix the process restarts in place withexec; on Windows service deployments it cooperates with SCM restart behavior. OxiDNS also captures the original executable path before binary replacement so Linux restarts do not fail on/proc/self/exe (deleted). query_recordergained aggregate stats APIs and WebUI charts: top clients, top qnames, qtype / rcode distributions, latency histogram, slow-query ranking, and minute/hour query trends. SQLite read/write settings were tuned for these aggregation queries.- WebUI config lifecycle is clearer: top-level
runtime/api/logchanges now prompt for restart instead of hot reload; config rollback chooses hot reload or restart based on the changed fields, and restart progress is shown while the console waits for reconnection. - WebUI plugin management now checks references before deletion, can replace references, remove safely removable references, or jump to the editor for manual repair. Plugin renames update references and ask for confirmation when other plugins are affected.
- Documentation refreshed the plugin overview and sidebar navigation, added the roadmap page, and clarified
redirectrule forms,qname/cnamedomain rules, README roadmap, and disclaimers.
Compatibility and Upgrade Notes
- Root crate version bumped to
1.1.0; release tag should usev1.1.0. v1.0.2DNS resolution configs generally upgrade directly tov1.1.0; environment placeholders are additive and do not affect configs that do not use them.- Breaking Change: old
restart: none|serviceand CLI--restart <none|service>are no longer accepted. Useno_restart: true/--no-restartinstead. To preserve the old “do not restart after upgrade” behavior, setno_restart: trueor pass--no-restart. - Missing
${VAR}placeholders now fail config parsing. Use$${...}for literal${...}, and quote placeholders when environment values may contain YAML-special characters. - New
github_token/--github-tokensupport is optional and does not affect existing public-repository upgrade configs. - Existing
query_recorderdeployments can use the new stats APIs and WebUI charts without config changes. The stats endpoints read SQLite history, so large databases should be monitored for disk and query latency.
v1.0.2
Release Scope
- Patch Release fixing domain-based upstreams depending on local DNS during startup and config validation, and clarifying
bootstrapversusdial_addrresolution precedence.
Changes
- Fixed
forwardaddress validation reusing fullConnectionInfoconstruction. Domain-based upstreams now perform syntax validation only and no longer trigger system DNS resolution during startup validation. - Changed upstream connection-info construction so only literal IPs and explicit
dial_addrvalues become startup-known remote IPs; hostnames remain asserver_nameand are resolved later throughbootstrapor at first connection time. - Clarified the runtime mutual exclusion between
dial_addrandbootstrap: when both are configured,dial_addrtakes precedence,bootstrapis ignored, and initialization emits a warning. - Updated
forwardplugin reference docs and WebUI field descriptions with hostname resolution timing, thebootstrap/dial_addreither-or recommendation, and precedence behavior. - Added regression coverage for deferring domain upstream resolution, preserving the SNI hostname with
dial_addr, anddial_addroverridingbootstrap.
Compatibility and Upgrade Notes
- Root crate version bumped to
1.0.2; release tag should usev1.0.2. v1.0.1configs upgrade directly tov1.0.2with no new required fields.- Domain-based upstreams without
bootstrapordial_addrno longer block startup; the first connection still uses the operating system resolver. - To avoid runtime dependence on local DNS entirely, configure exactly one of
bootstrapordial_addrfor domain-based upstreams. - Existing configs that set both
bootstrapanddial_addrstill start, but onlydial_addris effective.
v1.0.1
Release Scope
- Patch Release fixing DNS response compliance issues, client-IP canonicalization, and WebUI usability problems from
v1.0.0, while adding service management capabilities, installer scripts, and query-auditing UX improvements.
Changes
- Fixed
redirectplugin placing synthetic CNAME records after other answers instead of first, aligning with RFC expectations. - Fixed dual-stack sockets passing IPv4-mapped IPv6 addresses (
::ffff:x.x.x.x) intoDnsContextwithout canonicalization, causingclient_ipmatchers and other IP-dependent logic to misidentify them as IPv6. - Fixed WebUI returning 404 on page refresh and added auto-connect to
/apion first load for full-backend-hosting deployments. - Added
service restartCLI command for restarting OxiDNS when running as a system service. - Added Linux / macOS / Windows hosted-service installer scripts (
install.sh/install.ps1) for one-command install, registration, and service startup. query_recorderpanel gained click-to-filter by matcher row, color-coded latency badges, and Info tooltips on record-count column headers.- WebUI plugin detail sheets, cache dialogs, and config field editor polished: replaced native
confirmwith shadcn AlertDialog, adopted responsive two-column grid layout, and constrained content tomax-w-6xlcentered layout.
Compatibility and Upgrade Notes
- Root crate version bumped to
1.0.1; release tag should usev1.0.1. v1.0.0configs upgrade directly tov1.0.1with no new required fields.- Deployments using dual-stack sockets with
client_ipmatchers, ECS, or IP-dependent policies will see client IPs correctly canonicalized to IPv4 after upgrading. - Installer scripts register the app as a system service by default; set
OXIDNS_INSTALL_SERVICE=0for portable-only installation.
v1.0.0
Release Scope
- Major Release marking OxiDNS's move from an experimental plugin-driven DNS engine to the 1.0 stable line.
v1.0.0officially includes the built-in WebUI management console and management API, plugin runtime, observability, packaging, and stability work sincev0.5.2.
Important Upgrade Notice
- This release completes the project rename to OxiDNS. The GitHub repository, release assets, binary name, package metadata, service files, README files, docs site, logo, and startup banner now use
oxidns. - Older automatic upgrade flows still point at the pre-rename project and release assets, so they cannot upgrade directly to
v1.0.0. When upgrading from an older build, manually download the matching OxiDNS release package, replace the binary, and deploy the bundled WebUI static assets. - After this one-time manual migration, future upgrades should use the new
svenshi/oxidnsrepository andoxidns-*release assets.
WebUI Capabilities
- OxiDNS WebUI brings runtime status, configuration, plugins, metrics, logs, query auditing, and cache management into one console, reducing day-to-day reliance on scattered CLI commands, log files, and handwritten API calls.
- Configuration management is safer for production use: YAML editing, live validation, config history, diff review, apply, and rollback live in one workflow, so complex policy changes can be reviewed before they take effect and recovered more easily.
- Plugin orchestration is easier to understand: plugin topology, plugin details, structured configuration, and the sequence composer make the DNS request path visible and reduce YAML reference mistakes, missing dependencies, and troubleshooting time.
- Troubleshooting is more direct: metrics, live logs, query records, execution flow, and cache details can be inspected together, making it easier to trace a problematic domain to matched rules, upstream behavior, cache state, and final responses.
- Deployment and access are simpler: the WebUI ships with release archives, Docker images, Debian packages, and the
upgradeflow, and OxiDNS can host the static assets directly from the management API so one process serves both the API and the console.
Changes
- Reworked the management API into a prefixed unified entry point, adding auth/CORS support, runtime state, log streaming, metrics, config save/apply/rollback, and plugin API aggregation.
- Replaced the mutable global plugin registry with an immutable catalog plus runtime manager, simplified plugin factory creation context, hardened reload paths, and split registry internals into catalog, context, init_plan, and runtime modules.
- Added a shared plugin metrics layer covering servers, forward upstreams, cache, query recorder, and side-effect executors, with unified management API exposure.
- Expanded
query_recorderwith sampled matcher-hit stats, filtering, execution-flow visualization, record details, and cleaned-up model/store structures. - Added cache management APIs for reading cached DNS response details, TTLs, hit metadata, record contents, and cache snapshots.
- Updated
upgrade, release, Docker, Debian packaging, systemd service files, and CI workflows for the OxiDNS 1.0 release path. - Completed the project branding migration from ForgeDNS to OxiDNS across GitHub templates and all user-facing project identity.
- Performance and stability work includes disabling Nagle on TCP upstreams, reducing split-lock pressure, moving dual-selector preferred probing out of forward, supporting dual-stack port-only listeners, and hardening global runtime-manager reloads.
- Refreshed README, quickstart, configuration, API, plugin reference, scenarios, benchmarks, and MikroTik policy routing documentation.
Compatibility and Upgrade Notes
- The root crate version is now
1.0.0; the release tag should bev1.0.0. - Existing
v0.5.2DNS resolution configs should generally upgrade directly. This release mainly introduces the complete WebUI, management API, metrics, and packaging capabilities. - When upgrading from pre-rename builds, do not rely on the old automatic upgrade flow to cross the rename boundary. Manually download the
v1.0.0release package and complete the migration. - The management API now uses a prefixed route layout. If reverse proxies, ACLs, or automation scripts call old API paths directly, confirm them against the updated API docs.
- For automatic upgrade, Docker, or Debian package deployments, confirm that the console static asset directory and service files are installed with the new package.
- Deployments relying on plugin reload, online config editing, or runtime APIs should validate auth, CORS, permissions, and rollback flows in a staging environment first.
v0.5.2
Release Scope
- Patch Release focused on DoH / DoH3 upstream long-connection reuse and upstream duration parsing.
Changes
- Fixed an issue where DoH (HTTP/2) and DoH3 (HTTP/3) upstream connection pools could reuse already closed connections. After the remote peer closes an idle connection, the pool now evicts unavailable connections and recreates fresh ones, avoiding repeated
H2 send_request errororH3 send_request errorfailures (Closed #78). - Fixed upstream
timeoutconfiguration parsing. Values such astimeout: 3andtimeout: "3s"now deserialize correctly and can be used during forward plugin initialization (Closed #79). - Added unified duration parsing for duration-based fields, supporting units such as
ms,s,m,h, andd. Bare numeric values are interpreted as seconds by default.
Compatibility and Upgrade Notes
- This release does not introduce new required configuration fields. Existing
v0.5.1configurations can be upgraded directly. - Duration-based fields such as
timeoutandidle_timeoutsupport formats including3,"3","3s", and"500ms". - Bare duration numbers are interpreted as seconds. Use an explicit
mssuffix for millisecond-level values. - Upgrading to
v0.5.2is recommended for deployments that configure upstreamtimeout, or use DoH / DoH3 upstreams and have seen repeated request failures after long runtimes.
2026-04
v0.5.1
Release Scope
- Patch Release focused on
any_matchquick-setup dependency analysis andquery_recorderpagination and cleanup boundaries.
Changes
- Fixed
any_matchdependency analysis so quick-setup matcher expressions are preserved and expanded correctly. Expressions such asqname $providerandqtype 1now keep their original meaning during startup and dependency analysis. - Fixed
query_recorderretention cleanup and pagination cursor boundaries. Cleanup cutoff time now uses real timestamps, and paginated listing fetches one extra row to detect whether another page exists. - Adjusted
query_recordertimestamp storage and read paths to avoid unnecessary unsigned conversions around record creation time. - Updated the
upgradeCLI default cache and backup directories to./upgrade-cacheand./upgrade-backups, and fixed the matching default-value tests.
Compatibility and Upgrade Notes
- This release does not introduce new configuration fields. Existing
v0.5.0configurations can be upgraded directly. - Upgrading to
v0.5.1is recommended for deployments that usequery_recorderor quick-setup expressions insideany_match. query_recorderremains Experimental, and its API surface or configuration fields may still change in future releases.
v0.5.0
Release Scope
- Minor Release adding query auditing, aggregate matcher support, and HTTP/3 discovery improvements.
Changes
- Added the
query_recorderexecutor for persisted query logging with retention cleanup, plus plugin API endpoints for stats, paginated record listing, and single-record details. - Added the
any_matchmatcher so one matcher can aggregate multiple matcher expressions and return true when any branch matches, including negated expressions like!$tag. - When HTTP/3 is enabled on the HTTP server, HTTP/2 responses now automatically advertise
Alt-Svc: h3=":<listen-port>"; ma=86400so clients can discover and upgrade to H3. - Fixed dependency tracking for negated matchers, for example
!$has_resp, insidesequence, so quick setup and dependency analysis no longer miss those references (Closed #75). - Unified time handling around
jiff + AppClock, making cron scheduling, log time formatting, and system-time access paths more consistent.
Compatibility and Upgrade Notes
- This release does not require global config migrations. Existing
v0.4.xconfigurations can be upgraded directly. query_recorderis currently Experimental. Its API surface and configuration fields may change in upcoming minor releases.- To enable query auditing, insert
query_recorderinto thesequencechain and tune retention parameters according to disk budget. - For automatic HTTP/3 discovery by DoH clients, ensure
enable_http3: trueis set and TLS certificate/key are configured correctly.
v0.4.2
Release Scope
- Patch Release fixing connection release in upstream race scenarios and adding automatic upgrade support.
Changes
- Fixed an issue where some connections were not properly released in upstream race scenarios, such as when multiple concurrent upstreams were configured or fallback was enabled.
- Added the
upgradeCLI tool and plugin to support automatic updates and binary replacement. - When the application is running as a Linux service,
upgradecan also restart it automatically after the update.
Compatibility and Upgrade Notes
- This release does not introduce new required configuration fields.
- Deployments that rely on concurrent upstream racing, fallback, or automatic upgrade flows can upgrade to
v0.4.2.
v0.4.1
Release Scope
- Patch Release fixing an upstream
request_mapmemory leak and improving DoH HTTP response compatibility.
Changes
- Fixed an upstream
request_mapmemory leak during connection close, request timeout, and abnormal cleanup paths, preventing pending query waiters and senders from being retained over time. - Reworked
request_mapinto a fixed-capacity sparse table so each connection no longer reserves the fullu16DNS ID space. - Fixed DoH response header generation so
application/dns-messagereplies carry the correctContent-Length, andCache-Control: max-age=...is derived from the actual DNS TTL. - Common
NoError,NXDOMAIN, andNODATADoH responses now derive HTTP cache lifetime from answer TTLs or SOA negative TTLs. Refusal-style replies no longer advertise misleading cache headers.
Compatibility and Upgrade Notes
- This release does not add new configuration fields. Existing
v0.4.0configs can be upgraded directly tov0.4.1. - Because this release fixes an upstream
request_mapmemory leak, upgrading tov0.4.1is recommended for long-running deployments with many persistent or concurrent upstream connections. - For DoH access through
dig +https://..., browsers, reverse proxies, or HTTP caches, the upgrade also improves HTTP response compatibility.
v0.4.0
Release Scope
- Minor Release adding provider-scoped hot reload and reworking provider composition and initialization.
Changes
- Added the
reload_providerexecutor plus the provider-scoped management APIPOST /plugins/<provider_tag>/reload. After downloading or overwriting rule files, OxiDNS can refresh only the affected providers instead of forcing a full application reload. - Reworked provider composition so
domain_setandip_setcompile only their own local rules and keep querying referenced providers fromsetsat runtime. - Runtime initialization now skips providers that have no live dependents, so unused rule sets no longer spend startup time on file reads, dat parsing, or memory allocation.
- Expanded quick-setup dependency analysis into runtime reference paths such as
sequenceandcron, making plugin dependency graphs and init ordering more accurate. - Added docs for targeted provider reload through both the API and the new
reload_providerexecutor, including chained download-and-refresh examples.
Compatibility and Upgrade Notes
- Existing workflows that run
downloadand then a fullreloadcan usually switch todownload -> reload_providerto avoid rebuilding unrelated plugins. reload_provideronly refreshes an existing provider's config snapshot and external data files. Ifconfig.yaml, provider tags,setstopology, or the plugin list changes, keep using the fullreloadpath.- Providers that are not reachable from any live runtime path are no longer inserted into the runtime registry. Deployments that rely on a provider's runtime API surface or behavior must reference it directly or indirectly from a live
server,executor, ormatcher.
v0.3.2
Release Scope
- Patch Release reducing false warning logs from normal connection lifecycles and improving debug output.
Changes
- Adjusted UDP, TCP, DoT, and DoQ upstream pool initialization so OxiDNS no longer pre-creates idle connections during startup, reducing false EOF / reset warnings when upstreams close idle sockets on their own.
- Expected TCP upstream lifecycle events such as EOF, connection recycling, and invalid-connection eviction are now logged at
debuginstead ofwarn. - Downgraded DoH server-side TLS, HTTP/2, and HTTP/3 handshake aborts plus client-closed response-send failures to
debug. - Debug request/response logging now prints DNS
questions, message IDs, EDNS data, and answers directly.Recordnow has a more readableDebug/Displayrepresentation.
Compatibility and Upgrade Notes
- This release does not introduce new configuration fields. Existing
0.3.xconfigs can be upgraded as-is. - Warning-count based alerting should see a noticeable drop in noise after
v0.3.2because normal upstream disconnects and DoH client aborts are no longer treated as warnings.
v0.3.1
Release Scope
- Patch Release fixing
sequencebuiltin control-flow semantics and completing release metadata.
Changes
- Fixed
sequencebuiltin control-flow semantics soaccept/rejectstop the current chain consistently,returnexplicitly resumes the caller, and nestedjump/gotobehavior is more consistent. - Removed the old internal flow-state dependency from control-flow propagation and now relies on
ExecStepdirectly, reducing ambiguity whensequence,with_nextexecutors, and nested calls are combined. - Expanded unit and integration coverage around
sequence, includingaccept,return,reject,jump,goto, andadguard_rule/questiondriven branches. - Added the metadata, README files, repository links, and versioned dependency declarations needed to publish
oxidns-proto,oxidns-zoneparser, andoxidns-ripsetto crates.io cleanly. - Refreshed the
configuration,executor, andmatcherdocs to explain builtinsequencecontrol flow,marksyntax, and numericqtype/qclassforms more clearly.
Compatibility and Upgrade Notes
- For policy layouts that depend on nested
sequencecalls orjump/goto/returncombinations,v0.3.1is the recommended upgrade for predictable control-flow behavior. - This release does not introduce new config fields; it focuses on control-flow fixes, test hardening, and release metadata cleanup.
v0.3.0
Release Scope
- Minor Release adding HTTP callbacks, config checking, dat export, zone parsing, and Linux netlink integration.
Changes
- Added the
http_requestexecutor for synchronous or asynchronoushttp/httpscallbacks in either thebeforeorafterphase, with template placeholders,json/form/bodypayloads, SOCKS5, redirect handling, and configurable error modes. - Added the
checkandexport-datCLI commands.check --graphperforms static validation and prints the plugin dependency graph, whileexport-datcan export selected rules fromgeosite.dat/geoip.datinto OxiDNS or original text formats. - Aligned
hostsbehavior with mosdns semantics, and upgradedarbitrarywith a fuller zone parser that supports$ORIGIN,$TTL,$INCLUDE,$GENERATE, RFC3597, and broader record syntax. - Switched the Linux
ipset/nftsetexecutors to an embedded Rust netlink backend, removing the runtime dependency on theipset/nftshell commands. - Split protocol, zone parsing, and Linux integration internals into three workspace crates:
oxidns-proto,zoneparser, andripset. Added a reusable wire-buffer pool on the network hot path and tuned UDP/TCP/upstream socket parameters. - Added a dedicated CLI docs page and refreshed the
executor,provider,quickstart,benchmarks, andreleaseschapters.
Compatibility and Upgrade Notes
- Unprefixed
hostsrules now behave asfull:rules; positive local answers now use a fixed TTL of10; and a name hit without a matching address family now returnsNoError + empty answer + fake SOAinstead of falling through the rest of the executor chain. arbitraryno longer provides the old quick-setup syntax. Migrate those cases to explicitrules/filesconfiguration when upgrading.- Quickstart added a Docker Compose example and clarified Docker image registry, Windows release assets, and service deployment guidance.
v0.2.1
Release Scope
- Patch Release fixing DoH over HTTP/2 upstream GET handling and updating quickstart documentation.
Changes
- Fixed a DoH over HTTP/2 bug where GET requests did not close the request stream, causing some upstreams to time out after 5 seconds.
- Completed the
QuestionDisplayimplementation so logs and debug output render DNS questions consistently. - Relaxed the cache TTL unit test to tolerate cross-second timing drift in CI.
- Removed the Docker
linux/arm/v7support note from quickstart and added adocker composedeployment example.
Compatibility and Upgrade Notes
- This release does not introduce new configuration fields.
- Upgrading to
v0.2.1is recommended for deployments using DoH over HTTP/2 upstream GET requests.
v0.2.0
Release Scope
- Feature Release adding subscription download, scheduled jobs, script execution, and geodata provider support.
Changes
- Added the
downloadexecutor for downloading remotehttp/httpsfiles to local storage, with SOCKS5 proxying, HTTP redirect following, and startup bootstrap for missing files. - Added the
cronexecutor for background jobs with interval or standard 5-field cron triggers. - Added the
reloadexecutor for full application reloads. - Added the
scriptexecutor for running external commands with injected context fields. - Added
geoip,geosite, andadguard_ruleproviders, plus thequestionmatcher. Extendedqnamematching to supportadguard_rulerule sets directly. - Cache now supports stale lazy refresh, rule matcher internals were split and optimized, and configurable log file rotation was added.
- Expanded documentation for
executor,matcher,provider,server,quickstart, andscenarios, and added docs-site CI.
Compatibility and Upgrade Notes
startup_if_missingis enabled by default for smoother first-deployment and rule-file bootstrap behavior.ros_address_listsupportsfixed_ttl=0for no-timeout behavior.- Added
short_circuitsupport to quick setup forhosts,black_hole, andcache. - Removed the
hostsquick setup to tighten early quick-setup behavior. - Migrated from
serde_ymltoserde_yaml_ng, with several dependency and CI tooling updates.
2026-03
v0.1.1
Release Scope
- Compatibility Update standardizing the MikroTik-related executor name.
Changes
- Renamed the MikroTik-related executor to
ros_address_listto better match its actual behavior and naming style. - Corrected documentation examples and feature descriptions.
- Applied formatting cleanup to keep code and docs aligned.
Compatibility and Upgrade Notes
- Deployments that used the old MikroTik executor name in
v0.1.0need to update the plugin type when upgrading tov0.1.1.
v0.1.0
Release Scope
- First Public Release providing the initial OxiDNS plugin architecture and core capability set.
Changes
- Established the OxiDNS plugin architecture around
server -> DnsContext -> matcher / executor / provider -> upstream or side effects. - Completed server and upstream support for UDP, TCP, DoT, DoQ, and DoH.
- Delivered MosDNS-style
sequenceorchestration,jump/goto/returncontrol flow, and$tagreferences. - Added core executors such as
cache,forward,fallback,hosts,redirect,ecs_handler, anddual_selector. - Added
domain_set,ip_set, query / response predicates, client IP, response IP, and CNAME-based matching capabilities. - Added the management API, health checks, control endpoints, and plugin-related API surfaces. Added CLI commands with service-manager integration.
- Added Debian packaging, Docker workflow support, and the initial multi-platform release pipeline.
- Built reusable upstream connection pools and fetchers for UDP, TCP, DoT, DoH, and DoQ, and optimized matchers, cache, pools, request mapping, and clock updates on the hot path.
Compatibility and Upgrade Notes
- Tokio worker-thread count is configurable from runtime config.
- MikroTik RouterOS dynamic-route and address-list integration is available.
- Linux
ipset/nftsetcommand integration and test coverage are available. - The first round of Chinese and English README, quickstart, configuration, and module documentation is included.