|
|
|
@ -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) |
|
|
|
}) |
|
|
|
|