mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-09-01 00:39:24 +00:00
13f2ebfe12
Add config server client support for the C FFI and Android JNI bindings. Reuse the existing easytier::web_client::run_web_client path and NetworkInstanceManager; OHOS is unchanged. Report successful remote config apply/delete operations through a callback, with one JSON event per affected instance. Keep the config server client and FFI data plane mutually exclusive: once either side is in use, the other side returns an error instead of sharing lifecycle state.
204 lines
6.8 KiB
Rust
204 lines
6.8 KiB
Rust
//! JNI facade for Android callers of EasyTier.
|
|
//!
|
|
//! This file intentionally lists every Java-visible native method exported by
|
|
//! `libeasytier_android_jni.so`. The implementation details live in sibling
|
|
//! modules so this facade stays readable as an API map.
|
|
//!
|
|
//! Network management APIs:
|
|
//! - `setTunFd(instanceName, fd)`: attach an Android TUN fd to an instance.
|
|
//! - `parseConfig(config)`: validate TOML config text.
|
|
//! - `runNetworkInstance(config)`: start a local network instance.
|
|
//! - `retainNetworkInstance(instanceNames)`: retain named instances and stop the rest.
|
|
//! - `collectNetworkInfos()`: return running instance info as a JSON string.
|
|
//!
|
|
//! Config server client APIs:
|
|
//! - `startConfigServerClient(url, hostname, machineId, secureMode, callback)`:
|
|
//! start the managed remote config client.
|
|
//! - `stopConfigServerClient()`: stop the managed client and release its Java callback.
|
|
//! - `isConfigServerClientConnected()`: return whether the managed client is connected.
|
|
//!
|
|
//! Error API:
|
|
//! - `getLastError()`: return the latest FFI/JNI error string for the calling thread.
|
|
|
|
mod callback;
|
|
mod config_server_api;
|
|
mod error;
|
|
mod logger;
|
|
mod network_api;
|
|
mod strings;
|
|
|
|
use jni::JNIEnv;
|
|
use jni::objects::{JClass, JObject, JObjectArray, JString};
|
|
use jni::sys::{jboolean, jint, jstring};
|
|
|
|
/// Attach a TUN file descriptor to an EasyTier network instance.
|
|
///
|
|
/// Java signature:
|
|
/// `EasyTierJNI.setTunFd(instanceName: String, fd: Int): Int`
|
|
///
|
|
/// `instanceName` must name an instance known to the shared FFI instance cache.
|
|
/// The `fd` must be a valid Android TUN file descriptor. On failure this
|
|
/// returns `-1` and throws `RuntimeException` with the FFI error message when
|
|
/// one is available.
|
|
#[unsafe(no_mangle)]
|
|
pub extern "system" fn Java_com_easytier_jni_EasyTierJNI_setTunFd(
|
|
env: JNIEnv,
|
|
class: JClass,
|
|
inst_name: JString,
|
|
fd: jint,
|
|
) -> jint {
|
|
logger::init();
|
|
network_api::set_tun_fd_jni(env, class, inst_name, fd)
|
|
}
|
|
|
|
/// Validate a TOML network config string.
|
|
///
|
|
/// Java signature:
|
|
/// `EasyTierJNI.parseConfig(config: String): Int`
|
|
///
|
|
/// This only validates the config text; it does not start or mutate any
|
|
/// instance. On failure this returns `-1` and throws `RuntimeException`.
|
|
#[unsafe(no_mangle)]
|
|
pub extern "system" fn Java_com_easytier_jni_EasyTierJNI_parseConfig(
|
|
env: JNIEnv,
|
|
class: JClass,
|
|
config: JString,
|
|
) -> jint {
|
|
logger::init();
|
|
network_api::parse_config_jni(env, class, config)
|
|
}
|
|
|
|
/// Start one local EasyTier network instance from TOML config text.
|
|
///
|
|
/// Java signature:
|
|
/// `EasyTierJNI.runNetworkInstance(config: String): Int`
|
|
///
|
|
/// The instance name in the config must be unique in the FFI instance cache.
|
|
/// On failure this returns `-1` and throws `RuntimeException`.
|
|
#[unsafe(no_mangle)]
|
|
pub extern "system" fn Java_com_easytier_jni_EasyTierJNI_runNetworkInstance(
|
|
env: JNIEnv,
|
|
class: JClass,
|
|
config: JString,
|
|
) -> jint {
|
|
logger::init();
|
|
network_api::run_network_instance_jni(env, class, config)
|
|
}
|
|
|
|
/// Retain the named network instances and stop all other instances.
|
|
///
|
|
/// Java signature:
|
|
/// `EasyTierJNI.retainNetworkInstance(instanceNames: Array<String>?): Int`
|
|
///
|
|
/// Passing `null` or an empty array stops all instances. Null elements inside a
|
|
/// non-empty array are skipped. On failure this returns `-1` and throws
|
|
/// `RuntimeException`.
|
|
#[unsafe(no_mangle)]
|
|
pub extern "system" fn Java_com_easytier_jni_EasyTierJNI_retainNetworkInstance(
|
|
env: JNIEnv,
|
|
class: JClass,
|
|
instance_names: JObjectArray,
|
|
) -> jint {
|
|
logger::init();
|
|
network_api::retain_network_instance_jni(env, class, instance_names)
|
|
}
|
|
|
|
/// Collect running network instance information.
|
|
///
|
|
/// Java signature:
|
|
/// `EasyTierJNI.collectNetworkInfos(maxLength: Int): String?`
|
|
///
|
|
/// Returns a JSON string containing `NetworkInstanceRunningInfoMap`, or null if
|
|
/// collection fails. `maxLength` limits how many FFI entries are collected. On
|
|
/// failure this throws `RuntimeException` when an error message is available.
|
|
#[unsafe(no_mangle)]
|
|
pub extern "system" fn Java_com_easytier_jni_EasyTierJNI_collectNetworkInfos(
|
|
env: JNIEnv,
|
|
class: JClass,
|
|
max_length: jint,
|
|
) -> jstring {
|
|
logger::init();
|
|
network_api::collect_network_infos_jni(env, class, max_length)
|
|
}
|
|
|
|
/// Return the latest FFI/JNI error string for the calling thread.
|
|
///
|
|
/// Java signature:
|
|
/// `EasyTierJNI.getLastError(): String?`
|
|
///
|
|
/// This combines the FFI thread-local error with any pending config-server Java
|
|
/// callback error. It returns null when no error is available.
|
|
#[unsafe(no_mangle)]
|
|
pub extern "system" fn Java_com_easytier_jni_EasyTierJNI_getLastError(
|
|
env: JNIEnv,
|
|
class: JClass,
|
|
) -> jstring {
|
|
error::get_last_error_jni(env, class)
|
|
}
|
|
|
|
/// Start the managed config-server client.
|
|
///
|
|
/// Java signature:
|
|
/// `EasyTierJNI.startConfigServerClient(url, hostname, machineId, secureMode, callback): Int`
|
|
///
|
|
/// JNI only converts Java values and keeps the Java callback alive. The FFI
|
|
/// layer owns singleton lifecycle, config-server/data-plane mutual exclusion,
|
|
/// remote instance tracking, and callback event timing. If `callback` is
|
|
/// non-null, each remote apply/delete event is delivered to
|
|
/// `ConfigServerEventCallback.onEvent(eventJson)`.
|
|
///
|
|
/// On failure this returns `-1` and throws `RuntimeException`.
|
|
#[unsafe(no_mangle)]
|
|
pub extern "system" fn Java_com_easytier_jni_EasyTierJNI_startConfigServerClient(
|
|
mut env: JNIEnv,
|
|
_class: JClass,
|
|
config_server_url: JString,
|
|
hostname: JString,
|
|
machine_id: JString,
|
|
secure_mode: jboolean,
|
|
callback: JObject,
|
|
) -> jint {
|
|
logger::init();
|
|
config_server_api::start_config_server_client_jni(
|
|
&mut env,
|
|
config_server_url,
|
|
hostname,
|
|
machine_id,
|
|
secure_mode,
|
|
callback,
|
|
)
|
|
}
|
|
|
|
/// Stop the managed config-server client.
|
|
///
|
|
/// Java signature:
|
|
/// `EasyTierJNI.stopConfigServerClient(): Int`
|
|
///
|
|
/// The FFI layer performs the actual stop and managed instance cleanup. JNI
|
|
/// releases the Java callback reference after FFI stop succeeds. On failure
|
|
/// this returns `-1` and throws `RuntimeException`.
|
|
#[unsafe(no_mangle)]
|
|
pub extern "system" fn Java_com_easytier_jni_EasyTierJNI_stopConfigServerClient(
|
|
env: JNIEnv,
|
|
class: JClass,
|
|
) -> jint {
|
|
logger::init();
|
|
config_server_api::stop_config_server_client_jni(env, class)
|
|
}
|
|
|
|
/// Report whether the managed config-server client is connected.
|
|
///
|
|
/// Java signature:
|
|
/// `EasyTierJNI.isConfigServerClientConnected(): Boolean`
|
|
///
|
|
/// Returns `JNI_TRUE` only when the FFI config-server client exists and reports
|
|
/// connected.
|
|
#[unsafe(no_mangle)]
|
|
pub extern "system" fn Java_com_easytier_jni_EasyTierJNI_isConfigServerClientConnected(
|
|
env: JNIEnv,
|
|
class: JClass,
|
|
) -> jboolean {
|
|
logger::init();
|
|
config_server_api::is_config_server_client_connected_jni(env, class)
|
|
}
|