#![cfg(not(target_os = "android"))]
use crate::{ArgVerbosity, Config};
use std::{
net::SocketAddr,
os::raw::{c_char, c_int, c_void},
};
#[derive(Clone)]
pub struct CCallback(pub Option<unsafe extern "C" fn(c_int, *mut c_void)>, pub *mut c_void);
impl CCallback {
pub unsafe fn call(self, arg: c_int) {
if let Some(cb) = self.0 {
unsafe { cb(arg, self.1) };
}
}
}
unsafe impl Send for CCallback {}
unsafe impl Sync for CCallback {}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn socks_hub_run(
listen_proxy_role: *const c_char,
remote_server: *const c_char,
verbosity: ArgVerbosity,
callback: Option<unsafe extern "C" fn(c_int, *mut c_void)>,
ctx: *mut c_void,
) -> c_int {
log::set_max_level(verbosity.into());
if let Err(err) = log::set_boxed_logger(Box::<crate::dump_logger::DumpLogger>::default()) {
log::warn!("Failed to set logger: {err}");
}
let listen_proxy_role = unsafe { std::ffi::CStr::from_ptr(listen_proxy_role) }.to_str().unwrap();
let remote_server = unsafe { std::ffi::CStr::from_ptr(remote_server) }.to_str().unwrap();
let ccb = CCallback(callback, ctx);
let cb = |addr: SocketAddr| {
log::info!("Listening on {addr}");
let port = addr.port() as c_int;
unsafe {
ccb.call(port);
}
};
let mut config = Config::default();
config
.listen_proxy_role(listen_proxy_role)
.verbosity(verbosity)
.remote_server(remote_server);
crate::api::api_internal_run(config, Some(cb))
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn socks_hub_stop() -> c_int {
crate::api::api_internal_stop()
}