Browse Source

Update Android JNI wrapper to parse CLI args with clap try_parse_from; remove legacy C export wrappers from general_api/cbindgen

pull/250/head
ssrlive 1 month ago
parent
commit
b2c3659f7f
  1. 2
      cbindgen.toml
  2. 52
      src/android.rs
  3. 75
      src/general_api.rs

2
cbindgen.toml

@ -4,8 +4,6 @@ cpp_compat = true
[export]
include = [
"tun2proxy_run_with_cli",
"tun2proxy_with_fd_run",
"tun2proxy_with_name_run",
"tun2proxy_stop",
"tun2proxy_set_log_callback",
"tun2proxy_set_traffic_status_callback",

52
src/android.rs

@ -2,56 +2,56 @@
use crate::{
Args,
args::ArgProxy,
error::{Error, Result},
};
use jni::{
Env, EnvUnowned,
objects::{JClass, JString},
sys::{jboolean, jchar, jint},
sys::{jchar, jint},
};
/// # Safety
///
/// Running tun2proxy with some arguments
/// Parameters:
/// - proxy_url: the proxy url, e.g. "socks5://127.0.0.1:1080"
/// - tun_fd: the tun file descriptor, it will be owned by tun2proxy
/// - close_fd_on_drop: whether close the tun_fd on drop
/// - tun_mtu: the tun mtu
/// - dns_strategy: the dns strategy, see ArgDns enum
/// - verbosity: the verbosity level, see ArgVerbosity enum
/// - cli_args: The command line arguments,
/// e.g. `tun2proxy-bin --tun-fd 43 --close-fd-on-drop false --proxy socks5://127.0.0.1:1080 --dns over-tcp --verbosity trace`
/// - tun_mtu: The MTU of the TUN device, e.g. 1500
#[unsafe(no_mangle)]
pub unsafe extern "C" fn Java_com_github_shadowsocks_bg_Tun2proxy_run(
mut env: EnvUnowned<'_>,
_clazz: JClass<'_>,
proxy_url: JString<'_>,
tun_fd: jint,
close_fd_on_drop: jboolean,
cli_args: JString<'_>,
tun_mtu: jchar,
verbosity: jint,
dns_strategy: jint,
) -> jint {
let dns = dns_strategy.try_into().unwrap();
let verbosity = verbosity.try_into().unwrap();
let filter_str = &format!("off,tun2proxy={verbosity}");
let filter = android_logger::FilterBuilder::new().parse(filter_str).build();
env.with_env(|env: &mut Env| -> Result<jint> {
let cli_args = get_java_string(env, &cli_args)?;
let tokens = shlex::split(&cli_args).ok_or_else(|| Error::from("Failed to split CLI args"))?;
let tokens_clone = tokens.clone();
let args = <Args as ::clap::Parser>::try_parse_from(tokens).map_err(|err| Error::from(format!("Parse CLI args: {err}")))?;
let filter_str = format!("off,tun2proxy={}", args.verbosity);
let filter = android_logger::FilterBuilder::new().parse(&filter_str).build();
android_logger::init_once(
android_logger::Config::default()
.with_tag("tun2proxy")
.with_max_level(log::LevelFilter::Trace)
.with_filter(filter),
);
env.with_env(|env: &mut Env| -> Result<jint> {
let proxy_url = get_java_string(env, &proxy_url).unwrap();
let proxy = ArgProxy::try_from(proxy_url.as_str()).unwrap();
let mut args = Args::default();
args.proxy(proxy)
.tun_fd(Some(tun_fd))
.close_fd_on_drop(close_fd_on_drop)
.dns(dns)
.verbosity(verbosity);
if !tokens_clone
.iter()
.any(|token| token == "--dns" || token.starts_with("--dns=") || token == "-d" || token.starts_with("-d"))
{
log::error!("--dns is required for Android");
return Err(Error::from("--dns is required for Android"));
}
if args.tun_fd.is_none() {
log::error!("tun_fd is required for Android");
return Err(Error::from("tun_fd is required for Android"));
}
let v = crate::general_api::general_run_for_api(args, tun_mtu, false);
Ok::<jint, Error>(v)
})

75
src/general_api.rs

@ -1,79 +1,6 @@
use crate::{
ArgVerbosity, Args,
args::{ArgDns, ArgProxy},
};
use crate::Args;
use std::os::raw::{c_char, c_int, c_ushort};
/// # Safety
///
/// Run the tun2proxy component with some arguments.
/// Parameters:
/// - proxy_url: the proxy url, e.g. "socks5://127.0.0.1:1080"
/// - tun: the tun device name, e.g. "utun5"
/// - bypass: the bypass IP/CIDR, e.g. "123.45.67.0/24"
/// - dns_strategy: the dns strategy, see ArgDns enum
/// - root_privilege: whether to run with root privilege
/// - verbosity: the verbosity level, see ArgVerbosity enum
#[unsafe(no_mangle)]
pub unsafe extern "C" fn tun2proxy_with_name_run(
proxy_url: *const c_char,
tun: *const c_char,
bypass: *const c_char,
dns_strategy: ArgDns,
_root_privilege: bool,
verbosity: ArgVerbosity,
) -> c_int {
let proxy_url = unsafe { std::ffi::CStr::from_ptr(proxy_url) }.to_str().unwrap();
let proxy = ArgProxy::try_from(proxy_url).unwrap();
let tun = unsafe { std::ffi::CStr::from_ptr(tun) }.to_str().unwrap().to_string();
let mut args = Args::default();
if let Ok(bypass) = unsafe { std::ffi::CStr::from_ptr(bypass) }.to_str() {
args.bypass(bypass.parse().unwrap());
}
args.proxy(proxy).tun(tun).dns(dns_strategy).verbosity(verbosity);
#[cfg(target_os = "linux")]
args.setup(_root_privilege);
general_run_for_api(args, tun::DEFAULT_MTU, false)
}
/// # Safety
///
/// Run the tun2proxy component with some arguments.
/// Parameters:
/// - proxy_url: the proxy url, e.g. "socks5://127.0.0.1:1080"
/// - tun_fd: the tun file descriptor, it will be owned by tun2proxy
/// - close_fd_on_drop: whether close the tun_fd on drop
/// - packet_information: indicates whether exists packet information in packet from TUN device
/// - tun_mtu: the tun mtu
/// - dns_strategy: the dns strategy, see ArgDns enum
/// - verbosity: the verbosity level, see ArgVerbosity enum
#[cfg(unix)]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn tun2proxy_with_fd_run(
proxy_url: *const c_char,
tun_fd: c_int,
close_fd_on_drop: bool,
packet_information: bool,
tun_mtu: c_ushort,
dns_strategy: ArgDns,
verbosity: ArgVerbosity,
) -> c_int {
let proxy_url = unsafe { std::ffi::CStr::from_ptr(proxy_url) }.to_str().unwrap();
let proxy = ArgProxy::try_from(proxy_url).unwrap();
let mut args = Args::default();
args.proxy(proxy)
.tun_fd(Some(tun_fd))
.close_fd_on_drop(close_fd_on_drop)
.dns(dns_strategy)
.verbosity(verbosity);
general_run_for_api(args, tun_mtu, packet_information)
}
/// # Safety
/// Run the tun2proxy component with command line arguments
/// Parameters:

Loading…
Cancel
Save