Release Notes
2026-08
v1.5.2
Release Scope
- Patch Release. v1.5.2 focuses on trusted client-IP restoration, isolated dual-stack preference probes, efficient large-rule loading, and safe runtime lifecycles. It also adds sequence mark-set operations and hardens the release pipeline.
- v1.5.1 YAML configurations upgrade directly. The new
client_ip_from_ecsexecutor,dual_selector.probe_executorfield, andset_markbuiltin are all opt-in, so existing policies do not change automatically.
Changes
feat(client_ip_from_ecs): add an executor that replaces the request-local client IP with an ECS address supplied by a trusted forwarding peer, making that address available to subsequent client-IP matchers, recorders, and policies. Missing or empty allowlists trust IPv4 and IPv6 loopback only, and only complete IPv4/32or IPv6/128host prefixes are accepted. The plugin is included in the standard and full bundles, but not minimal.feat/fix(dual_selector): add optionalprobe_executorsupport toprefer_ipv4andprefer_ipv6, allowing preferred-QTYPE probes to use a dedicatedforwardorsequence. Omitting it preserves the previous downstream-continuation behavior. Original and probe work use isolated subquery contexts, every return path joins or cancels both tasks, cleanup stops during plugin destruction, and startup rejects missing, wrong-kind, self-referencing, or cyclic dependencies.feat(sequence): letmarkappend multipleu32values separated by spaces or commas, and addset_markto replace the entire current mark set. Duplicate values are collapsed, while missing, negative, non-numeric, or overflowing values fail sequence initialization. Dependency graphs, execution paths, and the WebUI editor understand the new syntax.perf/fix(loaders): unify streaming text input and capacity reservation across matchers, hosts, redirect, providers, RouterOS persistence, and zone records, avoiding retention of complete large files or intermediate rule collections. The zone parser gains visitor APIs. Multi-pass compilation fingerprints replayed inputs, publishes only fully built candidates, and moves large compilation work off the async runtime.fix(runtime/providers): provider reload retains serialized ownership after caller cancellation, and runtime teardown drains in-flight reloads and background builds so old snapshot compilation cannot cross reload or destroy boundaries. Replay compilation for AdGuard, V2Ray, and related providers also gains stronger source-location, comment-handling, and rollback coverage.fix(download/upgrade): shared HTTP downloads now own temporary files through drop cleanup, removing incomplete files after timeout, cancellation, or failure and atomically replacing the destination only after success. Windows ZIP-upgrade path handling is corrected as well.deps/ci/release: move tooxidns-mikrotik-rs 0.8.1, which includes lossless Tokio response delivery, and remove the temporary Git patch plus crates.io--no-verify. Updatehotpath,base64, and other dependencies, isolate cross-target build caches, and publish version-bumped workspace support crates in dependency order before the root package.docs/benchmarks/telegram: reorganize bilingual installation, configuration, CLI, API, and plugin references; add reproducible multi-implementation benchmark scenarios and results; and render Telegram announcements as compatible HTML that preserves headings, lists, emphasis, inline code, and links, with truncation tests.
Compatibility and Upgrade Notes
- The root crate version is
1.5.2;oxidns-protois updated to0.1.5andoxidns-zoneparserto0.1.2; the release tag should bev1.5.2. Publication now uploads new support-crate versions before the root crate. - v1.5.1 configurations upgrade directly. No fields are renamed or removed, and no existing plugin policy defaults change. Run
oxidns check -c <config-file>before replacing the binary. client_ip_from_ecschanges the request-local client IP observed by later plugins. Place it before the affected matchers and recorders, allow only controlled reverse proxies or local forwarders inargs, and never trust a source reachable directly by clients. The forwarder must send/32or/128ECS; network prefixes are ignored.- Omitting
dual_selector.probe_executorpreserves v1.5.1 behavior. When configured, probe-context marks, responses, and transient state do not flow back to the original request, but completed external side effects cannot be rolled back; dedicated probe chains should favor side-effect-free resolution executors. - Existing single-value
marksyntax remains valid, and only an explicitset_markclears the previous set. If a large rule file changes during one multi-pass build, the candidate is rejected and the previous snapshot remains active; automation should trigger reload only after the replacement file is fully installed.
2026-07
v1.5.1
Release Scope
- Patch Release. v1.5.1 focuses on matcher runtime control, upgrade operations, and WebUI quality. It expands temporary matcher switching into tri-state base-result controls, adds force and post-upgrade cleanup controls, and delivers a concentrated set of localization, polling, log-viewer, and plugin-card fixes.
- Existing YAML configurations upgrade directly, but the matcher runtime management API has a breaking change. Clients using that API must migrate before upgrading.
Changes
feat/fix(matcher): replace the runtime switch withnormal,always_false, andalways_truemodes. Both fixed modes skip the matcher implementation and fix its base Boolean value; each$tagor!$tagreference then applies its own outer negation, so positive and negated results remain opposites.sequence,any_match, and query recorder now track both the fixed mode and effective match result, with regression coverage for shared controls.feat(upgrade): let the management API and WebUI setforceto reinstall a release even when it is already current. Addcleanupto control removal of download caches and backups after a successful upgrade. The WebUI persists both preferences and generates equivalent CLI commands. Cleanup releases the upgrade lock first and reports cleanup failures without changing a successful apply result.fix(webui/i18n): complete Chinese and English localization for RouterOS, plugin definitions, metrics, configuration history, and console components, including locale-aware date formatting. Add coverage auditing to prevent missing English translations or fallback to Chinese.fix(webui/runtime): schedule runtime polling according to page visibility while retaining background metric collection. Isolate responses, metric baselines, and update-check caches between backend connections; fetch matcher state only on initial load or explicit refresh; reset QPS sampling after long gaps.feat(webui/logs): add persisted timestamp formats, optional elapsed-time display, adaptive duration units, and compact target paths. Unify plugin configuration and metric cards around an adaptive grid, with better RouterOS write-result, timestamp-metric, and system-memory presentation.perf(build): use size-oriented release optimization, fat LTO, one codegen unit, and symbol stripping. Limit Tokio, QUIC, and TLS dependencies to required features, and attempt UPX compression for minimal and standard release artifacts without making compression failure block publication. Exclude development-only benchmarks, site documentation, and WebUI sources from the crates.io source package to stay clear of the registry size limit.deps/ci/release: updatewincode,syn, other Rust dependencies, and GitHub Actions. Temporarily apply the RouterOS unbounded-response-channel fix through a Git patch to prevent protocol-event loss under burst traffic. The patch is not published separately, and crates.io publication uses--no-verifyuntil upstream ships the fix. GitHub Release and Telegram announcements now share version-heading-validated release notes; announcements target the configured topic and are pinned automatically.
Compatibility and Upgrade Notes
- The root crate version is
1.5.1; publishable workspace crate versions remain unchanged, and the release tag should bev1.5.1. The RouterOS patch is not published as a separate crate. - v1.5.0 YAML configurations upgrade directly. No configuration fields are added, renamed, or given new defaults. Run
oxidns check -c <config-file>before replacing the binary. - Matcher API migration:
POST /api/plugins/<matcher_tag>/enableand/disableare removed. UsePOST /api/plugins/<matcher_tag>/modewith{ "mode": "normal|always_false|always_true" }. TheGET /statusresponse replacesenabledwithmode. Unmigrated automation and third-party controllers will receive a 404 or fail response decoding. - Fixed matcher modes exist only in the current runtime and reset to
normalafter an application reload or process restart. The mode is shared by matcher tag, while reference semantics remain local: withalways_false,$tagmisses and!$tagmatches;always_trueproduces the opposite results. Control theany_matchmatcher itself when the whole composition must be fixed. - The WebUI defaults to deleting download caches and backups after a successful upgrade. Disable post-upgrade cleanup when local rollback files must be retained. Use
forceonly to repair a damaged installation or redeploy the same version, after confirming the intended bundle and platform. - Minimal and standard artifacts may be UPX-compressed. Environments with binary scanners, allowlists, or integrity baselines should verify the release asset digest again and smoke-test startup, upgrade, and rollback before production replacement.
v1.5.0
Release Scope
- Minor Release. v1.5.0 centers on RouterOS policy synchronization and live operations: it adds the
ros_routestatic policy-route plugin, comprehensively rebuildsros_address_list, and adds management API plus WebUI runtime controls for matchers and providers. - It also adds a configurable
responseexecutor, timezone-awaretimematching, query-recorder space reclamation, stronger CNAME response selection, advanced WebUI configuration, and broader OpenWrt, ARMv7, and container delivery support.
Changes
feat(routeros): addros_routeto synchronize observed DNS A/AAAA addresses into per-IP static routes in a selected RouterOS routing table, with IPv4/IPv6 gateways, distance, TTL leases, persistent IP/CIDR entries, optional conntrack-delayed removal, startup recovery, and bounded shutdown cleanup.refactor(routeros): share TLS/API-SSL transport, bounded parallel batching, key-coalescing queues, leases, reconciliation, retry, and lifecycle primitives acrossros_address_listandros_route. RouterOS outages no longer block DNS startup; synchronous mode is limited bywait_timeoutand never changes the DNS response on failure; deletion revalidates internal ID, target key, and ownership comment to avoid touching foreign entries.feat(runtime_control): all matchers gain live status, enable, and disable controls; providers gain serialized reload with conflicting concurrent requests rejected. The management API, logs, and WebUI plugin detail panels expose these controls, while builds without the API feature keep them disabled.feat(response/matcher): add aresponseexecutor that builds Answer, Authority, and Additional sections from zone-record templates with RCODE, flags, and{qname}/{qclass}placeholders. Thetimematcher gains IANA timezones, multiple periods, overnight windows, weekdays, and month-day constraints.refactor(query_recorder): coordinate readers, writers, and maintenance sharing one SQLite database. Retention cleanup and manual history clearing now delete in batches, truncate WAL, migrate legacy databases to incremental auto-vacuum, reclaim disk space, and keep the in-memory tail consistent with stored results.fix(dns/forward/cache): add a shared query-aware response classifier. Concurrent upstream selection distinguishes complete positives, definitive negatives, and incomplete aliases; bare CNAME responses no longer win early, vote as negatives, or populate address caches. Cache dump/load, lazy refresh, TTL, and persisted-age behavior are hardened while repeated CNAME scans are reduced.feat(webui): add collapsible advanced configuration fields while preserving explicit defaults,false,0, and empty objects. Replace Monaco with a locally hosted CodeMirror YAML editor with stronger validation, completion, array, and time-period serialization. Improve DNS traffic, process memory, and unavailable-metrics dashboard states.feat(release/operations): add an ARMv7 release target; let the installer deployluci-app-oxidnsand its Chinese package on OpenWrt; move the container to an Alpine build stage plus BusyBox musl runtime; split upgrade discovery, digest verification, archive handling, and binary/WebUI installation while correcting full/slim target selection.fix(config/api/health): reject path-unsafe plugin tags and the reserved quick-setup namespace, consistently URL-encode plugin API routes, and report health only after plugin initialization. Synchronize newresponseand RouterOS configuration, features, and build-info capabilities.deps/ci/docs: update dependencies and GitHub Actions, including theoxidns-protonightly-Clippy fix. Clarify server, plugin, infra, upgrade, and provider/V2Ray module boundaries and update bilingual API, plugin, OpenWrt, installation, and operations documentation.
Compatibility and Upgrade Notes
- The root crate version is
1.5.0;oxidns-protois updated to0.1.4; the release tag should bev1.5.0. - Most v1.4.0 configurations upgrade directly; all newly introduced capabilities are optional. Run
oxidns checkbefore upgrading. Unsafe plugin tags and reserved quick-setup tags now fail validation and must be renamed together with all references. - RouterOS ownership migration: the default
ros_address_list.comment_prefixchanges fromfdnstooxi. To continue recognizing, refreshing, or cleaning entries created by older releases, explicitly keepcomment_prefix: fdnsin the existing plugin configuration; handle the old namespace before switching tooxi. ros_address_listadds optionaltls,wait_timeout, andqueue_capacity; existing address-list, persistent, and TTL settings remain valid.cleanup_on_shutdownstill defaults totrue, and application reload shuts down the old instance first. Deployments requiring policy continuity should evaluatefalseand must not run two processes with the same tag, comment prefix, and target list.ros_routeis new and requires a pre-created RouterOS routing table/rule plus at least one gateway.fixed_ttl: 0creates dynamic routes that never expire naturally, and dynamic leases have no entry-count cap; assess RouterOS routing-table and OxiDNS memory capacity first. Custom builds can selectplugin-ros-address-listorplugin-ros-route;plugin-mikrotikremains the aggregate feature.- Legacy query-recorder databases migrate to incremental auto-vacuum on the first retention cleanup or manual history clear. The first migration/reclaim of a large database may create noticeable disk I/O, so schedule it outside peak traffic and keep free space available.
forward.concurrent: 1still does not retry upstreams that were not started. An incomplete CNAME response can still be returned when no better result exists, but is not cached as an address answer. Legacy CNAME-only address entries in cache dumps are discarded during load or hit validation.- The container now uses a musl/BusyBox runtime while retaining CA and timezone data. Container, OpenWrt, and ARMv7 deployments should verify startup arguments, mounts, timezone behavior, and upgrade/rollback procedures before production replacement.
Archive
Detailed notes are partitioned by month so the current page remains bounded:
Before upgrading, read the target release and every intervening “Configuration and Upgrade Notes” section. Historical notes describe behavior at that time; current parameters come from the code and documentation at the matching release tag.