From 41b6d656046a61ebcce921f4b381c5d8db39556c Mon Sep 17 00:00:00 2001 From: KKRainbow <443152178@qq.com> Date: Thu, 30 Apr 2026 23:55:56 +0800 Subject: [PATCH] fix faketcp filter on windows (#2190) --- easytier/src/tunnel/fake_tcp/netfilter/mod.rs | 14 +++--- .../tunnel/fake_tcp/netfilter/windivert.rs | 50 ++++++++++++++++--- easytier/src/tunnel/fake_tcp/packet.rs | 1 - easytier/src/tunnel/fake_tcp/stack.rs | 5 +- 4 files changed, 54 insertions(+), 16 deletions(-) diff --git a/easytier/src/tunnel/fake_tcp/netfilter/mod.rs b/easytier/src/tunnel/fake_tcp/netfilter/mod.rs index d238b60a..9817bfbe 100644 --- a/easytier/src/tunnel/fake_tcp/netfilter/mod.rs +++ b/easytier/src/tunnel/fake_tcp/netfilter/mod.rs @@ -57,21 +57,21 @@ cfg_select! { pub mod windivert; pub fn create_tun( - _interface_name: &str, - _src_addr: Option, - local_addr: SocketAddr, + interface_name: &str, + src_addr: Option, + dst_addr: SocketAddr, ) -> io::Result> { - match windivert::WinDivertTun::new(local_addr) { + match windivert::WinDivertTun::new(src_addr, dst_addr) { Ok(tun) => Ok(Arc::new(tun)), Err(e) => { tracing::warn!( ?e, - ?local_addr, + ?dst_addr, "WinDivertTun init failed, falling back to PnetTun" ); Ok(Arc::new(pnet::PnetTun::new( - local_addr.to_string().as_str(), - pnet::create_packet_filter(None, local_addr), + interface_name, + pnet::create_packet_filter(src_addr, dst_addr), )?)) } } diff --git a/easytier/src/tunnel/fake_tcp/netfilter/windivert.rs b/easytier/src/tunnel/fake_tcp/netfilter/windivert.rs index fdbe0877..289d4a8e 100644 --- a/easytier/src/tunnel/fake_tcp/netfilter/windivert.rs +++ b/easytier/src/tunnel/fake_tcp/netfilter/windivert.rs @@ -80,15 +80,11 @@ impl Drop for WinDivertTun { } impl WinDivertTun { - pub fn new(local_addr: SocketAddr) -> io::Result { + pub fn new(src_addr: Option, dst_addr: SocketAddr) -> io::Result { let (tx, rx) = tokio::sync::mpsc::channel(1024); - let ip_filter = match local_addr { - SocketAddr::V4(addr) => format!("ip.DstAddr == {}", addr.ip()), - SocketAddr::V6(addr) => format!("ipv6.DstAddr == {}", addr.ip()), - }; - // Filter: DstIP == LocalIP AND TCP. - let filter = format!("{} and tcp", ip_filter); + let filter = build_filter(src_addr, dst_addr)?; + tracing::debug!(%filter, "WinDivertTun created with filter"); // Sniff mode: 1 (WINDIVERT_FLAG_SNIFF) // Layer: Network (0) @@ -143,6 +139,46 @@ impl WinDivertTun { } } +fn build_filter(src_addr: Option, dst_addr: SocketAddr) -> io::Result { + if let Some(src_addr) = src_addr + && src_addr.is_ipv4() != dst_addr.is_ipv4() + { + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + "src/dst addr family mismatch", + )); + } + + let mut filters = Vec::with_capacity(5); + filters.push("tcp".to_owned()); + + match dst_addr { + SocketAddr::V4(addr) => { + filters.push(format!("ip.DstAddr == {}", addr.ip())); + filters.push(format!("tcp.DstPort == {}", addr.port())); + } + SocketAddr::V6(addr) => { + filters.push(format!("ipv6.DstAddr == {}", addr.ip())); + filters.push(format!("tcp.DstPort == {}", addr.port())); + } + } + + if let Some(src_addr) = src_addr { + match src_addr { + SocketAddr::V4(addr) => { + filters.push(format!("ip.SrcAddr == {}", addr.ip())); + filters.push(format!("tcp.SrcPort == {}", addr.port())); + } + SocketAddr::V6(addr) => { + filters.push(format!("ipv6.SrcAddr == {}", addr.ip())); + filters.push(format!("tcp.SrcPort == {}", addr.port())); + } + } + } + + Ok(filters.join(" and ")) +} + #[async_trait::async_trait] impl stack::Tun for WinDivertTun { async fn recv(&self, packet: &mut BytesMut) -> Result { diff --git a/easytier/src/tunnel/fake_tcp/packet.rs b/easytier/src/tunnel/fake_tcp/packet.rs index 41770e3b..8f494e10 100644 --- a/easytier/src/tunnel/fake_tcp/packet.rs +++ b/easytier/src/tunnel/fake_tcp/packet.rs @@ -128,7 +128,6 @@ pub fn build_tcp_packet( eth_buf.freeze() } -#[tracing::instrument(ret)] pub fn parse_ip_packet( buf: &Bytes, ) -> Option<(MacAddr, MacAddr, IPPacket<'_>, tcp::TcpPacket<'_>)> { diff --git a/easytier/src/tunnel/fake_tcp/stack.rs b/easytier/src/tunnel/fake_tcp/stack.rs index e9696524..6866c926 100644 --- a/easytier/src/tunnel/fake_tcp/stack.rs +++ b/easytier/src/tunnel/fake_tcp/stack.rs @@ -517,9 +517,12 @@ impl Stack { { trace!(?tcp_packet, "Received SYN packet for port {}, ignoring", tcp_packet.get_destination()); continue; - } else if (tcp_packet.get_flags() & tcp::TcpFlags::RST) == 0 { + } else if (tcp_packet.get_flags() & tcp::TcpFlags::RST) != 0 { info!("Unknown RST TCP packet from {}, ignoring", remote_addr); continue; + } else { + trace!("Unknown TCP packet from {}, ignoring", remote_addr); + continue; } } None => {