* feat(config): add conditions while preserving mask rules
Accept conditions alongside the existing masks and mask spellings, rejecting conflicting matching fields and flat-source combinations. Normalize all forms into the existing predicate engine.
Add explicit masks leaves for composed expressions and source groups. Keep simple address exports compact and serialize richer rules under conditions.
Cover round-trips, nested source discovery, controller payloads, warning-free compatibility, and routing across accepted and rejected reloads.
* docs(routing): explain conditions and compatible mask syntax
Document expression composition, conflicting fields, source shorthand, and canonical serialization in English and Chinese. Record the controller diagnostic shape in the changelog.
Add a complete conditions example, validate it through the native configuration pipeline, and show conditions in the rule-source example.
* fix(config): clarify invalid rule conditions diagnostics
Name the mutually exclusive matching fields explicitly, including legacy aliases, instead of reporting an unwritten duplicate conditions key.
Explain that nested masks leaves accept only strings or nonempty string lists, with regression tests for JSON/YAML conflicts and invalid leaf shapes.
* refactor(tests): simplify rule conditions coverage
Stage all spelling and format variants before checking their shared canonical form. Restore that form once while preserving per-variant compilation and the complete decision matrix.
Remove conflict inputs already covered by stronger diagnostic assertions, clarify controller payload names, and validate all five rule forms in one fixture per CLI mode.
* fix(rules): correct source-group predicate guidance
Recommend the rule_source_group predicate without a masks wrapper so the rename hint works in nested expressions and source groups. Cover the suggested syntax and diagnostic in regression tests.
Update both documentation locales to describe source-group references under conditions or masks, including boolean composition.
Report shared selector and group ancestry once per selected occurrence while preserving reverse hop order, independently repeated references, routing behavior, and catalog identities. Cover nested selections and pinned TCP/UDP flows, simplify reporting metadata assembly, and clarify chain ordering, client naming, and DIRECT-to-proxy semantics in both controller guides.
Keep managed desktop capture working without native default routes or usable loopback addresses. Add local-only fallback routing with fail-closed TUN egress guards, preserve strict ownership and native exclusions, enable IPv6 only on the owned TUN, and keep automatic DNS reachable with split routes.
Allow rule caches in directories accessible through group permissions or ACLs without requiring directory ownership, and create missing cache directories and parents automatically. Existing ownership and permissions remain unchanged, while world-writable directories, unsafe cache files, and conflicting cache leases remain rejected. Clarify the startup and cache-save permission requirements.
Add optional NTP synchronization for hosts where shoes cannot set the system clock. Share the corrected time across REALITY, VMess, Shadowsocks 2022, and TLS certificate validation, using protected direct UDP with bounded synchronization, periodic refresh, and reload-safe ownership. Preserve timestamp windows and replay protection, retain the last correction on refresh failure, and document configuration and clock limitations.
Expand regression coverage for whole-path routing across forwarding, DNS, rule downloads, probes, and session reuse to guard against route changes affecting established flows or shared state. Add native Caddy and WireGuard cases plus dual-stack kernel-TUN coverage, strengthen routing boundaries and controller assertions, enable routing and consumer suites on macOS, and make test fixtures portable across platforms.
Close regression gaps in message framing, AnyTLS recovery and UoT interoperability, routing limits, and reload retention. Harden test helpers to reject empty child runs, verify HTTP response integrity, and terminate curl on failure or cancellation; tighten CI test selection and simplify the supporting fixtures.
Add optional global_settings.default_dns so listeners, TUN entries, and WireGuard inbounds can share DNS configuration without repetition. Omitted or null inbound DNS inherits the default, while explicit objects override it completely. Inline fake-IP defaults share one pool, and independent bootstrap and service lookups remain unchanged. Includes validation, regression coverage, and English and Chinese documentation.
Allow client groups to select complete paths of different lengths consistently across forwarding, DNS, downloads, and carrier routes. Separate source configuration from bounded runtime plans, preserve selection boundaries and per-flow path pinning, and keep TCP/UDP rotation and automatic selection independent. Unify chain syntax while retaining legacy proxy-list alternatives, and cache up to 16 NaiveProxy sessions by selected prefix, pruning closed entries before LRU eviction without interrupting active tunnels. Add routing measurements, lifecycle coverage, and updated English and Chinese configuration guidance.
Retain the wrapped transport when a pooled AnyTLS session closes during checkout and make one fresh attempt only before the current stream queues its SYN. Preserve non-replay behavior after queue admission and apply the same recovery to TCP and UDP-over-TCP, with regression coverage for stale checkout, admission boundaries, and fresh-dial failures.
Filter delayed macOS filesystem notifications when watched regular-file metadata is unchanged, avoiding unnecessary configuration reloads after startup. Preserve observations across watcher rebuilds and registration failures, keep recovery channels independent, and retain genuine edits and explicit reloads while leaving uncertain metadata and other platforms unfiltered.
* Validate published configuration examples
* Move configuration reference into Starlight site
* Check documentation site in CI
* Complete optional docs dependency lock entries
Removes historical benchmark output while preserving links to archived results, refreshes benchmark documentation, and keeps test scratch files outside the checkout. Moves the manual desktop systemd unit into examples and updates deployment instructions without changing release packaging or mobile integration.
* fix(quic): verify IP hops against their configured identity
Use the hop address as the certificate verification fallback for all QUIC transports, preserving explicit SNI overrides and wire-SNI behavior. Expand handshake tests across raw QUIC, XHTTP-H3, Hysteria2, and TUIC with IPv4/IPv6 and certificate mismatch cases.
* fix(websocket): validate required upgrade response headers
Require case-insensitive Upgrade and Connection tokens in the shared outbound handshake. Cover eager and early-data clients, malformed and repeated headers, handshake flushing, and coalesced first-frame preservation. Correct existing mock responses to include mandatory headers.
* test(quic): clarify SNI verification cases
Replace nested options with the existing NoneOrOne type and hoist invariant configuration formatting out of the protocol loop. Preserve all certificate and wire-SNI assertions.
* test(websocket): simplify upgrade validation matrix
Deduplicate expected errors and clarify early-data and async exchange names without changing cases, assertions, or peer lifetime.
* fix(xhttp): suppress inherited SNI inside the carrier
Retain the hop identity for certificate verification while restoring the absent default wire SNI for inner protocols. Extend the TLS identity matrix through the XHTTP builder to cover omitted, null, and explicit SNI.
* fix(vision): keep the initial prefix in one TLS record
Floor configured Vision client TLS buffers at 21 bytes so peers receive the UUID and first frame header together. Preserve ordinary TLS limits and cover tiny buffers with record-level assertions, UDP exchanges, and sing-box/Xray peer tests.
* fix(tls): drain deferred KeyUpdate replies before Vision writes
Materialize pending KeyUpdate replies before draining TLS output so they cannot fragment the initial Vision prefix. Preserve queued application data and fatal alerts after session failure, with framing and backpressure regressions.
* refactor(tls): clarify identity and Vision regression tests
Replace positional identity-path flags with a test-local enum, use the existing message shutdown helper, and document the XHTTP inner SNI boundary. Preserve test coverage and production behavior.
* ci: pin Xray test peers to 26.10.31
Replace the unavailable release download with the latest release and its verified checksum. Align source-built peers and fixture version checks with the same release.
Reuse idle AnyTLS carriers across TCP and UDP-over-TCP requests to avoid repeated connections and transport handshakes. Sessions remain exclusive to each active request and isolated by proxy route, with configurable idle retention, warm-open watchdogs, shared negotiated padding, and safe response draining after peer FIN. Add configuration documentation, regression coverage, and CI interoperability checks against a pinned reference peer.
Fix protocol edge cases that could corrupt framing, misroute UDP traffic, or leave clients waiting. Bound frame sizes and padding, preserve TUIC traffic until authentication, route each UDP destination independently, and correct Vision/XUDP handling. Keep TLS verification identity separate from wire SNI, preserve local endpoint addresses, validate WebSocket upgrades including early-data handshakes, and flush terminal proxy failures.
Add reusable rule-source groups and config-driven remote downloads with explicit proxy and DNS routing, in-memory retention, and optional private atomic disk caching. Preserve active traffic across download and reload failures while keeping configuration checks offline. Consolidate process-wide limits and rule_cache_dir under global_settings, retain global_limits as a warning-emitting alias, and remove ordered fallback groups and health_check configuration.
Support WebSocket early data for compatibility with sing-box, Xray, and Mihomo. Add opt-in client sending through path or header carriers, automatic server reception of up to 2048 bytes from Sec-WebSocket-Protocol, strict handshake validation, and fixes for buffered data and stream metadata, with configuration documentation and interoperability coverage.
Adds native Hysteria2 and TUIC v5 outbound clients so proxy routes can use either protocol directly for TCP and UDP. Includes pooled QUIC connections with bounded resource use, cancellation-safe TUIC commands, Hysteria2 Salamander obfuscation and port hopping, hardened HTTP/3 authentication, TLS verification, configuration examples, and interoperability coverage in CI.
Adds an outermost sudoku_mask wrapper so TCP clients and servers can interoperate with Xray FinalMask, including configurable layouts and padding, stacked masks, and XHTTP carriers. Preserves explicit flush ownership and prevents Vision or raw TCP splice from bypassing the mask, with configuration validation and documentation for supported placements and limits. Native UDP/QUIC masking is not included.
Add managed Linux TUN and REDIRECT capture with independent DNS interception, protected bootstrap and outbound sockets, best-effort systemd-resolved integration, and retained-ingress reload and recovery. Include configuration documentation, service integration, and kernel coverage.
* Fix split-task readiness during TLS read-driven flushes
Preserve original reader and writer registrations behind a shared readiness dispatcher. Keep internal receive, drain and flush helpers non-registering, and wake parked writers on read-driven progress or fatal receive errors without adding write-side self-wakes.
Cover ordinary TLS, REALITY, raw handoff, vectored writes, control-operation readiness, reader cancellation and terminal errors. Extract the fix and later TLS test cleanups from 5f475063 and f83bc0f1 without the Sudoku-only test cases.
* Simplify TLS readiness regression tests
Preserve Hickory transport error kinds during hostname lookups so the existing resolver refresh and retry policy handles timeouts and unavailable connections. Reuse the shared error conversion and cover transport recovery, cached success, and NXDOMAIN responses without unnecessary refresh.
Raise the configurable QUIC socket-buffer default to 8 MiB and apply it consistently to listeners, outbound proxies, and DNS-over-HTTP/3. Keep tuning best-effort under OS limits, normalize Linux readbacks, suppress repeated warnings, and document kernel settings and reload behavior.
Add Linux ARMv7 hard-float GNU and static musl binaries so 32-bit ARMv7 systems can use prebuilt Shoes releases. Retain the six existing targets, pin build tooling and cross images, and validate each packaged binary with native or QEMU checks before uploading it. Harden future releases with version and tag validation, SHA-256 checksums, and GitHub build-provenance attestations, and document platform requirements and artifact verification.
Refresh eligible Rust dependencies and build tooling, including notify 8.2.1, Web PKI roots 1.0.11 and the ctutils constant-time fix. Handle macOS watcher restart failures, update Unicode-domain data, and require Rust 1.99.1 while preserving maintained fork pins and protocol baselines. Retain parking_lot 0.12 and the upstream nix pin for Android/iOS compatibility.
REALITY connections fail when the cover target uses a minimal 28-byte EncryptedExtensions record because rustls adds an SNI acknowledgement that no longer fits. Pin the stable-release rustls fork that omits this acknowledgement only for REALITY, update the cover fixtures to use minimal records, and add regression coverage for successful handshakes and rejection of undersized records. Ordinary TLS behavior and strict record-capacity checks remain unchanged.
Move 37 large unit-test suites into adjacent child modules to keep production files easier to navigate while preserving access to private implementation details. Small suites remain inline and integration tests stay separate. Remove unused fixture parameters and duplicate helpers, and clarify configuration test setup without changing test coverage or behavior.
Add opt-in fallback groups that route new flows through the first healthy eligible path and fail closed when no path remains, without overriding manual selections or replaying traffic. Reuse the shared probe engine with bounded generation-owned scheduling, resolver-aware path identity and reload cleanup, and reject transport combinations that cannot reliably attribute health to a concrete path.
Support server-key:user-key and longer identity chains for Shadowsocks 2022 AES clients, allowing connections to multi-user servers and identity relays. Add the required identity headers, configuration validation, and usage documentation while preserving existing single-key and legacy configurations. This is client-only support; native SS2022 UDP and server-side multi-user support remain out of scope.
Add advisory selector/reload performance reports, optional Linux unit/process coverage with changed-line summaries, and bounded rule-parser property tests to make regressions and verification gaps easier to spot. Reports reject invalid measurements and account for timing noise without introducing hard performance gates; existing tests and production behavior remain unchanged.
Add a system-only native_cache_secs option for configurable OS/NSS application memoization while preserving the existing 60-second implicit default and uncached explicit system behavior. Disable completed-cache reads and writes for zero windows, reject invalid DNS options, and document freshness and lookup-sharing semantics.
Expose bounded setup, routing, and DNS notes in existing `/connections` responses so dashboards can explain active connections without a separate debug API or retained history. Add the default-off `connection_notes` controller setting and bounded per-connection storage while preserving existing connection metadata and forwarding behavior.
Make configuration failures easier to locate without weakening validation: add configuration-entry and rule context, preserve native YAML error locations, and identify input files in validation errors. Reject previously ignored unknown fields in named PEM entries and TCP settings, clarify diagnostic limits and upgrade requirements, and add coverage for strict parsing, representative configurations, and offline validation behavior.
Move file I/O onto dedicated per-sink workers so slow storage does not stall relay threads. Bound pending records and escaped bytes, drop newest records on overload with health counters, and preserve FIFO ordering and flush barriers. Integrate bounded shutdown and reusable file-sink ownership with CLI and mobile FFI while preserving sanitization and existing log formatting.
Retain fixture ports until listener handoff, await Shoes readiness before starting dependent peers, and settle native watcher setup notifications before activation assertions. Pin Hickory 0.26.3 to a connection-close recovery backport that preserves typed H3 errors and healthy-upstream failover without widening retry limits.
Add URL-scoped health and delay-based upstream selection so new connections can use healthy, transport-compatible proxies without requiring a controller listener. This introduces strict client_group.type configuration in place of strategy, bounded automatic probes with lazy activity tracking and reload fencing, controller reporting, and configuration documentation. It also preserves local failure attribution through outbound HTTP/2 adapters so local resource limits do not incorrectly penalize proxy health.