diff --git a/easytier-core/src/gateway/proxy/wrapped_tcp_proxy.rs b/easytier-core/src/gateway/proxy/wrapped_tcp_proxy.rs index e1ce8c5c..aa613c25 100644 --- a/easytier-core/src/gateway/proxy/wrapped_tcp_proxy.rs +++ b/easytier-core/src/gateway/proxy/wrapped_tcp_proxy.rs @@ -159,6 +159,10 @@ where let is_syn = tcp_packet.syn() && !tcp_packet.ack(); if is_syn { + // Own virtual IP traffic must stay local; it can never reach a peer. + if ctx.local_ipv4 == Some(dst_ip) { + return false; + } if !check_dst_allowed(dst_ip).await { tracing::warn!( ?ctx.transport, @@ -447,4 +451,33 @@ mod tests { .await ); } + + #[tokio::test] + async fn own_virtual_ip_syn_is_not_marked() { + let own_ip = "10.144.144.204".parse().unwrap(); + let src = SocketAddrV4::new(own_ip, 50000); + let dst = SocketAddrV4::new(own_ip, 80); + + for transport in [ + WrappedTcpProxyTransport::Kcp, + WrappedTcpProxyTransport::Quic, + ] { + let mut packet = build_tcp_packet(src, dst, true, false); + + assert!( + !try_process_wrapped_tcp_packet_from_nic( + &mut packet, + context(transport), + |_| false, + |_| async { true }, + ) + .await + ); + + assert_eq!( + packet.peer_manager_header().unwrap().packet_type, + PacketType::Data as u8 + ); + } + } } diff --git a/easytier-core/src/gateway/proxy/wrapped_transport/packet_plane.rs b/easytier-core/src/gateway/proxy/wrapped_transport/packet_plane.rs index 5432bd3a..c6664c28 100644 --- a/easytier-core/src/gateway/proxy/wrapped_transport/packet_plane.rs +++ b/easytier-core/src/gateway/proxy/wrapped_transport/packet_plane.rs @@ -257,7 +257,7 @@ where WrappedTransportKind::Quic => WrappedTcpProxyTransport::Quic, }, my_peer_id: self.peer_manager.my_peer_id(), - local_ipv4: snapshot.local_inet.map(|inet| inet.address()), + local_ipv4: snapshot.virtual_ipv4, smoltcp_enabled: snapshot.smoltcp_enabled, }, move |src| connection_engine.is_tcp_proxy_connection(src),