Skip to content

feat(proxy): consolidate local traffic policy controls#1386

Open
maybeknott wants to merge 5 commits into
therealaleph:mainfrom
maybeknott:feat/proxy-traffic-policy
Open

feat(proxy): consolidate local traffic policy controls#1386
maybeknott wants to merge 5 commits into
therealaleph:mainfrom
maybeknott:feat/proxy-traffic-policy

Conversation

@maybeknott
Copy link
Copy Markdown

@maybeknott maybeknott commented May 24, 2026

This consolidates local traffic-policy behavior into one reviewable proxy slice.

When block_quic = true, SOCKS5 UDP DNS requests for HTTPS/SVCB records are answered locally with an empty successful response. Ordinary A/AAAA DNS traffic is left untouched. This lets browsers skip advertised HTTP/3 endpoints earlier instead of discovering them through DNS and then spending time on UDP/443 retries that will be blocked by policy.

The branch also adds a local block_hosts policy evaluated before relay, tunnel-node, SNI rewrite, or upstream SOCKS5 dispatch. Matching HTTP and CONNECT traffic is answered locally, SOCKS5 CONNECT receives a ruleset failure reply, and matching UDP traffic is dropped locally. Matching follows the existing host-list convention: exact entries match only that hostname, and leading-dot entries match the parent suffix plus subdomains.

The desktop UI now exposes a multiline Block hosts editor, preserves the TOML value on save, and shows local policy counters in the stats panel. Stats JSON includes both local block-list hits and QUIC policy counters so Android/UI consumers can surface the same behavior without parsing logs.

Validation:

  • git diff --check
  • cargo test dns_ --lib
  • cargo test block_hosts --lib
  • cargo test stats_snapshot_exports_local_block_counter --lib
  • cargo test host_list_editor --features ui --bin mhrv-rs-ui

When block_quic is enabled, browsers should move to the TCP proxy path as early as possible instead of spending retry time on HTTP/3 discovery. SOCKS5 UDP already drops UDP/443 datagrams, but modern clients can learn HTTP/3 availability before opening UDP by querying DNS HTTPS or SVCB records over UDP/53.

Add a local DNS classifier in the SOCKS5 UDP relay for single-question IN queries of type HTTPS (65) and SVCB (64). Matching queries receive an empty successful DNS response with the original question preserved and all answer, authority, and additional counts cleared. Ordinary A/AAAA and multi-question queries continue through the existing UDP tunnel path unchanged.

The suppression only runs when block_quic is active and only on UDP target port 53. It does not change CONNECT handling, TCP DNS, DoH bypass/block policy, Full-mode UDP support, or the existing silent UDP/443 drop contract. Local counters record suppressed HTTPS/SVCB hints and dropped QUIC datagrams for diagnostics.

Add focused unit coverage for HTTPS suppression, SVCB suppression, non-suppression of A queries, and refusal to rewrite multi-question packets.
Expose the local QUIC policy decisions added to the SOCKS5 UDP relay so users can tell when fallback steering is active. The desktop traffic panel now shows the number of UDP/443 datagrams dropped by block_quic and the number of DNS HTTPS/SVCB questions answered locally.

Document the behavior in the main guide without expanding the troubleshooting section into a new feature walkthrough. The note explains that block_quic now covers both UDP/443 datagrams and DNS HTTP/3 advertisement hints, causing browsers to fall back to TCP/HTTPS sooner.

Add block_quic to the primary Apps Script and Full Mode TOML examples so new configs make the default traffic policy explicit near the listener and SOCKS settings.
@github-actions github-actions Bot added the type: fix fix: PR — auto-applied by release-drafter label May 24, 2026
Strengthen the focused DNS coverage for the block_quic HTTPS/SVCB suppression path.

The new tests verify that the local empty-answer response preserves the client recursion-desired bit, clears additional-record state instead of echoing EDNS-style trailing data, rejects compressed question names, and ignores non-IN classes. These cases keep the helper intentionally narrow: only ordinary single-question IN queries for HTTPS or SVCB are answered locally.

Clarify the guide note to state that ordinary A/AAAA DNS questions are unchanged by this policy.
Add a config-backed block_hosts list for destinations that should be answered by the local proxy before any relay, tunnel, SNI rewrite, or upstream SOCKS5 dispatch is attempted. The matcher intentionally reuses the existing passthrough host semantics: exact entries match only that hostname, while leading-dot entries match the bare suffix and its subdomains with case-insensitive trailing-dot normalization.

HTTP proxy requests now check the parsed target host at ingress. Blocked plain HTTP requests and blocked CONNECT authorities receive a local 204 No Content response with Connection: close and Content-Length: 0, so the browser gets a deterministic terminal response without opening an outbound socket or consuming Apps Script quota.

SOCKS5 CONNECT requests now check the resolved request target before the success reply is sent. Blocked targets receive a ruleset-failure response and no outbound connection is opened. SOCKS5 UDP ASSOCIATE datagrams also check each parsed datagram target and drop blocked destinations before creating or reusing a tunnel-mux UDP session.

The shared tunnel dispatcher keeps a defensive block_hosts guard as well, so future ingress paths cannot accidentally bypass the local policy and reach raw TCP passthrough, Full Tunnel, Apps Script relay, or SNI rewrite. This keeps the policy local to the client and avoids any changes to Code.gs, CodeFull.gs, or tunnel-node.

Wire block_hosts through the flat Config, the TOML [network] section, JSON-to-TOML migration serialization, and the desktop UI form state. The UI does not expose an editor for the list yet, but it now preserves hand-edited TOML entries on Save instead of dropping them.

Document the TOML shape in the guide, add block_hosts to the checked-in TOML examples, and cover both TOML round-trip/migration behavior and host matching semantics with focused unit tests.
Add a desktop UI editor for network.block_hosts so local quota-saving block rules can be managed without hand-editing config.toml. The editor stores one hostname per line, trims blank and comment lines on save, preserves existing exact-host and leading-dot suffix semantics, and shows the number of active local block rules before the user saves or starts the proxy.

Account for local block-list decisions at the proxy short-circuit points. HTTP CONNECT and plain HTTP blocks increment the counter before returning a local 204, SOCKS5 CONNECT increments before returning the ruleset failure reply, SOCKS5 UDP increments before dropping a blocked datagram, and the shared dispatch guard increments before dropping a blocked tunnel path. Apps Script and Full-mode servers share the same counter with DomainFronter so relay stats reflect traffic avoided before any relay, tunnel-node, SNI rewrite, or upstream SOCKS5 work is opened.

Extend StatsSnapshot, the human-readable stats line, and the JSON stats export with blocked_requests. This gives the desktop traffic panel and Android/JNI consumers a stable numeric field for local block-list hits without changing the existing cache, quota, h2, or per-site fields.

Document the UI editor, the TOML representation, the matching rules, and the blocked_requests telemetry in the English and Persian guides. Add block_hosts comments to the shipped TOML examples so configuration-facing behavior is visible from the sample files.

Add focused regression coverage for block-host editor parsing and stats export formatting. Verification: git diff --check passed. cargo test stats_snapshot_exports_local_block_counter --lib and cargo test --bin mhrv-rs-ui host_list_editor could not run because winnow v0.7.15 is not available locally and static.crates.io timed out while Cargo attempted to download it.
@maybeknott maybeknott changed the title fix(proxy): suppress HTTPS DNS hints when QUIC is blocked feat(proxy): consolidate local traffic policy controls May 24, 2026
@github-actions github-actions Bot added the type: feature feat: PR — auto-applied by release-drafter label May 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: feature feat: PR — auto-applied by release-drafter type: fix fix: PR — auto-applied by release-drafter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant