multi_fix: harden peer/session handling, tighten foreign-network trust, and improve web client metadata (#1999)

* machine-id should be scoped unbder same user-id
* feat: report device os metadata to console
* fix sync root key cause packet loss
* fix tun packet not invalid
* fix faketcp cause lat jitter
* fix some packet not decrypt
* fix peer info patch, improve performance of update self info
* fix foreign credential identity mismatch handling
This commit is contained in:
KKRainbow
2026-03-21 21:06:07 +08:00
committed by GitHub
parent 77966916c4
commit 2bfdd44759
24 changed files with 1381 additions and 358 deletions
+16 -2
View File
@@ -57,6 +57,17 @@ fn get_faketcp_tunnel_type_str(driver_type: &str) -> String {
format!("faketcp_{}", driver_type)
}
async fn create_tun_off_runtime(
interface_name: String,
src_addr: Option<SocketAddr>,
dst_addr: SocketAddr,
) -> Result<Arc<dyn stack::Tun>, TunnelError> {
tokio::task::spawn_blocking(move || create_tun(&interface_name, src_addr, dst_addr))
.await
.map_err(|e| TunnelError::InternalError(format!("faketcp create_tun task failed: {e}")))?
.map_err(Into::into)
}
pub struct FakeTcpTunnelListener {
addr: url::Url,
os_listener: Option<tokio::net::TcpListener>,
@@ -137,7 +148,9 @@ impl FakeTcpTunnelListener {
let ret = match self.stack_map.entry(interface_name.to_string()) {
dashmap::Entry::Occupied(entry) => entry.get().clone(),
dashmap::Entry::Vacant(entry) => {
let tun = create_tun(interface_name, None, local_socket_addr)?;
let tun =
create_tun_off_runtime(interface_name.to_string(), None, local_socket_addr)
.await?;
tracing::info!(
?local_socket_addr,
"create new stack with interface_name: {:?}",
@@ -314,7 +327,8 @@ impl crate::tunnel::TunnelConnector for FakeTcpTunnelConnector {
IpAddr::V6(ip) => (None, Some(ip)),
};
let tun = create_tun(&interface_name, Some(remote_addr), local_addr)?;
let tun =
create_tun_off_runtime(interface_name.clone(), Some(remote_addr), local_addr).await?;
let local_ip = local_ip.unwrap_or("0.0.0.0".parse().unwrap());
let mut stack = stack::Stack::new(tun, local_ip, local_ip6, mac);
let driver_type = stack.driver_type();
@@ -367,7 +367,7 @@ fn read_packet_socket_stats(fd: i32) -> io::Result<PacketSocketStats> {
}
pub struct LinuxBpfTun {
fd: OwnedFd,
fd: Arc<OwnedFd>,
ifindex: i32,
stop: Arc<AtomicBool>,
worker: Option<std::thread::JoinHandle<()>>,
@@ -395,7 +395,7 @@ impl LinuxBpfTun {
if fd < 0 {
return Err(io::Error::last_os_error());
}
let fd = unsafe { OwnedFd::from_raw_fd(fd) };
let fd = Arc::new(unsafe { OwnedFd::from_raw_fd(fd) });
let mut addr: libc::sockaddr_ll = unsafe { mem::zeroed() };
addr.sll_family = libc::AF_PACKET as u16;
@@ -404,7 +404,7 @@ impl LinuxBpfTun {
let bind_ret = unsafe {
libc::bind(
fd.as_raw_fd(),
fd.as_ref().as_raw_fd(),
&addr as *const _ as *const libc::sockaddr,
mem::size_of::<libc::sockaddr_ll>() as u32,
)
@@ -413,7 +413,7 @@ impl LinuxBpfTun {
return Err(io::Error::last_os_error());
}
let actual_rcvbuf = set_socket_rcvbuf(fd.as_raw_fd(), DEFAULT_RCVBUF_BYTES)?;
let actual_rcvbuf = set_socket_rcvbuf(fd.as_ref().as_raw_fd(), DEFAULT_RCVBUF_BYTES)?;
let filter = build_tcp_filter(src_addr, dst_addr)?;
let mut prog = libc::sock_fprog {
@@ -425,7 +425,7 @@ impl LinuxBpfTun {
};
let opt_ret = unsafe {
libc::setsockopt(
fd.as_raw_fd(),
fd.as_ref().as_raw_fd(),
libc::SOL_SOCKET,
libc::SO_ATTACH_FILTER,
&mut prog as *mut _ as *mut libc::c_void,
@@ -442,7 +442,7 @@ impl LinuxBpfTun {
};
let _ = unsafe {
libc::setsockopt(
fd.as_raw_fd(),
fd.as_ref().as_raw_fd(),
libc::SOL_SOCKET,
libc::SO_RCVTIMEO,
&timeout as *const _ as *const libc::c_void,
@@ -453,10 +453,13 @@ impl LinuxBpfTun {
let stop = Arc::new(AtomicBool::new(false));
let (tx, rx) = tokio::sync::mpsc::channel(1024);
let stop_clone = stop.clone();
let read_fd = fd.as_raw_fd();
let read_fd = fd.as_ref().as_raw_fd();
let fd_guard = fd.clone();
let interface_name_for_worker = interface_name.to_string();
let worker = std::thread::spawn(move || {
// Keep the packet socket alive until the detached worker actually exits.
let _fd_guard = fd_guard;
let mut buf = vec![0u8; 65536];
let mut stats_enabled = true;
let mut total_packets: u64 = 0;
@@ -562,9 +565,11 @@ impl LinuxBpfTun {
impl Drop for LinuxBpfTun {
fn drop(&mut self) {
self.stop.store(true, AtomicOrdering::Relaxed);
let _ = unsafe { libc::shutdown(self.fd.as_raw_fd(), libc::SHUT_RD) };
let _ = unsafe { libc::shutdown(self.fd.as_ref().as_raw_fd(), libc::SHUT_RD) };
if let Some(worker) = self.worker.take() {
let _ = worker.join();
// Dropping the JoinHandle detaches the worker. The worker holds its own Arc<OwnedFd>
// clone, so the packet socket stays valid until recv wakes up and the thread exits.
drop(worker);
}
}
}
@@ -602,7 +607,7 @@ impl stack::Tun for LinuxBpfTun {
let ret = unsafe {
libc::sendto(
self.fd.as_raw_fd(),
self.fd.as_ref().as_raw_fd(),
packet.as_ptr() as *const libc::c_void,
packet.len(),
0,