Commit Graph

10 Commits

Author SHA1 Message Date
Shin (Former Aleph) 91015b0594 v1.0.0: multi-arch Android APK + GitHub Actions release job + install docs (#30)
Version bump reflects the scope — a unified Rust core that now ships
for desktop (Linux/macOS/Windows) AND Android from the same crate.

Android changes:
- build.gradle.kts: ABI filters expanded to arm64-v8a + armeabi-v7a
  + x86_64 + x86. cargoBuild{Debug,Release} pass all four ABIs to
  cargo-ndk in a single invocation. normalizeTun2proxySo() walks every
  ABI dir now (was arm64-only).
- Release buildType signs with the debug keystore — no Play Store
  target, so signature identity doesn't matter, installability does.
  Gradle auto-provisions ~/.android/debug.keystore if absent, so CI
  runners inherit this without extra setup.
- versionName 1.0.0, versionCode 100 (room to bump monotonically).

CI:
- release.yml gets a dedicated `android:` job that sets up JDK 17,
  Android SDK/NDK 26, all four rust-android targets, installs
  cargo-ndk, runs assembleRelease, and uploads a single universal APK
  named `mhrv-rs-android-universal-v<version>.apk` into the same
  `dist/` collected by the release job downstream.
- `release:` job now gates on `needs: [build, android]` so tagging
  v1.0.0 triggers both build matrices before cutting the GitHub
  release.

Docs:
- docs/android.md — full 10-step install walk-through: APK sideload,
  Apps Script deployment (with "Advanced → Go to (unsafe) → Allow"
  reality check), config paste, SNI reachability test, MITM CA
  install with OEM-specific nav paths (Pixel / Samsung / Xiaomi),
  Start, troubleshooting common failure modes. Also documents the
  known limitations — Cloudflare Turnstile loops (inherent to the
  Apps Script egress IP pool), UDP/QUIC not tunnelled, IPv6 leaks,
  Apps Script daily quota — so users know what to expect before
  trying it on a site that won't work.
- releases/README.md — APK row added to the English and Persian
  tables, version bumped everywhere to v1.0.0.
- Top-level README — Android listed under Platforms with a link
  to docs/android.md.

Release artifact:
- releases/mhrv-rs-android-universal-v1.0.0.apk — 38 MB universal
  APK built locally from this tree. Installs + launches on API 24+.
  The CI job will regenerate it on tag push; this is the copy
  committed for users who can't reach GitHub Releases.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 02:56:39 +03:00
therealaleph 3534747e68 v0.8.6: armhf glibc pin + Check-for-updates button (#15)
=== PR #14 follow-up: armhf build runs on Pi Bookworm/Bullseye ===

PR #14 (merged earlier) added arm-unknown-linux-gnueabihf to the
release matrix but pinned os=ubuntu-latest, which is 24.04 with GLIBC
2.39. Target armhf sysroot on 24.04 is Debian Trixie (GLIBC 2.39),
far too new for a Raspberry Pi 2/3 on Bookworm (2.36) or Bullseye
(2.31) — users would get 'GLIBC_2.39 not found' the same way the
Linux-amd64 issue #2 folks did before we pinned them to 22.04.

Fix: pin the armhf matrix entry to ubuntu-22.04, matching our other
linux-gnu targets. Binary will link against GLIBC 2.35 max, which
loads on Pi Bookworm and Bullseye. Also trimmed two trailing spaces.

Locally verified the cross-compile: rust:latest + gcc-arm-linux-
gnueabihf + proper CARGO_HOME config.toml produces a valid ARM 32-bit
ELF (2.9 MB, armhf EABI5).

=== Issue #15: 'Check for updates' button in the UI ===

New src/update_check.rs module. On the user's click (no polling):

  1. Tcp-probes github.com:443 with a 5s budget. If unreachable, we
     return Offline(reason) instead of a confusing 'update check
     failed' — distinguishes 'you're offline' from 'GitHub API
     misbehaved'.

  2. HTTPS GET api.github.com/repos/.../releases/latest via the
     tokio + rustls stack (same hand-rolled HTTP pattern as
     domain_fronter — no new crate deps). Parses tag_name, strips
     the v-prefix, loose-semver-compares to env!(CARGO_PKG_VERSION).

  3. Returns one of four UpdateCheck variants: Offline / Error /
     UpToDate / UpdateAvailable { release_url }.

New UI wiring (src/bin/ui.rs):
  - Cmd::CheckUpdate enqueue variant
  - UiState::last_update_check { InFlight, Done(result) }
  - 'Check for updates' button next to the CA buttons
  - Result displayed as a colored small-text line under the CA info:
    green 'up to date', amber 'update available v0.8.5 → v0.8.6' with
    a clickable release-page hyperlink, red for offline/error.

Verified end-to-end with a live github.com fetch (got a rate-limit
HTTP 403 from my IP because I've been hitting the API a lot, but
that's the expected Error() state — response classification was
correct). Three unit tests for is_newer() and a gated live test for
the full round-trip.

43 tests pass.
2026-04-22 19:03:14 +03:00
Hamed Soltani b617f67c6f add armhf arch to build targets 2026-04-22 18:18:44 +03:30
therealaleph 04661bfdec v0.7.1: Linux GLIBC 2.35 floor + scroll main window on short screens
Two user-reported issues.

=== GLIBC too new (reported via twitter) ===

Our linux-amd64 and linux-arm64 gnu builds were compiled on
ubuntu-latest (24.04, GLIBC 2.39), which means the resulting binaries
refuse to load on anything older:

  ./mhrv-rs: /lib/x86_64-linux-gnu/libc.so.6: version 'GLIBC_2.39'
    not found (required by ./mhrv-rs)

Users on Ubuntu 22.04 / Mint 21 (GLIBC 2.35) — the typical user in Iran
where this project's target audience lives, and where they can't
dist-upgrade because they're behind exactly the kind of network
restriction this tool exists to bypass — could not run the gnu builds
at all.

Fix: pin the linux-gnu matrix entries to ubuntu-22.04 runners. GLIBC
2.35 is now the minimum; binaries load on Ubuntu 22.04, Mint 21,
Debian 12, Fedora 36+, RHEL 9+ and everything newer.

Users on older distros (Ubuntu 20.04, CentOS 7) can still use the
static musl builds (mhrv-rs-linux-musl-amd64.tar.gz et al.) which
have no GLIBC dependency at all.

=== Short-screen laptops — main window content clipped (PR #6) ===

Co-authored fix from @v4g4b0nd-0x76 in PR #6 (manually applied to
avoid pulling in 400 lines of unrelated cargo-fmt churn):

- Wrap the CentralPanel body in ScrollArea::vertical()
  .auto_shrink([false; 2]) so everything stays reachable on short
  screens.
- Lower the min_inner_size from [420, 540] to [420, 400] so laptops
  with ~13" screens at default scaling can shrink the window without
  clipping UI elements.

Closes #6.

Co-authored-by: v4g4b0nd-0x76 <v4g4b0nd-0x76@users.noreply.github.com>
2026-04-22 11:08:57 +03:00
therealaleph fdd6c200d6 ci: drop --user on musl docker build (caused /root/.cargo permission denied)
The messense/rust-musl-cross images expect to run as root so cargo can
write to /root/.cargo. Overriding the container user to match the host
UID broke cargo's registry cache with 'Permission denied' before a
single file compiled. Drop the flag and chown the target/ tree after
the build instead.
2026-04-22 02:32:56 +03:00
therealaleph 6c5b62e5e6 v0.5.1: static musl builds for OpenWRT (amd64 + arm64)
A user on OpenWRT x86_64 reported the linux release doesn't run there —
root cause was glibc vs musl mismatch (our gnu binary was looking for a
dynamic linker that doesn't exist on router userlands). Add two musl
targets that produce fully static PIE binaries:

- x86_64-unknown-linux-musl  -> mhrv-rs-linux-musl-amd64.tar.gz
- aarch64-unknown-linux-musl -> mhrv-rs-linux-musl-arm64.tar.gz

CI uses the messense/rust-musl-cross docker images (better-maintained
than cargo-zigbuild with a pinned zig, which has version regressions
on the ar wrapper between 0.13 and 0.16).

Locally verified:
- both archs cross-compile green in docker
- resulting x86_64 binary (3.3 MB) runs in an alpine:latest container,
  --version / --help work, no dynamic lib requirements

The musl archive skips the UI (routers are headless) and swaps run.sh
for a procd init script (assets/openwrt/mhrv-rs.init) expecting the
binary at /usr/bin/mhrv-rs and config at /etc/mhrv-rs/config.json.

Side effect: switched tokio-rustls to default-features=false + ring
(was pulling aws-lc-rs transitively, which can't easily cross-compile
for musl). The main crate already uses ring explicitly, so no runtime
behavior change.

README gets a 'Running on OpenWRT (or any musl distro)' section in
both English and Persian with scp + procd enable/start recipe.
Closes #2.
2026-04-22 02:29:26 +03:00
therealaleph 899ef06f4a v0.4.1: launcher scripts (run.sh / run.command / run.bat)
First run needs the CLI to install the MITM CA into the system trust
store (sudo/admin prompt), which the UI alone can't do reliably from a
double-click. Add a small launcher for each platform that runs the CLI
with --install-cert once, then starts the UI. Each release archive now
contains a run.* script alongside the binaries.
2026-04-21 22:17:25 +03:00
therealaleph 3eb0d9667a ci: simplify aarch64-linux cross-compile (CLI-only, skip UI)
The arm64 multiarch apt setup was failing because the Azure mirror on
GitHub runners only serves amd64. Since we don't build the UI for
aarch64-linux (server target), we only need the cross-compiler itself,
which is amd64-native. Drop the arm64 system libs and the best-effort
UI build step.
2026-04-21 21:48:39 +03:00
therealaleph e4fe2b5939 v0.4.0: add cross-platform desktop UI (egui)
New bin 'mhrv-rs-ui' behind the 'ui' feature flag. CLI users pay
zero egui compile cost; UI users get a single static binary.

UI features:
- Config form (Apps Script ID, auth key, Google IP, front domain,
  ports, log level, verify_ssl)
- Start/Stop buttons that spawn the proxy on a dedicated tokio thread
- Live stats (relay calls, failures, cache hit rate, bytes relayed,
  blacklisted scripts) polled every ~700ms
- Test button (end-to-end relay probe)
- Install CA / Check CA buttons
- Recent log panel (last 200 lines)
- Dense, dark, utility-look: no emojis, no cards, no gradients

Architecture:
- Refactored crate into lib + two bins (mhrv-rs, mhrv-rs-ui).
  src/lib.rs exposes all modules, main.rs uses them via 'use mhrv_rs::...'
- New src/data_dir.rs: platform-appropriate user data dir
  (~/Library/Application Support/mhrv-rs on macOS,
   ~/.config/mhrv-rs on Linux, %APPDATA%\mhrv-rs on Windows).
  CLI falls back to ./config.json for backward compat.
- CA moves to {data_dir}/ca/ca.crt (was ./ca/ca.crt).
- UI background thread owns the tokio runtime and proxy handle;
  communicates with UI via std::mpsc commands + Arc<Mutex<UiState>>.
- macOS .app bundle: assets/macos/Info.plist template + build-app.sh
  that assembles .app from the binary. Bundled into release zips.
- CI: Linux system libs (libxkbcommon, libwayland, libxcb*, libx11,
  libgl, libgtk-3) installed on Ubuntu runners for eframe. aarch64
  Linux UI is best-effort cross-compile. Windows MinGW, macOS native.

25 lib tests still pass. 5MB release UI binary on macOS.
2026-04-21 21:36:52 +03:00
therealaleph 2dd8be72ca initial release: Rust port of MasterHttpRelayVPN apps_script mode
Faithful port of @masterking32's MasterHttpRelayVPN. All credit for
the original idea, protocol, and Python implementation goes to him.

Implemented:
- Local HTTP proxy (CONNECT + plain HTTP)
- MITM with on-the-fly per-domain cert generation via rcgen
- CA auto-install for macOS / Linux / Windows
- Apps Script JSON relay, protocol-compatible with Code.gs
- TLS client with SNI spoofing (connect to Google IP, SNI=www.google.com,
  inner HTTP Host=script.google.com)
- Connection pooling (45s TTL, max 20 idle)
- Multi-script round-robin for higher quota
- Header filtering (strips connection-specific + brotli)
- Config-driven, JSON schema matches Python version

Deferred (TODOs in code):
- HTTP/2 multiplexing
- Request batching / coalescing / response cache
- Range-based parallel download
- SNI-rewrite tunnels for YouTube/googlevideo
- Firefox NSS cert install
- domain_fronting / google_fronting / custom_domain modes
  (mostly broken post-Cloudflare 2024, not a priority)

13 unit tests pass, 2.4MB stripped release binary.
2026-04-21 18:03:03 +03:00