mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-06 17:59:11 +00:00
fix faketcp filter on windows (#2190)
This commit is contained in:
@@ -57,21 +57,21 @@ cfg_select! {
|
||||
pub mod windivert;
|
||||
|
||||
pub fn create_tun(
|
||||
_interface_name: &str,
|
||||
_src_addr: Option<SocketAddr>,
|
||||
local_addr: SocketAddr,
|
||||
interface_name: &str,
|
||||
src_addr: Option<SocketAddr>,
|
||||
dst_addr: SocketAddr,
|
||||
) -> io::Result<Arc<dyn super::stack::Tun>> {
|
||||
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),
|
||||
)?))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,15 +80,11 @@ impl Drop for WinDivertTun {
|
||||
}
|
||||
|
||||
impl WinDivertTun {
|
||||
pub fn new(local_addr: SocketAddr) -> io::Result<Self> {
|
||||
pub fn new(src_addr: Option<SocketAddr>, dst_addr: SocketAddr) -> io::Result<Self> {
|
||||
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<SocketAddr>, dst_addr: SocketAddr) -> io::Result<String> {
|
||||
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<usize, std::io::Error> {
|
||||
|
||||
@@ -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<'_>)> {
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
Reference in New Issue
Block a user