RKNnoVPN/RKNNOVPN_ARCHITECTURE.md
loop-uh 5260d4f31a Recover uncommitted working tree from user-supplied archive
Preserved on a recovery branch; stable main remains at v2.4.1.
2026-08-07 00:32:07 +03:00

5.5 KiB
Raw Permalink Blame History

Архитектура RKNnoVPN

RKNnoVPN - прозрачный прокси-стек для rooted Android без Android VpnService, TUN-интерфейса и системной VPN-индикации. Архитектура v2 является local-first: APK полностью usable без root/module, а root runtime является опциональным исполнителем сетевой конфигурации.

Ownership

APK

APK owns:

  • user profile;
  • nodes and subscriptions;
  • subscription fetch/parse/merge;
  • update check and artifact download;
  • UI state and user-visible settings;
  • rendering the root runtime config passed to the module.

APK can run without root/module. Missing, old, denied or malformed runtime must disable only runtime actions such as start/stop/reset/logs/module staging. It must not block profile editing, subscription management, update checks, or app startup.

Runtime/module

Runtime/module owns:

  • applying rendered runtime config;
  • starting, stopping and resetting root networking;
  • sing-box/Xray process lifecycle;
  • iptables/DNS/policy-routing scripts;
  • minimal status/logs/version responses.

Runtime/module is optional. Every runtime action must exact-match the APK release version and wire epoch. Negotiation, startup remediation loops and generated method surfaces are not supported architecture.

Removed Old Paths

Do not restore:

  • APK startup -> root runtime status probe -> generated surface parse -> blocked UI;
  • runtime-owned user profile files;
  • root-required subscriptions;
  • root-required update check/download;
  • generated method-surface parsing or method capability gates in APK startup;
  • embedded panel/config fallbacks or profile carry-forward for old installs;
  • socket/JSON-RPC control plane.

Unsupported old state should fail clearly or be replaced by current canonical state. It should not be carried forward silently.

Current Control Flow

APK profile/subscriptions/settings
  -> APK renders runtime config JSON
  -> su -c /data/adb/modules/rknnovpn/bin/rknnovpn-runtime apply <config>
  -> rknnovpn-runtime validates/saves module config
  -> rknnovpn-runtime renders sing-box/Xray runtime files
  -> start/stop/reset operate only on root networking

rknnovpn-runtime version returns release version, version code and wire epoch. The APK compares those values against its own release before runtime actions.

rknnovpn-runtime status returns only runtime state needed by the UI: connection state, minimal health booleans, uptime and traffic when available. It must not return APK-owned profile, subscription, update check or update download state.

rknnovpn-runtime start, stop, restart and reset return an explicit runtime action result envelope, not a bare status snapshot. The action result contains:

accepted, status, stage, runtimeCode, userMessage, debug, rollbackApplied

This lets the APK distinguish a valid runtime response whose action was rejected or degraded from a missing runtime, root denial, timeout, non-zero shell failure or malformed protocol response. A rejected action still publishes the returned runtime status as a reachable runtime result; only transport/protocol failures mark the root runtime unavailable.

rknnovpn-runtime logs returns bounded runtime logs. It must not expose raw APK profile storage.

Runtime CLI contract checks are fixture-based, not generated. The APK test resources under app/app/src/test/resources/runtime/ and Go fixtures under runtime/testdata/ must stay byte-equivalent for minimal version, status, runtime action, ping, and test-node envelopes. These fixtures are exact-version protocol smoke tests only; do not add codegen, method negotiation, capability discovery or a generated daemon contract back into this path.

Storage

APK profile storage:

<APK private files>/rknnovpn/profile.json

This is the only user profile source of truth.

Runtime config storage:

/data/adb/modules/rknnovpn/config/config.json

This is a rendered runtime config owned by the apply path. It may contain a profile projection needed by the renderer, but that projection is not a user profile database and must not be treated as runtime-owned user intent.

Rendered core config:

/data/adb/modules/rknnovpn/config/rendered/singbox.json

Root runtime cleanup is owned by:

/data/adb/modules/rknnovpn/scripts/rescue_reset.sh

Shared module paths, marker semantics and permission helpers live in:

/data/adb/modules/rknnovpn/scripts/lib/rknnovpn_env.sh

Update Flow

APK checks GitHub releases, downloads module/APK artifacts, and verifies checksums. Module staging is a runtime action because it writes to root-owned module storage, so it requires exact APK/runtime version match. Update check/download themselves must not require runtime.

Runtime module staging must build the root-manager pending update layout:

/data/adb/modules_update/rknnovpn
/data/adb/ksu/modules_update/rknnovpn
/data/adb/ap/modules_update/rknnovpn

The staged directory is an already-materialized module layout with bin/, scripts/, config/, run/, logs/, the installed release catalog (releases/<version>/install-manifest.json plus current), and module entrypoint files. It must not be a raw downloaded module zip stored under the active module's releases/ catalog.

Verification Surface

GitHub Actions is the authoritative broad verification and release surface. Local checks should stay focused on the edited slice unless explicitly requested or needed to debug a CI failure.