unsafe_in_unsafe issues

This commit is contained in:
ssrlive 2025-02-27 13:53:39 +08:00
parent 9a018f2393
commit fd7dca9988
16 changed files with 37 additions and 36 deletions

View file

@ -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: |

View file

@ -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"]

View file

@ -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()
} }

View file

@ -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;

View file

@ -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);

View file

@ -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};

View file

@ -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) };
} }
} }
} }

View file

@ -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()
} }

View file

@ -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,

View file

@ -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")]

View file

@ -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::{

View file

@ -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;

View file

@ -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) };
} }
} }
} }

View file

@ -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>();

View file

@ -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,

View file

@ -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()) };