Skip to content
Quickstarts

Android quickstart

Build the ForestVPN Android tunnel runtime from source with cargo-ndk and bridge it from your VpnService.

The Android surface is the forestvpn-android-jni crate — the tunnel runtime compiled as a cdylib (libforestvpn_android_jni.so) that your VpnService drives over a small, stable C ABI.

Honest distribution note: this path is source-only today. There is no prebuilt AAR, no Maven artifact, and no Kotlin/Java wrapper library — you build the shared library from source and bring your own JNI (or JNA) bridge. If that changes, this page will change with it.

Prerequisites

  • The Rust toolchain (rustup.rs) with the Android targets (rustup target add aarch64-linux-android)
  • cargo-ndk (cargo install cargo-ndk)
  • The Android NDK, with ANDROID_NDK_HOME set
  • A checkout of the ForestVPN repository

1. Get the source

git clone [email protected]:forestvpn/forestvpn.git
cd forestvpn

2. Build the shared library

android-jni-build.sh
#!/usr/bin/env bash
# Build the ForestVPN Android tunnel runtime from source (the only
# distribution path today — no prebuilt AAR ships). Run from the repo root.
# Prerequisites: the Rust toolchain, cargo-ndk, and the Android NDK
# (ANDROID_NDK_HOME).
set -euo pipefail

cd forestvpn-sdk
cargo ndk -t arm64-v8a build -p forestvpn-android-jni --release
# → target/aarch64-linux-android/release/libforestvpn_android_jni.so

Add more -t targets (armeabi-v7a, x86_64) as your ABI matrix needs. Copy the resulting .so into your app module's src/main/jniLibs/<abi>/ directory and load it with System.loadLibrary("forestvpn_android_jni").

3. The C ABI you bridge

The library exports a compact extern "C" surface (see forestvpn-sdk/crates/forestvpn-android-jni/src/exports.rs — the authoritative signatures live there):

Entry pointWhat it does
fvpn_android_abi_versionABI version handshake — check it before anything else
fvpn_android_initializeCreate a tunnel runtime from an established VpnService TUN fd + a versioned runtime config
fvpn_android_set_target_stateDrive the tunnel state machine (secured / unsecured)
fvpn_android_apply_runtime_configApply a new runtime config to a live runtime
fvpn_android_statusRead the runtime's status document
fvpn_android_last_error_messageCopy the thread-local error message after a failed call
fvpn_android_shutdownTear down and free the runtime handle

The flow mirrors every other ForestVPN tunnel platform: your VpnService establishes the TUN interface, hands its fd plus the runtime config from the control plane to fvpn_android_initialize, then sets the target state to secured. Status and errors are polled through the same handle.

Verified by

scripts/quickstart-verify/android-jni.sh — asserts the crate exists at the documented path, that every entry point named above is really exported, and (when cargo-ndk + the NDK are present) runs the exact build script this page embeds. Without the Android toolchain the build leg skips loudly.