feat(direct): use mhrv-rs as upstream proxy for Psiphon / xray#1189
feat(direct): use mhrv-rs as upstream proxy for Psiphon / xray#1189dazzling-no-more wants to merge 2 commits into
Conversation
- ConfigStore.toJson(): drop a duplicate `fronting_groups` put left behind when therealaleph#1033 (fronting groups) + therealaleph#1057 (extras passthrough) + therealaleph#1189 (draft-drop filter) were squash-merged in sequence. The later filtered put was being overwritten by the older unfiltered one, breaking the ConfigStoreFrontingGroupsTest expectation that draft groups never reach disk. - ProfileStoreTest.applyProfile_*_returns_partial: the snapshot config was missing a deployment ID, so validateRuntimeShape rejected it as 'apps_script mode requires script_id' before the test's injected write failure could be exercised. Pre-existing bug in therealaleph#1057's tests; only surfaced now that we run the full suite on the integrated branch.
|
Reviewed via Anthropic Claude. Big PR — 2591 lines across desktop UI, Android UI, JNI, config, new Strong yes on the core idea. The Iranian community has been chaining mhrv-rs + Psiphon/xray manually for months (see patterniha/MITM-DomainFronting + B3hnamR/PsiphonOverMITM on Windows). Direct mode already does the right thing technically; this PR closes the discoverability gap with proper UI surfacing + cross-platform docs. That's a real win. Things I want to verify before merging (asking for some answers rather than blocking): 1.
Option (a) is fine. Option (b) is a network-behavior change worth flagging — outbound probes from a censorship-circumvention tool can leak side-channel signals on hostile networks. If active probing, would want it opt-in via config and disabled-by-default. 2. UI banner + LAN IP surfacing — confirm the LAN IP is only shown when 3. Android 4. Default Plan:
Could you respond to (1)-(4) above + add the smoke-test checklist to the PR body? That's enough for me to land it. Re: the bundled docs ( [reply via Anthropic Claude | reviewed by @therealaleph] |
|
Follow-up verification from today's DOPR:
I also checked the earlier review questions against the current diff:
Given the size of this PR and the previous note about a 5-7 day community-testing window, I am leaving it open rather than merging today. The Rust side looks healthy; the remaining risk is Android UI/build verification plus real user testing for Psiphon/xray chaining. [reply via Anthropic Claude | reviewed by @therealaleph] |
Summary
Adds a documented "use mhrv-rs as upstream proxy" path for Psiphon, xray, SwitchyOmega, etc. Direct mode already does the right thing technically — unmatched hosts fall through to plain TCP — but nothing surfaced this to users. Now the UI shows the copyable upstream address when running in Direct mode, and a new doc page walks through Psiphon setup on every platform.
Why
A few projects in the censorship-circumvention space already document this pairing on Windows: patterniha/MITM-DomainFronting (Xray config) and B3hnamR/PsiphonOverMITM (PowerShell launcher that bundles xray.exe + that config). The Persian-speaking user base in particular has been chaining them manually — set Psiphon's upstream proxy to the local Xray, so Psiphon's bootstrap traffic reaches its servers via fronted SNI.
We already implement everything they do (MITM + domain fronting in
directmode) — just nobody knew. This PR closes the discoverability gap, cross-platform and without bundling anything.What's in this PR
Desktop UI (
src/bin/ui.rs)127.0.0.1:8085 [copy]).0.0.0.0,[::], empty) collapse to127.0.0.1in the copy text so Windows users don't paste an address Winsock will reject as a connect target.detect_lan_ip()) for pasting into Psiphon on a different device.Shared helper (
src/lan_utils.rs)advertise_proxy_host()that normalizes wildcard / empty binds to127.0.0.1.Android UI (
HomeScreen.kt,strings.xml,values-fa/strings.xml)stringResource(5 new keys in eachstrings.xml).Columninstead of aRowso the label/address/copy stack vertically — survives Persian text and large font sizes without cramping.connectionMode == PROXY_ONLY. InVPN_TUNmode (the default), a red warning appears explaining that Android allows only one active VPN slot and Psiphon needs it — user has to stop mhrv-rs, switch to PROXY_ONLY, and reconnect first.Docs
docs/use-as-upstream.md+ Persian mirrordocs/use-as-upstream.fa.md.README.md(English + Persian) pointing at the new doc.Engineering note
No new transport, no new
Modevariant, no protocol change. Direct mode's dispatch insrc/proxy_server.rsalready routes unmatched hosts toplain_tcp_passthrough, which is exactly what Psiphon's bootstrap traffic needs — its end-to-end crypto stays intact and cert pinning isn't broken. This PR is UX + docs only.Test plan
cargo check --all --features ui— cleancargo test --lib lan_utils— 4 passed (advertise_proxy_host_collapses_wildcards_to_loopbacknew)./gradlew :app:compileDebugKotlin— cleancopyon the upstream banner → paste into Psiphon's Upstream Proxy field → Psiphon connects through mhrv-rsVPN_TUNmode): verify the red warning appears and the address is greyed outPROXY_ONLYmode): verify the address renders green andcopyworksdocs/use-as-upstream.fa.mdon GitHub, confirm every numbered item renders RTL (first strong character of each item is a Persian letter, not a Latin word)Persian rendering rule (for future reviewers)
The Unicode bidi algorithm picks paragraph direction from the first strong character. Persian numerals (
۱۲۳), markdown markers (**,[,#), and bullets are all bidi-weak. A Persian list item like۱. mhrv-rs را باز کنreads its first strong char asminmhrv-rsand flips LTR (visibly broken). Lead each Persian paragraph or list item with a Persian word — never a product name or English UI label.Credits
The Psiphon-upstream chain pattern documented here was already practiced in the community via patterniha/MITM-DomainFronting and packaged for Windows by B3hnamR/PsiphonOverMITM. This PR makes the same workflow work natively, on every platform mhrv-rs already supports, without bundling an external engine.