diff --git a/src/api.rs b/src/api.rs index 1ea0d8d..bf035ac 100644 --- a/src/api.rs +++ b/src/api.rs @@ -36,8 +36,9 @@ pub unsafe extern "C" fn over_tls_client_run( ctx: *mut c_void, ) -> c_int { log::set_max_level(verbosity.into()); - log::set_boxed_logger(Box::::default()).unwrap(); - + if let Err(err) = log::set_boxed_logger(Box::::default()) { + log::info!("failed to set logger, error={:?}", err); + } _over_tls_client_run(config_path, callback, ctx) } @@ -61,12 +62,8 @@ unsafe fn _over_tls_client_run( let block = || -> Result<()> { let config_path = std::ffi::CStr::from_ptr(config_path).to_str()?; - let cb = |addr: SocketAddr| { - log::trace!("Listening on {}", addr); - let port = addr.port(); - unsafe { - ccb.call(port as c_int); - } + let cb = |addr: SocketAddr| unsafe { + ccb.call(addr.port() as _); }; let mut config = crate::config::Config::from_config_file(config_path)?; diff --git a/src/bin/overtls.rs b/src/bin/overtls.rs index 172d77d..571ec75 100644 --- a/src/bin/overtls.rs +++ b/src/bin/overtls.rs @@ -3,6 +3,37 @@ use overtls::{client, config, server, CmdOpt, Error, Result}; fn main() -> Result<()> { let opt = CmdOpt::parse_cmd(); + if opt.c_api { + if opt.is_server() { + return Err(Error::from("C API is not supported for server")); + } + + // Test the C API usage + let config_path_str = opt.config.as_path().to_string_lossy().into_owned(); + let c_string = std::ffi::CString::new(config_path_str).unwrap(); + let config_path: *const std::os::raw::c_char = c_string.as_ptr(); + + let join = ctrlc2::set_handler(|| { + log::info!("Ctrl-C received, exiting..."); + unsafe { overtls::over_tls_client_stop() }; + true + }) + .expect("Error setting Ctrl-C handler"); + + unsafe extern "C" fn log_cb(_: overtls::ArgVerbosity, msg: *const std::os::raw::c_char, _ctx: *mut std::os::raw::c_void) { + println!("{:?}", unsafe { std::ffi::CStr::from_ptr(msg).to_str() }); + } + unsafe { overtls::overtls_set_log_callback(Some(log_cb), std::ptr::null_mut()) }; + + unsafe extern "C" fn port_cb(port: i32, _ctx: *mut std::os::raw::c_void) { + log::info!("Listening on {}", port); + } + unsafe { overtls::over_tls_client_run(config_path, opt.verbosity, Some(port_cb), std::ptr::null_mut()) }; + + join.join().unwrap(); + return Ok(()); + } + dotenvy::dotenv().ok(); let level = format!("{}={:?}", module_path!(), opt.verbosity); diff --git a/src/cmdopt.rs b/src/cmdopt.rs index 65f6b67..6c15944 100644 --- a/src/cmdopt.rs +++ b/src/cmdopt.rs @@ -100,6 +100,10 @@ pub struct CmdOpt { /// Generate QR code for client. #[arg(short, long)] pub qrcode: bool, + + /// Use C API for client. + #[arg(long)] + pub c_api: bool, } impl CmdOpt { diff --git a/src/dump_logger.rs b/src/dump_logger.rs index ec1500c..2f6a800 100644 --- a/src/dump_logger.rs +++ b/src/dump_logger.rs @@ -5,7 +5,7 @@ use std::{ }; lazy_static::lazy_static! { - pub static ref DUMP_CALLBACK: Mutex> = Mutex::new(None); + static ref DUMP_CALLBACK: Mutex> = Mutex::new(None); } /// # Safety @@ -20,7 +20,7 @@ pub unsafe extern "C" fn overtls_set_log_callback( } #[derive(Clone)] -pub struct DumpCallback(Option, *mut c_void); +struct DumpCallback(Option, *mut c_void); impl DumpCallback { unsafe fn call(self, dump_level: ArgVerbosity, info: *const c_char) { @@ -34,7 +34,7 @@ unsafe impl Send for DumpCallback {} unsafe impl Sync for DumpCallback {} #[derive(Debug, Clone, PartialEq, Eq, Default)] -pub struct DumpLogger {} +pub(crate) struct DumpLogger; impl log::Log for DumpLogger { fn enabled(&self, metadata: &log::Metadata) -> bool { diff --git a/src/lib.rs b/src/lib.rs index 31dab80..ecc8076 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,9 +15,11 @@ pub(crate) mod udprelay; pub(crate) mod webapi; pub(crate) mod weirduri; +pub use api::{over_tls_client_run, over_tls_client_stop}; use base64_wrapper::{base64_decode, base64_encode, Base64Engine}; use bytes::BytesMut; pub use cmdopt::{ArgVerbosity, CmdOpt, Role}; +pub use dump_logger::overtls_set_log_callback; pub use error::{Error, Result}; use socks5_impl::protocol::{Address, StreamOperation}; pub use tokio_util::sync::CancellationToken;