Skip to content

feat(frontend): warn about catch-all routing rules - #230

Merged
loss-and-quick merged 3 commits into
mainfrom
feat/routing-catch-all-warning
Aug 18, 2026
Merged

feat(frontend): warn about catch-all routing rules#230
loss-and-quick merged 3 commits into
mainfrom
feat/routing-catch-all-warning

Conversation

@loss-and-quick

@loss-and-quick loss-and-quick commented Aug 18, 2026

Copy link
Copy Markdown
Owner

Summary

A routing rule with no domain, ip or protocol whose port range spans every port matches all traffic. sing-box stops at it, so everything below is dead — including the action: resolve step plus the repeated IP checks that the generator appends after the user rules when domainStrategy is IPIfNonMatch (crates/kasumi-core/src/singbox_config.rs:1116-1119).

A rule like port 0-65535 → proxy is easy to add as a "default" and looks harmless, but it silently disables the resolve-then-geoip fallback: a domain that no geosite rule matched is no longer resolved and re-checked against geoip-ru, so a host on a Russian address goes through the proxy instead of direct. The rule is also redundant — route.final already sends the remainder to the same outbound, but after the resolve step.

The routing list now marks such a rule and greys out the rules it makes unreachable.

When the catch-all is the last enabled rule and routes to the proxy, it shadows nothing but the automatic tail, which already ends in the same fallback. Telling the user it matches every connection is true but unhelpful there, so that case gets its own line: the rule buys nothing and costs the automatic IP check.

Affected layer

  • frontend/ — React Web UI
  • crates/ · src-tauri/ — Rust core / backend / Tauri desktop
  • module/ — Android installable zip (thin launcher over the Rust daemon)
  • scripts/ — build / release helpers
  • CI / .github/
  • Docs only

Verification

Web UI (frontend/):

  • bun run check — Biome lint + format clean (106 files)
  • bun run test — vitest green (9 files, 82 tests; 7 new cases for isCatchAllRule, 5 for isRedundantCatchAll)
  • bun run buildtsc -b + vite build succeed
  • bun run check:i18n — 8 locales, 655 keys in sync, no stale keys

No Rust or module code touched, so those gates are not applicable.

Checklist

  • Title is a scoped Conventional Commit; commits are logically split (detector + tests, then the list rendering + strings, then the redundant-tail case)
  • No build artifacts committed
  • Generated frontend/src/generated/ was regenerated from Rust, not hand-edited — untouched here
  • If user-visible strings changed: settings.routingCatchAll, settings.routingUnreachable and settings.routingCatchAllRedundant added to en.ts and all 7 other locales
  • Renames touching the project id were grepped in all case forms — no rename in this PR

Notes for reviewers

The detector deliberately mirrors what the generator emits rather than guessing:

  • build_structured_singbox_rules (singbox_config.rs:938) only emits a port/network/protocol-only rule when neither the domain nor the ip half produced a match field, which is exactly the catch-all shape.
  • A rule narrowed to one network (tcp or udp alone) is not flagged — it leaves the other half of the chain reachable.
  • A rule whose domain list parses to nothing (all entries commented out with #, ext: …) also degrades to a port-only rule in the generator. That false negative is left alone: flagging it would mean re-implementing parse_singbox_domain in the UI.

A rule with no domain, ip or protocol whose port range spans every port
matches all traffic, so sing-box stops there: the rules below it and the
resolve step the generator appends for IPIfNonMatch never run.
Marks the catch-all rule and the rules it makes unreachable, so a
terminal rule stops silently swallowing the rest of the chain.
@github-actions github-actions Bot added the frontend React Web UI (frontend/) label Aug 18, 2026
…back

A catch-all routed to the proxy with nothing enabled below it shadows
only the automatic tail, which already ends in the same proxy fallback.
Saying it matches everything is true but unhelpful there — the rule buys
nothing and costs the automatic IP check, so name that instead.
@loss-and-quick
loss-and-quick merged commit 007e896 into main Aug 18, 2026
9 checks passed
@loss-and-quick
loss-and-quick deleted the feat/routing-catch-all-warning branch August 18, 2026 19:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

frontend React Web UI (frontend/)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant