fix: block DoH by default + fix Android tunnel_doh config mismatch#763
Conversation
Problem: PR therealaleph#468 changed `tunnel_doh` default to `true` (tunnel DoH through Apps Script) to avoid ISP-blocked DoH on censored networks. But this added ~1.5s of Apps Script round-trip per DNS lookup — every page load got noticeably slower because Chrome's DoH connections had to traverse the full tunnel path before the page could even start connecting. The Android side had a separate bug: `tunnelDoh` defaulted to `false` but only emitted `tunnel_doh` to JSON when `true`. Since the Rust default is `true`, omitting the field meant Rust always tunneled DoH regardless of the Android UI setting — bypass_doh was silently broken on Android. Fix: - Add `block_doh` config option: immediately reject (RST) connections to known DoH endpoints. Browsers fall back to system DNS, which tun2proxy handles via virtual DNS (instant, zero tunnel cost). Eliminates the DoH round-trip without exposing DoH connections to the ISP (unlike bypass_doh which sends DoH direct). - Default `block_doh: true` on Android — tested on Chrome/Brave, falls back to virtual DNS correctly. - Fix Android `tunnelDoh` default to `true` (matches Rust). - Always emit `tunnel_doh` and `block_doh` explicitly in Android JSON serialization — no more default-mismatch bugs. - Add Block DoH and Bypass DoH toggles in Android Advanced UI. Block DoH takes priority; Bypass DoH is disabled when Block is on. Tested on Pixel 6 Pro: zero chrome.cloudflare-dns.com tunnel sessions with block_doh=true. All DNS resolves instantly via tun2proxy virtual DNS. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@yyoyoian-pixel — reviewed locally (179 lib + 35 tunnel-node tests still pass). Merging. The DoH block is the right call — DoH-via-Apps-Script was wasting tunnel quota on a use case (encrypted DNS) where browsers will happily fall back to system DNS, which tun2proxy resolves via virtual DNS at zero cost. The Block > Bypass priority + the disabled Bypass switch when Block is on is a good UX pattern. The Android Will ship in the next release. [reply via Anthropic Claude | reviewed by @therealaleph] |
Wraps three already-merged PRs into a release: - PR #763 (@yyoyoian-pixel): block_doh: true default; rejects browser DoH at SOCKS5 listener so it falls back to system DNS via tun2proxy virtual DNS instead of paying ~1.5s tunnel round-trip per name lookup. Also fixes the Android tunnel_doh config mismatch (was false on Android, true on Rust — silently broke bypass_doh_hosts). - PR #751 (@yyoyoian-pixel): TLS pool refill loop keeping ≥8 ready connections, freshest-first acquire, pool TTL 45→60s, coalesce step 10→200ms (more conservative revert from v1.9.8 for full-mode batch packing). - PR #747 (@Shjpr9): added github.io to Fastly fronting group example. Tests: 179 lib + 35 tunnel-node green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…doh field Both v1.9.11 and v1.9.12 release CI runs failed because PR #763 added a new `block_doh: bool` field to `Config` but didn't update `src/bin/ui.rs::FormState::to_config()` which builds Config via a struct literal — caught by `cargo build --features ui --bin mhrv-rs-ui` only, not by the lib `cargo test` I'd run during PR review. Added the field to FormState (round-trip from Config), to ConfigWire (skip_serializing_if = "is_true" so default-true configs stay clean), and a new is_true helper. Verified mhrv-rs-ui release build green locally before pushing. Net effect: v1.9.13 ships everything v1.9.11 and v1.9.12 were supposed to ship (DoH block by default, TLS pool refill loop, github.io fronting group, parallel_relay safe-method gating) plus this UI fix. No additional behavior change. Tests: 180 lib + 35 tunnel-node + UI release-mode build all green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR #763 added `block_doh: bool` with `#[serde(default)]`, which resolves to Rust's `Default::default() = false` for bool, not the `true` PR #763's docs intended. Existing configs upgrading from v1.9.10 → v1.9.13 had no block_doh field, so they got `false` paired with `tunnel_doh: true` (new default from #468) — every browser DoH lookup got tunneled through Apps Script, adding ~1.5s overhead per page load. User-perceived as "v1.9.13 is slower than v1.9.10" in #773. Switched to a named-default function `default_block_doh() -> bool { true }` so the upgrade path actually delivers the fast block-then-system-DNS behaviour PR #763 advertised. Power users who specifically want browser DoH (with the latency cost) can still opt in with explicit `block_doh: false`. Tests: 180 lib + 35 tunnel-node + UI release-mode build all green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Great , tnx for adding this option i really appreciate it 🙏❤️ |
Summary
block_doh: true): immediately reject connections to known DoH endpoints (chrome.cloudflare-dns.com, dns.google, etc.). Browsers fall back to system DNS, which tun2proxy handles via virtual DNS — instant, zero tunnel cost. Saves ~1.5s per domain lookup vs tunneling DoH through Apps Script.block_quic: true): default on, with UI toggle on Android and desktop. QUIC over the TCP tunnel causes TCP-over-TCP meltdown (<1 Mbps). Browsers fall back to HTTPS/TCP within seconds. Closes Feat : Quic block in ui #793.tunnelDohdefaulted tofalseon Android buttrueon Rust. When Android omitted the field (default = don't emit), Rust used its own default (true) — sobypass_dohwas silently broken on Android. Now Android always emitstunnel_dohexplicitly and defaults match Rust.Context
PR #468 changed
tunnel_dohtotruebecause Iranian ISPs block direct DoH endpoints. This was the right call for censorship resistance, but it made every page load ~1.5s slower per domain (Chrome's DoH connections now traversed the full Apps Script tunnel).block_dohsolves both problems: no ISP-visible DoH connection (the connection never leaves the device), no tunnel round-trip (system DNS is instant via tun2proxy virtual DNS).Test plan
chrome.cloudflare-dns.comtunnel sessions withblock_doh=true🤖 Generated with Claude Code