socks_hub/
api.rs

1use crate::Config;
2use std::{net::SocketAddr, os::raw::c_int, sync::LazyLock, sync::Mutex};
3
4static TUN_QUIT: LazyLock<Mutex<Option<tokio_util::sync::CancellationToken>>> = LazyLock::new(|| Mutex::new(None));
5
6pub(crate) fn api_internal_run<F>(config: Config, callback: Option<F>) -> c_int
7where
8    F: FnOnce(SocketAddr) + Send + Sync + 'static,
9{
10    if TUN_QUIT.lock().unwrap().is_some() {
11        log::error!("socks-hub already started");
12        return -1;
13    }
14
15    let block = async move {
16        log::info!("config: {}", serde_json::to_string_pretty(&config)?);
17
18        let cancel_token = tokio_util::sync::CancellationToken::new();
19
20        TUN_QUIT.lock().unwrap().replace(cancel_token.clone());
21
22        crate::main_entry(&config, cancel_token, callback).await?;
23        Ok::<_, crate::BoxError>(())
24    };
25
26    match tokio::runtime::Builder::new_multi_thread().enable_all().build() {
27        Err(_err) => {
28            log::error!("failed to create tokio runtime with error: {_err:?}");
29            -1
30        }
31        Ok(rt) => match rt.block_on(block) {
32            Ok(_) => 0,
33            Err(_err) => {
34                log::error!("failed to run socks-hub with error: {_err:?}");
35                -2
36            }
37        },
38    }
39}
40
41pub(crate) fn api_internal_stop() -> c_int {
42    match TUN_QUIT.lock().unwrap().take() {
43        None => {
44            log::error!("socks-hub not started");
45            -1
46        }
47        Some(tun_quit) => {
48            tun_quit.cancel();
49            0
50        }
51    }
52}