ReVoltVPN 3.3.5: hardened Android runtime and verified TUN/SOCKS5 #3

Closed
Naveax wants to merge 6 commits from release/3.3.5 into main
pull from: release/3.3.5
Naveax commented 2026-09-03 22:18:23 +03:00 (Migrated from github.com)

Summary

This prepares ReVoltVPN 3.3.5 (3.3.5+31) from the hardened Android branch and supersedes the 3.3.4 beta runtime model with device-validated behavior.

Runtime and session safety

  • Keep per-session VLESS UUID/SOCKS credentials memory-only. Only the non-secret runtime generation token and expiry deadline are persisted for OS expiry enforcement.
  • Fail closed after process restart if Android cannot redeliver the original runtime config instead of reconstructing a tunnel from secrets on disk.
  • Enforce session expiry in the native VPN service with both a monotonic handler and AlarmManager.
  • Scope STOP/disconnect handling to the active runtime generation so stale notifications/intents cannot stop a newer tunnel.
  • Harden Flutter/native lifecycle handling around permission Activity detach, async disposal and rapid connect/disconnect races.

Network/runtime hardening

  • Full IPv4 + IPv6 TUN routes.
  • Fail-closed TUN and DNS setup.
  • Authenticated ephemeral loopback SOCKS5.
  • Xray/tun2socks recovery while the TUN remains fail closed.
  • Explicit TUN and SOCKS5 behavior retained.
  • Unknown/legacy persisted modes fail closed to TUN.

Control-plane hardening

  • Control responses are size bounded and nonce/call-generation bound.
  • Tunnel destination remains pinned to the compiled server IP/443 trust anchor.
  • REALITY/XHTTP session fields are validated before runtime start.
  • Control-plane requests do not follow HTTP redirects.
  • Existing AdMob bypass/callback behavior is intentionally unchanged.

Build/release hardening

  • Vendored flutter_vless_android 1.1.5 replaces build-time pub-cache mutation/patchers.
  • Gradle wrapper/dependency verification remains fail closed.
  • Production app config is SHA-256 pinned and release signing stays external to the repository.
  • R8/proguard release smoke build is part of CI.

UI

  • Connect button now gives immediate selection haptic on an accepted tap and success feedback after connect/disconnect.
  • Haptics default to enabled on fresh installs while remaining user-toggleable.

Why 3.3.5 instead of extending 3.3.4

The published v3.3.4 is marked beta and uses app-private disk persistence for session credentials/VLESS UUID so START_STICKY can rebuild the tunnel. This PR intentionally changes that security model: session secrets stay memory-only and a restart without the original config fails closed. Together with the additional lifecycle/network hardening and completed physical-device validation, this is better represented as 3.3.5 rather than a silent replacement of the 3.3.4 beta.

Validation

Physical Android device matrix: 25/25 PASS, including TUN, SOCKS5, Wi-Fi/mobile transitions, IPv4/IPv6, DNS behavior, screen-off/background/Doze/Battery Saver, app/process lifecycle, session expiry, notification disconnect/stale generation, permission lifecycle and rapid connect/disconnect cases.

Final release-prep commit: b711205f764e17376f59b3aea5455c129c6d82b1

Final fork CI: Android CI run #66 (33790162881) — SUCCESS

  • Flutter analyze: PASS
  • Flutter tests: PASS
  • Android lint: PASS
  • production release config fail-closed gate: PASS
  • cold + warm debug APK builds: PASS
  • vendored runtime immutability: PASS
  • release R8 smoke build: PASS
  • tracked build-input immutability: PASS

Upstream base verified at 9ac236a981061931db5faf6d2cbb72b6fabe5e41; branch is ahead with no upstream commits missing at preparation time.

The older revoltvpn_timer_fix.patch patcher-based approach is intentionally not reintroduced: this branch removes build-time runtime patchers and carries the hardened native runtime directly as vendored source.

## Summary This prepares **ReVoltVPN 3.3.5 (`3.3.5+31`)** from the hardened Android branch and supersedes the 3.3.4 beta runtime model with device-validated behavior. ### Runtime and session safety - Keep per-session VLESS UUID/SOCKS credentials **memory-only**. Only the non-secret runtime generation token and expiry deadline are persisted for OS expiry enforcement. - Fail closed after process restart if Android cannot redeliver the original runtime config instead of reconstructing a tunnel from secrets on disk. - Enforce session expiry in the native VPN service with both a monotonic handler and `AlarmManager`. - Scope STOP/disconnect handling to the active runtime generation so stale notifications/intents cannot stop a newer tunnel. - Harden Flutter/native lifecycle handling around permission Activity detach, async disposal and rapid connect/disconnect races. ### Network/runtime hardening - Full IPv4 + IPv6 TUN routes. - Fail-closed TUN and DNS setup. - Authenticated ephemeral loopback SOCKS5. - Xray/tun2socks recovery while the TUN remains fail closed. - Explicit TUN and SOCKS5 behavior retained. - Unknown/legacy persisted modes fail closed to TUN. ### Control-plane hardening - Control responses are size bounded and nonce/call-generation bound. - Tunnel destination remains pinned to the compiled server IP/443 trust anchor. - REALITY/XHTTP session fields are validated before runtime start. - Control-plane requests do not follow HTTP redirects. - Existing AdMob bypass/callback behavior is intentionally unchanged. ### Build/release hardening - Vendored `flutter_vless_android` 1.1.5 replaces build-time pub-cache mutation/patchers. - Gradle wrapper/dependency verification remains fail closed. - Production app config is SHA-256 pinned and release signing stays external to the repository. - R8/proguard release smoke build is part of CI. ### UI - Connect button now gives immediate selection haptic on an accepted tap and success feedback after connect/disconnect. - Haptics default to enabled on fresh installs while remaining user-toggleable. ## Why 3.3.5 instead of extending 3.3.4 The published `v3.3.4` is marked beta and uses app-private disk persistence for session credentials/VLESS UUID so `START_STICKY` can rebuild the tunnel. This PR intentionally changes that security model: session secrets stay memory-only and a restart without the original config fails closed. Together with the additional lifecycle/network hardening and completed physical-device validation, this is better represented as **3.3.5** rather than a silent replacement of the 3.3.4 beta. ## Validation **Physical Android device matrix: 25/25 PASS**, including TUN, SOCKS5, Wi-Fi/mobile transitions, IPv4/IPv6, DNS behavior, screen-off/background/Doze/Battery Saver, app/process lifecycle, session expiry, notification disconnect/stale generation, permission lifecycle and rapid connect/disconnect cases. Final release-prep commit: `b711205f764e17376f59b3aea5455c129c6d82b1` Final fork CI: **Android CI run #66 (`33790162881`) — SUCCESS** - Flutter analyze: PASS - Flutter tests: PASS - Android lint: PASS - production release config fail-closed gate: PASS - cold + warm debug APK builds: PASS - vendored runtime immutability: PASS - release R8 smoke build: PASS - tracked build-input immutability: PASS Upstream base verified at `9ac236a981061931db5faf6d2cbb72b6fabe5e41`; branch is ahead with no upstream commits missing at preparation time. The older `revoltvpn_timer_fix.patch` patcher-based approach is intentionally not reintroduced: this branch removes build-time runtime patchers and carries the hardened native runtime directly as vendored source.

Pull request closed

This pull request cannot be reopened because the branch was deleted.
Sign in to join this conversation.