mirror of
https://github.com/tun2proxy/tun2proxy.git
synced 2025-04-22 14:59:09 +00:00
refactor FFI
This commit is contained in:
parent
8067394003
commit
8a67915388
9 changed files with 84 additions and 31 deletions
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "tun2proxy"
|
name = "tun2proxy"
|
||||||
version = "0.2.3"
|
version = "0.2.4"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ ipstack = { version = "0.0", features = ["log"] }
|
||||||
log = { version = "0.4", features = ["std"] }
|
log = { version = "0.4", features = ["std"] }
|
||||||
socks5-impl = { version = "0.5" }
|
socks5-impl = { version = "0.5" }
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
tokio = { version = "1.35", features = ["full"] }
|
tokio = { version = "1.36", features = ["full"] }
|
||||||
tproxy-config = { version = "0.1", features = ["log"] }
|
tproxy-config = { version = "0.1", features = ["log"] }
|
||||||
trust-dns-proto = "0.23"
|
trust-dns-proto = "0.23"
|
||||||
tun2 = { version = "1.0", features = ["async"] }
|
tun2 = { version = "1.0", features = ["async"] }
|
||||||
|
|
|
@ -17,5 +17,5 @@ cd tun2proxy
|
||||||
cargo build --release --target aarch64-apple-ios
|
cargo build --release --target aarch64-apple-ios
|
||||||
cargo build --release --target x86_64-apple-ios
|
cargo build --release --target x86_64-apple-ios
|
||||||
lipo -create target/aarch64-apple-ios/release/libtun2proxy.a target/x86_64-apple-ios/release/libtun2proxy.a -output target/libtun2proxy.a
|
lipo -create target/aarch64-apple-ios/release/libtun2proxy.a target/x86_64-apple-ios/release/libtun2proxy.a -output target/libtun2proxy.a
|
||||||
cbindgen --config cbindgen.toml -l C -o target/tun2proxy-sys.h
|
cbindgen --config cbindgen.toml -l C -o target/tun2proxy-ffi.h
|
||||||
```
|
```
|
||||||
|
|
|
@ -161,7 +161,7 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/bash;
|
shellPath = /bin/bash;
|
||||||
shellScript = "set -e\nPATH=\"$PATH:${HOME}/.cargo/bin\"\nRUST_PROJ=${PROJECT_DIR}/..\ncd \"${RUST_PROJ}\"\ncargo build --release --target aarch64-apple-ios\ncargo build --release --target x86_64-apple-ios\nlipo -create target/aarch64-apple-ios/release/libtun2proxy.a target/x86_64-apple-ios/release/libtun2proxy.a -output target/libtun2proxy.a\ncbindgen --config cbindgen.toml -l C -o target/tun2proxy-sys.h\n";
|
shellScript = "set -e\nPATH=\"$PATH:${HOME}/.cargo/bin\"\nRUST_PROJ=${PROJECT_DIR}/..\ncd \"${RUST_PROJ}\"\ncargo build --release --target aarch64-apple-ios\ncargo build --release --target x86_64-apple-ios\nlipo -create target/aarch64-apple-ios/release/libtun2proxy.a target/x86_64-apple-ios/release/libtun2proxy.a -output target/libtun2proxy.a\ncbindgen --config cbindgen.toml -l C -o target/tun2proxy-ffi.h\n";
|
||||||
};
|
};
|
||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
|
|
|
@ -8,16 +8,16 @@
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
#import "Tun2proxyWrapper.h"
|
#import "Tun2proxyWrapper.h"
|
||||||
#include "tun2proxy-sys.h"
|
#include "tun2proxy-ffi.h"
|
||||||
|
|
||||||
@implementation Tun2proxyWrapper
|
@implementation Tun2proxyWrapper
|
||||||
|
|
||||||
+ (void)startWithConfig:(NSString *)proxy_url
|
+ (void)startWithConfig:(NSString *)proxy_url
|
||||||
tun_fd:(int)tun_fd
|
tun_fd:(int)tun_fd
|
||||||
tun_mtu:(uint32_t)tun_mtu
|
tun_mtu:(uint32_t)tun_mtu
|
||||||
dns_over_tcp:(bool)dns_over_tcp
|
dns_strategy:(ArgDns)dns_strategy
|
||||||
verbose:(bool)verbose {
|
verbosity:(ArgVerbosity)verbosity {
|
||||||
tun2proxy_run(proxy_url.UTF8String, tun_fd, tun_mtu, dns_over_tcp, verbose);
|
tun2proxy_run(proxy_url.UTF8String, tun_fd, tun_mtu, dns_strategy, verbosity);
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)shutdown {
|
+ (void)shutdown {
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
#![cfg(target_os = "android")]
|
#![cfg(target_os = "android")]
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
args::{ArgDns, ArgProxy},
|
args::ArgProxy,
|
||||||
error::{Error, Result},
|
error::{Error, Result},
|
||||||
ArgVerbosity, Args,
|
Args,
|
||||||
};
|
};
|
||||||
use jni::{
|
use jni::{
|
||||||
objects::{JClass, JString},
|
objects::{JClass, JString},
|
||||||
sys::{jboolean, jint},
|
sys::jint,
|
||||||
JNIEnv,
|
JNIEnv,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,11 +21,11 @@ pub unsafe extern "C" fn Java_com_github_shadowsocks_bg_Tun2proxy_run(
|
||||||
proxy_url: JString,
|
proxy_url: JString,
|
||||||
tun_fd: jint,
|
tun_fd: jint,
|
||||||
tun_mtu: jint,
|
tun_mtu: jint,
|
||||||
verbose: jboolean,
|
verbosity: jint,
|
||||||
dns_over_tcp: jboolean,
|
dns_strategy: jint,
|
||||||
) -> jint {
|
) -> jint {
|
||||||
let dns = if dns_over_tcp != 0 { ArgDns::OverTcp } else { ArgDns::Direct };
|
let dns = dns_strategy.try_into().unwrap();
|
||||||
let verbosity = if verbose != 0 { ArgVerbosity::Trace } else { ArgVerbosity::Info };
|
let verbosity = verbosity.try_into().unwrap();
|
||||||
let filter_str = &format!("off,tun2proxy={verbosity}");
|
let filter_str = &format!("off,tun2proxy={verbosity}");
|
||||||
let filter = android_logger::FilterBuilder::new().parse(filter_str).build();
|
let filter = android_logger::FilterBuilder::new().parse(filter_str).build();
|
||||||
android_logger::init_once(
|
android_logger::init_once(
|
||||||
|
|
60
src/args.rs
60
src/args.rs
|
@ -81,9 +81,10 @@ impl Args {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, clap::ValueEnum)]
|
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, clap::ValueEnum)]
|
||||||
pub enum ArgVerbosity {
|
pub enum ArgVerbosity {
|
||||||
Off,
|
Off = 0,
|
||||||
Error,
|
Error,
|
||||||
Warn,
|
Warn,
|
||||||
#[default]
|
#[default]
|
||||||
|
@ -92,6 +93,47 @@ pub enum ArgVerbosity {
|
||||||
Trace,
|
Trace,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
impl TryFrom<jni::sys::jint> for ArgVerbosity {
|
||||||
|
type Error = Error;
|
||||||
|
fn try_from(value: jni::sys::jint) -> Result<Self> {
|
||||||
|
match value {
|
||||||
|
0 => Ok(ArgVerbosity::Off),
|
||||||
|
1 => Ok(ArgVerbosity::Error),
|
||||||
|
2 => Ok(ArgVerbosity::Warn),
|
||||||
|
3 => Ok(ArgVerbosity::Info),
|
||||||
|
4 => Ok(ArgVerbosity::Debug),
|
||||||
|
5 => Ok(ArgVerbosity::Trace),
|
||||||
|
_ => Err(Error::from("Invalid verbosity level")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ArgVerbosity> for log::LevelFilter {
|
||||||
|
fn from(verbosity: ArgVerbosity) -> Self {
|
||||||
|
match verbosity {
|
||||||
|
ArgVerbosity::Off => log::LevelFilter::Off,
|
||||||
|
ArgVerbosity::Error => log::LevelFilter::Error,
|
||||||
|
ArgVerbosity::Warn => log::LevelFilter::Warn,
|
||||||
|
ArgVerbosity::Info => log::LevelFilter::Info,
|
||||||
|
ArgVerbosity::Debug => log::LevelFilter::Debug,
|
||||||
|
ArgVerbosity::Trace => log::LevelFilter::Trace,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<log::Level> for ArgVerbosity {
|
||||||
|
fn from(level: log::Level) -> Self {
|
||||||
|
match level {
|
||||||
|
log::Level::Error => ArgVerbosity::Error,
|
||||||
|
log::Level::Warn => ArgVerbosity::Warn,
|
||||||
|
log::Level::Info => ArgVerbosity::Info,
|
||||||
|
log::Level::Debug => ArgVerbosity::Debug,
|
||||||
|
log::Level::Trace => ArgVerbosity::Trace,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for ArgVerbosity {
|
impl std::fmt::Display for ArgVerbosity {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
@ -109,14 +151,28 @@ impl std::fmt::Display for ArgVerbosity {
|
||||||
/// - Virtual: Use a virtual DNS server to handle DNS queries, also known as Fake-IP mode
|
/// - Virtual: Use a virtual DNS server to handle DNS queries, also known as Fake-IP mode
|
||||||
/// - OverTcp: Use TCP to send DNS queries to the DNS server
|
/// - OverTcp: Use TCP to send DNS queries to the DNS server
|
||||||
/// - Direct: Do not handle DNS by relying on DNS server bypassing
|
/// - Direct: Do not handle DNS by relying on DNS server bypassing
|
||||||
|
#[repr(C)]
|
||||||
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, clap::ValueEnum)]
|
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, clap::ValueEnum)]
|
||||||
pub enum ArgDns {
|
pub enum ArgDns {
|
||||||
Virtual,
|
Virtual = 0,
|
||||||
OverTcp,
|
OverTcp,
|
||||||
#[default]
|
#[default]
|
||||||
Direct,
|
Direct,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
impl TryFrom<jni::sys::jint> for ArgDns {
|
||||||
|
type Error = Error;
|
||||||
|
fn try_from(value: jni::sys::jint) -> Result<Self> {
|
||||||
|
match value {
|
||||||
|
0 => Ok(ArgDns::Virtual),
|
||||||
|
1 => Ok(ArgDns::OverTcp),
|
||||||
|
2 => Ok(ArgDns::Direct),
|
||||||
|
_ => Err(Error::from("Invalid DNS strategy")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ArgProxy {
|
pub struct ArgProxy {
|
||||||
pub proxy_type: ProxyType,
|
pub proxy_type: ProxyType,
|
||||||
|
|
|
@ -62,7 +62,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
tproxy_config::tproxy_setup(&tproxy_args)?;
|
tproxy_config::tproxy_setup(&tproxy_args)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let tun2proxy = Builder::new(device, args).mtu(MTU).build();
|
let tun2proxy = Builder::new(device, args).mtu(MTU as _).build();
|
||||||
let (join_handle, quit) = tun2proxy.start();
|
let (join_handle, quit) = tun2proxy.start();
|
||||||
|
|
||||||
ctrlc2::set_async_handler(async move {
|
ctrlc2::set_async_handler(async move {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
use crate::ArgVerbosity;
|
||||||
use std::{
|
use std::{
|
||||||
os::raw::{c_char, c_int, c_void},
|
os::raw::{c_char, c_void},
|
||||||
sync::Mutex,
|
sync::Mutex,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,17 +11,17 @@ pub(crate) static DUMP_CALLBACK: Mutex<Option<DumpCallback>> = Mutex::new(None);
|
||||||
/// set dump log info callback.
|
/// set dump log info callback.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn tun2proxy_set_log_callback(
|
pub unsafe extern "C" fn tun2proxy_set_log_callback(
|
||||||
callback: Option<unsafe extern "C" fn(c_int, *const c_char, *mut c_void)>,
|
callback: Option<unsafe extern "C" fn(ArgVerbosity, *const c_char, *mut c_void)>,
|
||||||
ctx: *mut c_void,
|
ctx: *mut c_void,
|
||||||
) {
|
) {
|
||||||
*DUMP_CALLBACK.lock().unwrap() = Some(DumpCallback(callback, ctx));
|
*DUMP_CALLBACK.lock().unwrap() = Some(DumpCallback(callback, ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct DumpCallback(Option<unsafe extern "C" fn(c_int, *const c_char, *mut c_void)>, *mut c_void);
|
pub struct DumpCallback(Option<unsafe extern "C" fn(ArgVerbosity, *const c_char, *mut c_void)>, *mut c_void);
|
||||||
|
|
||||||
impl DumpCallback {
|
impl DumpCallback {
|
||||||
unsafe fn call(self, dump_level: c_int, info: *const c_char) {
|
unsafe fn call(self, dump_level: ArgVerbosity, info: *const c_char) {
|
||||||
if let Some(cb) = self.0 {
|
if let Some(cb) = self.0 {
|
||||||
cb(dump_level, info, self.1);
|
cb(dump_level, info, self.1);
|
||||||
}
|
}
|
||||||
|
@ -64,7 +65,7 @@ impl DumpLogger {
|
||||||
let ptr = c_msg.as_ptr();
|
let ptr = c_msg.as_ptr();
|
||||||
if let Some(cb) = DUMP_CALLBACK.lock().unwrap().clone() {
|
if let Some(cb) = DUMP_CALLBACK.lock().unwrap().clone() {
|
||||||
unsafe {
|
unsafe {
|
||||||
cb.call(record.level() as c_int, ptr);
|
cb.call(record.level().into(), ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
12
src/ios.rs
12
src/ios.rs
|
@ -14,20 +14,16 @@ pub unsafe extern "C" fn tun2proxy_run(
|
||||||
proxy_url: *const c_char,
|
proxy_url: *const c_char,
|
||||||
tun_fd: c_int,
|
tun_fd: c_int,
|
||||||
tun_mtu: c_uint,
|
tun_mtu: c_uint,
|
||||||
dns_over_tcp: c_char,
|
dns_strategy: ArgDns,
|
||||||
verbose: c_char,
|
verbosity: ArgVerbosity,
|
||||||
) -> c_int {
|
) -> c_int {
|
||||||
use log::LevelFilter;
|
log::set_max_level(verbosity.into());
|
||||||
let log_level = if verbose != 0 { LevelFilter::Trace } else { LevelFilter::Info };
|
|
||||||
log::set_max_level(log_level);
|
|
||||||
log::set_boxed_logger(Box::<crate::dump_logger::DumpLogger>::default()).unwrap();
|
log::set_boxed_logger(Box::<crate::dump_logger::DumpLogger>::default()).unwrap();
|
||||||
|
|
||||||
let dns = if dns_over_tcp != 0 { ArgDns::OverTcp } else { ArgDns::Direct };
|
|
||||||
let verbosity = if verbose != 0 { ArgVerbosity::Trace } else { ArgVerbosity::Info };
|
|
||||||
let proxy_url = std::ffi::CStr::from_ptr(proxy_url).to_str().unwrap();
|
let proxy_url = std::ffi::CStr::from_ptr(proxy_url).to_str().unwrap();
|
||||||
let proxy = ArgProxy::from_url(proxy_url).unwrap();
|
let proxy = ArgProxy::from_url(proxy_url).unwrap();
|
||||||
|
|
||||||
let args = Args::new(Some(tun_fd), proxy, dns, verbosity);
|
let args = Args::new(Some(tun_fd), proxy, dns_strategy, verbosity);
|
||||||
|
|
||||||
crate::api::tun2proxy_internal_run(args, tun_mtu as _)
|
crate::api::tun2proxy_internal_run(args, tun_mtu as _)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue