From ed73d318bb3bf19601e227ab83dd61d66ce4b9f8 Mon Sep 17 00:00:00 2001 From: Ruikang Wang <78412531+Thankyou-Cheems@users.noreply.github.com> Date: Wed, 30 Sep 2026 11:28:09 +0800 Subject: [PATCH] fix(windows): exclude loopback copies from UDP broadcast relay (#2619) - Filter WinDivert's local outbound loopback copies before relaying. - Preserve intentional repeated payloads and existing address constraints. - Update the capture filter regression assertion. --- easytier/src/instance/windows_udp_broadcast.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/easytier/src/instance/windows_udp_broadcast.rs b/easytier/src/instance/windows_udp_broadcast.rs index 4eaab566..583a113c 100644 --- a/easytier/src/instance/windows_udp_broadcast.rs +++ b/easytier/src/instance/windows_udp_broadcast.rs @@ -40,7 +40,10 @@ fn build_windivert_udp_filter(physical_interfaces: &[PhysicalInterface]) -> Stri dst_filters.push("(ip.DstAddr >= 224.0.0.0 and ip.DstAddr <= 239.255.255.255)".to_owned()); format!( - "outbound and ip and udp and ({}) and ({})", + // Windows can report a local loopback copy of outgoing broadcasts as + // outbound too. Capture only the non-loopback copy; payload-based + // deduplication would also discard legitimate discovery retries. + "outbound and not loopback and ip and udp and ({}) and ({})", src_filter, dst_filters.join(" or ") ) @@ -60,7 +63,7 @@ mod tests { let filter = build_windivert_udp_filter(&interfaces); - assert!(filter.starts_with("outbound and ip and udp and ")); + assert!(filter.starts_with("outbound and not loopback and ip and udp and ")); assert!(filter.contains("ip.SrcAddr == 192.168.1.7")); assert!(filter.contains("ip.SrcAddr == 169.254.13.10")); assert!(filter.contains("ip.DstAddr == 255.255.255.255"));