mirror of
https://github.com/tun2proxy/tun2proxy.git
synced 2025-04-21 22:39:08 +00:00
unsafe_in_unsafe issues
This commit is contained in:
parent
9a018f2393
commit
fd7dca9988
16 changed files with 37 additions and 36 deletions
1
.github/workflows/rust.yml
vendored
1
.github/workflows/rust.yml
vendored
|
@ -77,6 +77,7 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
- name: Install cargo lipo and rust compiler for ios target
|
- name: Install cargo lipo and rust compiler for ios target
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
[package]
|
[package]
|
||||||
name = "tun2proxy"
|
name = "tun2proxy"
|
||||||
version = "0.7.4"
|
version = "0.7.4"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/tun2proxy/tun2proxy"
|
repository = "https://github.com/tun2proxy/tun2proxy"
|
||||||
homepage = "https://github.com/tun2proxy/tun2proxy"
|
homepage = "https://github.com/tun2proxy/tun2proxy"
|
||||||
authors = ["B. Blechschmidt", "ssrlive"]
|
authors = ["B. Blechschmidt", "ssrlive"]
|
||||||
description = "Tunnel interface to proxy"
|
description = "Tunnel interface to proxy"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
rust-version = "1.80"
|
rust-version = "1.85"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["staticlib", "cdylib", "lib"]
|
crate-type = ["staticlib", "cdylib", "lib"]
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
#![cfg(target_os = "android")]
|
#![cfg(target_os = "android")]
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
Args,
|
||||||
args::ArgProxy,
|
args::ArgProxy,
|
||||||
error::{Error, Result},
|
error::{Error, Result},
|
||||||
Args,
|
|
||||||
};
|
};
|
||||||
use jni::{
|
use jni::{
|
||||||
|
JNIEnv,
|
||||||
objects::{JClass, JString},
|
objects::{JClass, JString},
|
||||||
sys::{jboolean, jchar, jint},
|
sys::{jboolean, jchar, jint},
|
||||||
JNIEnv,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// # Safety
|
/// # Safety
|
||||||
|
@ -21,7 +21,7 @@ use jni::{
|
||||||
/// - tun_mtu: the tun mtu
|
/// - tun_mtu: the tun mtu
|
||||||
/// - dns_strategy: the dns strategy, see ArgDns enum
|
/// - dns_strategy: the dns strategy, see ArgDns enum
|
||||||
/// - verbosity: the verbosity level, see ArgVerbosity enum
|
/// - verbosity: the verbosity level, see ArgVerbosity enum
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn Java_com_github_shadowsocks_bg_Tun2proxy_run(
|
pub unsafe extern "C" fn Java_com_github_shadowsocks_bg_Tun2proxy_run(
|
||||||
mut env: JNIEnv,
|
mut env: JNIEnv,
|
||||||
_clazz: JClass,
|
_clazz: JClass,
|
||||||
|
@ -58,7 +58,7 @@ pub unsafe extern "C" fn Java_com_github_shadowsocks_bg_Tun2proxy_run(
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// Shutdown tun2proxy
|
/// Shutdown tun2proxy
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn Java_com_github_shadowsocks_bg_Tun2proxy_stop(_env: JNIEnv, _: JClass) -> jint {
|
pub unsafe extern "C" fn Java_com_github_shadowsocks_bg_Tun2proxy_stop(_env: JNIEnv, _: JClass) -> jint {
|
||||||
crate::general_api::tun2proxy_stop_internal()
|
crate::general_api::tun2proxy_stop_internal()
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ async fn main_async(args: Args) -> Result<(), BoxError> {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn traffic_cb(status: *const tun2proxy::TrafficStatus, _: *mut std::ffi::c_void) {
|
unsafe extern "C" fn traffic_cb(status: *const tun2proxy::TrafficStatus, _: *mut std::ffi::c_void) {
|
||||||
let status = &*status;
|
let status = unsafe { &*status };
|
||||||
log::debug!("Traffic: ▲ {} : ▼ {}", status.tx, status.rx);
|
log::debug!("Traffic: ▲ {} : ▼ {}", status.tx, status.rx);
|
||||||
}
|
}
|
||||||
unsafe { tun2proxy::tun2proxy_set_traffic_status_callback(1, Some(traffic_cb), std::ptr::null_mut()) };
|
unsafe { tun2proxy::tun2proxy_set_traffic_status_callback(1, Some(traffic_cb), std::ptr::null_mut()) };
|
||||||
|
@ -79,7 +79,7 @@ async fn namespace_proxy_main(
|
||||||
_args: Args,
|
_args: Args,
|
||||||
_shutdown_token: tokio_util::sync::CancellationToken,
|
_shutdown_token: tokio_util::sync::CancellationToken,
|
||||||
) -> Result<std::process::ExitStatus, tun2proxy::Error> {
|
) -> Result<std::process::ExitStatus, tun2proxy::Error> {
|
||||||
use nix::fcntl::{open, OFlag};
|
use nix::fcntl::{OFlag, open};
|
||||||
use nix::sys::stat::Mode;
|
use nix::sys::stat::Mode;
|
||||||
use std::os::fd::AsRawFd;
|
use std::os::fd::AsRawFd;
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,14 @@ use std::net::SocketAddr;
|
||||||
use tokio::{
|
use tokio::{
|
||||||
io::AsyncWriteExt,
|
io::AsyncWriteExt,
|
||||||
net::{
|
net::{
|
||||||
tcp::{ReadHalf, WriteHalf},
|
|
||||||
UdpSocket,
|
UdpSocket,
|
||||||
|
tcp::{ReadHalf, WriteHalf},
|
||||||
},
|
},
|
||||||
sync::mpsc::{Receiver, Sender},
|
sync::mpsc::{Receiver, Sender},
|
||||||
};
|
};
|
||||||
use tun2proxy::{
|
use tun2proxy::{
|
||||||
udpgw::{Packet, UdpFlag},
|
|
||||||
ArgVerbosity, BoxError, Error, Result,
|
ArgVerbosity, BoxError, Error, Result,
|
||||||
|
udpgw::{Packet, UdpFlag},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) const CLIENT_DISCONNECT_TIMEOUT: tokio::time::Duration = std::time::Duration::from_secs(60);
|
pub(crate) const CLIENT_DISCONNECT_TIMEOUT: tokio::time::Duration = std::time::Duration::from_secs(60);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use hickory_proto::{
|
use hickory_proto::{
|
||||||
op::{Message, MessageType, ResponseCode},
|
op::{Message, MessageType, ResponseCode},
|
||||||
rr::{record_type::RecordType, Name, RData, Record},
|
rr::{Name, RData, Record, record_type::RecordType},
|
||||||
};
|
};
|
||||||
use std::{net::IpAddr, str::FromStr};
|
use std::{net::IpAddr, str::FromStr};
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub(crate) static DUMP_CALLBACK: Mutex<Option<DumpCallback>> = Mutex::new(None);
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// set dump log info callback.
|
/// set dump log info callback.
|
||||||
#[no_mangle]
|
#[unsafe(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(ArgVerbosity, *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,
|
||||||
|
@ -23,7 +23,7 @@ pub struct DumpCallback(Option<unsafe extern "C" fn(ArgVerbosity, *const c_char,
|
||||||
impl DumpCallback {
|
impl DumpCallback {
|
||||||
unsafe fn call(self, dump_level: ArgVerbosity, 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);
|
unsafe { cb(dump_level, info, self.1) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
args::{ArgDns, ArgProxy},
|
|
||||||
ArgVerbosity, Args,
|
ArgVerbosity, Args,
|
||||||
|
args::{ArgDns, ArgProxy},
|
||||||
};
|
};
|
||||||
use std::os::raw::{c_char, c_int, c_ushort};
|
use std::os::raw::{c_char, c_int, c_ushort};
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ static TUN_QUIT: std::sync::Mutex<Option<tokio_util::sync::CancellationToken>> =
|
||||||
/// - dns_strategy: the dns strategy, see ArgDns enum
|
/// - dns_strategy: the dns strategy, see ArgDns enum
|
||||||
/// - root_privilege: whether to run with root privilege
|
/// - root_privilege: whether to run with root privilege
|
||||||
/// - verbosity: the verbosity level, see ArgVerbosity enum
|
/// - verbosity: the verbosity level, see ArgVerbosity enum
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn tun2proxy_with_name_run(
|
pub unsafe extern "C" fn tun2proxy_with_name_run(
|
||||||
proxy_url: *const c_char,
|
proxy_url: *const c_char,
|
||||||
tun: *const c_char,
|
tun: *const c_char,
|
||||||
|
@ -25,12 +25,12 @@ pub unsafe extern "C" fn tun2proxy_with_name_run(
|
||||||
_root_privilege: bool,
|
_root_privilege: bool,
|
||||||
verbosity: ArgVerbosity,
|
verbosity: ArgVerbosity,
|
||||||
) -> c_int {
|
) -> c_int {
|
||||||
let proxy_url = std::ffi::CStr::from_ptr(proxy_url).to_str().unwrap();
|
let proxy_url = unsafe { std::ffi::CStr::from_ptr(proxy_url) }.to_str().unwrap();
|
||||||
let proxy = ArgProxy::try_from(proxy_url).unwrap();
|
let proxy = ArgProxy::try_from(proxy_url).unwrap();
|
||||||
let tun = std::ffi::CStr::from_ptr(tun).to_str().unwrap().to_string();
|
let tun = unsafe { std::ffi::CStr::from_ptr(tun) }.to_str().unwrap().to_string();
|
||||||
|
|
||||||
let mut args = Args::default();
|
let mut args = Args::default();
|
||||||
if let Ok(bypass) = std::ffi::CStr::from_ptr(bypass).to_str() {
|
if let Ok(bypass) = unsafe { std::ffi::CStr::from_ptr(bypass) }.to_str() {
|
||||||
args.bypass(bypass.parse().unwrap());
|
args.bypass(bypass.parse().unwrap());
|
||||||
}
|
}
|
||||||
args.proxy(proxy).tun(tun).dns(dns_strategy).verbosity(verbosity);
|
args.proxy(proxy).tun(tun).dns(dns_strategy).verbosity(verbosity);
|
||||||
|
@ -53,7 +53,7 @@ pub unsafe extern "C" fn tun2proxy_with_name_run(
|
||||||
/// - dns_strategy: the dns strategy, see ArgDns enum
|
/// - dns_strategy: the dns strategy, see ArgDns enum
|
||||||
/// - verbosity: the verbosity level, see ArgVerbosity enum
|
/// - verbosity: the verbosity level, see ArgVerbosity enum
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn tun2proxy_with_fd_run(
|
pub unsafe extern "C" fn tun2proxy_with_fd_run(
|
||||||
proxy_url: *const c_char,
|
proxy_url: *const c_char,
|
||||||
tun_fd: c_int,
|
tun_fd: c_int,
|
||||||
|
@ -63,7 +63,7 @@ pub unsafe extern "C" fn tun2proxy_with_fd_run(
|
||||||
dns_strategy: ArgDns,
|
dns_strategy: ArgDns,
|
||||||
verbosity: ArgVerbosity,
|
verbosity: ArgVerbosity,
|
||||||
) -> c_int {
|
) -> c_int {
|
||||||
let proxy_url = std::ffi::CStr::from_ptr(proxy_url).to_str().unwrap();
|
let proxy_url = unsafe { std::ffi::CStr::from_ptr(proxy_url) }.to_str().unwrap();
|
||||||
let proxy = ArgProxy::try_from(proxy_url).unwrap();
|
let proxy = ArgProxy::try_from(proxy_url).unwrap();
|
||||||
|
|
||||||
let mut args = Args::default();
|
let mut args = Args::default();
|
||||||
|
@ -83,9 +83,9 @@ pub unsafe extern "C" fn tun2proxy_with_fd_run(
|
||||||
/// e.g. `tun2proxy-bin --setup --proxy socks5://127.0.0.1:1080 --bypass 98.76.54.0/24 --dns over-tcp --verbosity trace`
|
/// e.g. `tun2proxy-bin --setup --proxy socks5://127.0.0.1:1080 --bypass 98.76.54.0/24 --dns over-tcp --verbosity trace`
|
||||||
/// - tun_mtu: The MTU of the TUN device, e.g. 1500
|
/// - tun_mtu: The MTU of the TUN device, e.g. 1500
|
||||||
/// - packet_information: Whether exists packet information in packet from TUN device
|
/// - packet_information: Whether exists packet information in packet from TUN device
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn tun2proxy_run_with_cli_args(cli_args: *const c_char, tun_mtu: c_ushort, packet_information: bool) -> c_int {
|
pub unsafe extern "C" fn tun2proxy_run_with_cli_args(cli_args: *const c_char, tun_mtu: c_ushort, packet_information: bool) -> c_int {
|
||||||
let Ok(cli_args) = std::ffi::CStr::from_ptr(cli_args).to_str() else {
|
let Ok(cli_args) = unsafe { std::ffi::CStr::from_ptr(cli_args) }.to_str() else {
|
||||||
log::error!("Failed to convert CLI arguments to string");
|
log::error!("Failed to convert CLI arguments to string");
|
||||||
return -5;
|
return -5;
|
||||||
};
|
};
|
||||||
|
@ -246,7 +246,7 @@ pub async fn general_run_async(
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// Shutdown the tun2proxy component.
|
/// Shutdown the tun2proxy component.
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn tun2proxy_stop() -> c_int {
|
pub unsafe extern "C" fn tun2proxy_stop() -> c_int {
|
||||||
tun2proxy_stop_internal()
|
tun2proxy_stop_internal()
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
||||||
use httparse::Response;
|
use httparse::Response;
|
||||||
use socks5_impl::protocol::UserKey;
|
use socks5_impl::protocol::UserKey;
|
||||||
use std::{
|
use std::{
|
||||||
collections::{hash_map::RandomState, HashMap, VecDeque},
|
collections::{HashMap, VecDeque, hash_map::RandomState},
|
||||||
iter::FromIterator,
|
iter::FromIterator,
|
||||||
net::SocketAddr,
|
net::SocketAddr,
|
||||||
str,
|
str,
|
||||||
|
|
|
@ -22,18 +22,18 @@ use std::{
|
||||||
use tokio::{
|
use tokio::{
|
||||||
io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt},
|
io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt},
|
||||||
net::{TcpSocket, TcpStream, UdpSocket},
|
net::{TcpSocket, TcpStream, UdpSocket},
|
||||||
sync::{mpsc::Receiver, Mutex},
|
sync::{Mutex, mpsc::Receiver},
|
||||||
};
|
};
|
||||||
pub use tokio_util::sync::CancellationToken;
|
pub use tokio_util::sync::CancellationToken;
|
||||||
use tproxy_config::is_private_ip;
|
use tproxy_config::is_private_ip;
|
||||||
use udp_stream::UdpStream;
|
use udp_stream::UdpStream;
|
||||||
#[cfg(feature = "udpgw")]
|
#[cfg(feature = "udpgw")]
|
||||||
use udpgw::{UdpGwClientStream, UdpGwResponse, UDPGW_KEEPALIVE_TIME, UDPGW_MAX_CONNECTIONS};
|
use udpgw::{UDPGW_KEEPALIVE_TIME, UDPGW_MAX_CONNECTIONS, UdpGwClientStream, UdpGwResponse};
|
||||||
|
|
||||||
pub use {
|
pub use {
|
||||||
args::{ArgDns, ArgProxy, ArgVerbosity, Args, ProxyType},
|
args::{ArgDns, ArgProxy, ArgVerbosity, Args, ProxyType},
|
||||||
error::{BoxError, Error, Result},
|
error::{BoxError, Error, Result},
|
||||||
traffic_status::{tun2proxy_set_traffic_status_callback, TrafficStatus},
|
traffic_status::{TrafficStatus, tun2proxy_set_traffic_status_callback},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "mimalloc")]
|
#[cfg(feature = "mimalloc")]
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#![cfg(target_os = "linux")]
|
#![cfg(target_os = "linux")]
|
||||||
|
|
||||||
use crate::{error, SocketDomain, SocketProtocol};
|
use crate::{SocketDomain, SocketProtocol, error};
|
||||||
use nix::{
|
use nix::{
|
||||||
errno::Errno,
|
errno::Errno,
|
||||||
fcntl::{self, FdFlag},
|
fcntl::{self, FdFlag},
|
||||||
sys::socket::{cmsg_space, getsockopt, recvmsg, sendmsg, sockopt, ControlMessage, ControlMessageOwned, MsgFlags, SockType},
|
sys::socket::{ControlMessage, ControlMessageOwned, MsgFlags, SockType, cmsg_space, getsockopt, recvmsg, sendmsg, sockopt},
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::{
|
||||||
proxy_handler::{ProxyHandler, ProxyHandlerManager},
|
proxy_handler::{ProxyHandler, ProxyHandlerManager},
|
||||||
session_info::SessionInfo,
|
session_info::SessionInfo,
|
||||||
};
|
};
|
||||||
use socks5_impl::protocol::{self, handshake, password_method, Address, AuthMethod, StreamOperation, UserKey, Version};
|
use socks5_impl::protocol::{self, Address, AuthMethod, StreamOperation, UserKey, Version, handshake, password_method};
|
||||||
use std::{collections::VecDeque, net::SocketAddr, sync::Arc};
|
use std::{collections::VecDeque, net::SocketAddr, sync::Arc};
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::sync::{LazyLock, Mutex};
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// set traffic status callback.
|
/// set traffic status callback.
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn tun2proxy_set_traffic_status_callback(
|
pub unsafe extern "C" fn tun2proxy_set_traffic_status_callback(
|
||||||
send_interval_secs: u32,
|
send_interval_secs: u32,
|
||||||
callback: Option<unsafe extern "C" fn(*const TrafficStatus, *mut c_void)>,
|
callback: Option<unsafe extern "C" fn(*const TrafficStatus, *mut c_void)>,
|
||||||
|
@ -34,7 +34,7 @@ struct TrafficStatusCallback(Option<unsafe extern "C" fn(*const TrafficStatus, *
|
||||||
impl TrafficStatusCallback {
|
impl TrafficStatusCallback {
|
||||||
unsafe fn call(self, info: &TrafficStatus) {
|
unsafe fn call(self, info: &TrafficStatus) {
|
||||||
if let Some(cb) = self.0 {
|
if let Some(cb) = self.0 {
|
||||||
cb(info, self.1);
|
unsafe { cb(info, self.1) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,11 @@ use std::{collections::VecDeque, hash::Hash, net::SocketAddr, sync::atomic::Orde
|
||||||
use tokio::{
|
use tokio::{
|
||||||
io::{AsyncReadExt, AsyncWriteExt},
|
io::{AsyncReadExt, AsyncWriteExt},
|
||||||
net::{
|
net::{
|
||||||
tcp::{OwnedReadHalf, OwnedWriteHalf},
|
|
||||||
TcpStream,
|
TcpStream,
|
||||||
|
tcp::{OwnedReadHalf, OwnedWriteHalf},
|
||||||
},
|
},
|
||||||
sync::Mutex,
|
sync::Mutex,
|
||||||
time::{sleep, Duration},
|
time::{Duration, sleep},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) const UDPGW_LENGTH_FIELD_SIZE: usize = std::mem::size_of::<u16>();
|
pub(crate) const UDPGW_LENGTH_FIELD_SIZE: usize = std::mem::size_of::<u16>();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
use hashlink::{linked_hash_map::RawEntryMut, LruCache};
|
use hashlink::{LruCache, linked_hash_map::RawEntryMut};
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
convert::TryInto,
|
convert::TryInto,
|
||||||
|
|
|
@ -73,7 +73,7 @@ fn run_service(_arguments: Vec<std::ffi::OsString>) -> Result<(), crate::BoxErro
|
||||||
let rt = tokio::runtime::Builder::new_multi_thread().enable_all().build()?;
|
let rt = tokio::runtime::Builder::new_multi_thread().enable_all().build()?;
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
unsafe extern "C" fn traffic_cb(status: *const crate::TrafficStatus, _: *mut std::ffi::c_void) {
|
unsafe extern "C" fn traffic_cb(status: *const crate::TrafficStatus, _: *mut std::ffi::c_void) {
|
||||||
let status = &*status;
|
let status = unsafe { &*status };
|
||||||
log::debug!("Traffic: ▲ {} : ▼ {}", status.tx, status.rx);
|
log::debug!("Traffic: ▲ {} : ▼ {}", status.tx, status.rx);
|
||||||
}
|
}
|
||||||
unsafe { crate::tun2proxy_set_traffic_status_callback(1, Some(traffic_cb), std::ptr::null_mut()) };
|
unsafe { crate::tun2proxy_set_traffic_status_callback(1, Some(traffic_cb), std::ptr::null_mut()) };
|
||||||
|
|
Loading…
Add table
Reference in a new issue