remove src modified flag from pm hdr (#1857)

This commit is contained in:
KKRainbow
2026-02-02 16:47:26 +08:00
committed by GitHub
parent cd2cf56358
commit bf3edbd28f
5 changed files with 63 additions and 55 deletions
+3 -4
View File
@@ -13,7 +13,6 @@ use kcp_sys::{
packet_def::KcpPacket, packet_def::KcpPacket,
stream::KcpStream, stream::KcpStream,
}; };
use pnet::packet::ipv4::Ipv4Packet;
use prost::Message; use prost::Message;
use tokio::{select, task::JoinSet}; use tokio::{select, task::JoinSet};
@@ -191,7 +190,7 @@ impl NatDstConnector for NatDstKcpConnector {
_cidr_set: &CidrSet, _cidr_set: &CidrSet,
_global_ctx: &GlobalCtx, _global_ctx: &GlobalCtx,
hdr: &PeerManagerHeader, hdr: &PeerManagerHeader,
_ipv4: &Ipv4Packet, _ipv4: &Ipv4Addr,
_real_dst_ip: &mut Ipv4Addr, _real_dst_ip: &mut Ipv4Addr,
) -> bool { ) -> bool {
hdr.from_peer_id == hdr.to_peer_id && hdr.is_kcp_src_modified() hdr.from_peer_id == hdr.to_peer_id && hdr.is_kcp_src_modified()
@@ -213,8 +212,8 @@ impl TcpProxyForWrappedSrcTrait for TcpProxyForKcpSrc {
&self.0 &self.0
} }
fn set_src_modified(hdr: &mut PeerManagerHeader, modified: bool) -> &mut PeerManagerHeader { fn mark_src_modified(hdr: &mut PeerManagerHeader) -> &mut PeerManagerHeader {
hdr.set_kcp_src_modified(modified) hdr.mark_kcp_src_modified()
} }
async fn check_dst_allow_wrapped_input(&self, dst_ip: &Ipv4Addr) -> bool { async fn check_dst_allow_wrapped_input(&self, dst_ip: &Ipv4Addr) -> bool {
+3 -4
View File
@@ -24,7 +24,6 @@ use bytes::{BufMut, Bytes, BytesMut};
use dashmap::DashMap; use dashmap::DashMap;
use derivative::Derivative; use derivative::Derivative;
use derive_more::{Constructor, Deref, DerefMut, From, Into}; use derive_more::{Constructor, Deref, DerefMut, From, Into};
use pnet::packet::ipv4::Ipv4Packet;
use prost::Message; use prost::Message;
use quinn::udp::{EcnCodepoint, RecvMeta, Transmit}; use quinn::udp::{EcnCodepoint, RecvMeta, Transmit};
use quinn::{AsyncUdpSocket, Endpoint, RecvStream, SendStream, StreamId, TokioRuntime, UdpPoller}; use quinn::{AsyncUdpSocket, Endpoint, RecvStream, SendStream, StreamId, TokioRuntime, UdpPoller};
@@ -376,7 +375,7 @@ impl NatDstConnector for NatDstQuicConnector {
_cidr_set: &CidrSet, _cidr_set: &CidrSet,
_global_ctx: &GlobalCtx, _global_ctx: &GlobalCtx,
hdr: &PeerManagerHeader, hdr: &PeerManagerHeader,
_ipv4: &Ipv4Packet, _ipv4: &Ipv4Addr,
_real_dst_ip: &mut Ipv4Addr, _real_dst_ip: &mut Ipv4Addr,
) -> bool { ) -> bool {
hdr.from_peer_id == hdr.to_peer_id && hdr.is_quic_src_modified() hdr.from_peer_id == hdr.to_peer_id && hdr.is_quic_src_modified()
@@ -401,8 +400,8 @@ impl TcpProxyForWrappedSrcTrait for TcpProxyForQuicSrc {
} }
#[inline] #[inline]
fn set_src_modified(hdr: &mut PeerManagerHeader, modified: bool) -> &mut PeerManagerHeader { fn mark_src_modified(hdr: &mut PeerManagerHeader) -> &mut PeerManagerHeader {
hdr.set_quic_src_modified(modified) hdr.mark_quic_src_modified()
} }
#[inline] #[inline]
+33 -20
View File
@@ -51,7 +51,7 @@ pub(crate) trait NatDstConnector: Send + Sync + Clone + 'static {
cidr_set: &CidrSet, cidr_set: &CidrSet,
global_ctx: &GlobalCtx, global_ctx: &GlobalCtx,
hdr: &PeerManagerHeader, hdr: &PeerManagerHeader,
ipv4: &Ipv4Packet, ipv4: &Ipv4Addr,
real_dst_ip: &mut Ipv4Addr, real_dst_ip: &mut Ipv4Addr,
) -> bool; ) -> bool;
fn transport_type(&self) -> TcpProxyEntryTransportType; fn transport_type(&self) -> TcpProxyEntryTransportType;
@@ -90,16 +90,15 @@ impl NatDstConnector for NatDstTcpConnector {
cidr_set: &CidrSet, cidr_set: &CidrSet,
global_ctx: &GlobalCtx, global_ctx: &GlobalCtx,
hdr: &PeerManagerHeader, hdr: &PeerManagerHeader,
ipv4: &Ipv4Packet, ipv4: &Ipv4Addr,
real_dst_ip: &mut Ipv4Addr, real_dst_ip: &mut Ipv4Addr,
) -> bool { ) -> bool {
let is_exit_node = hdr.is_exit_node(); let is_exit_node = hdr.is_exit_node();
if !(cidr_set.contains_v4(ipv4.get_destination(), real_dst_ip) if !(cidr_set.contains_v4(*ipv4, real_dst_ip)
|| is_exit_node || is_exit_node
|| global_ctx.no_tun() || global_ctx.no_tun()
&& Some(ipv4.get_destination()) && Some(*ipv4) == global_ctx.get_ipv4().as_ref().map(Ipv4Inet::address))
== global_ctx.get_ipv4().as_ref().map(Ipv4Inet::address))
{ {
return false; return false;
} }
@@ -885,33 +884,47 @@ impl<C: NatDstConnector> TcpProxy<C> {
let ipv4_inet = self.get_local_inet()?; let ipv4_inet = self.get_local_inet()?;
let ipv4_addr = ipv4_inet.address(); let ipv4_addr = ipv4_inet.address();
let hdr = packet.peer_manager_header().unwrap().clone(); {
let hdr = packet.peer_manager_header().unwrap();
if hdr.packet_type != PacketType::Data as u8 || hdr.is_no_proxy() { if (hdr.packet_type != PacketType::Data as u8
return None; && hdr.packet_type != PacketType::DataWithKcpSrcModified as u8
}; && hdr.packet_type != PacketType::DataWithQuicSrcModified as u8)
|| hdr.is_no_proxy()
let payload_bytes = packet.mut_payload(); {
return None;
let ipv4 = Ipv4Packet::new(payload_bytes)?; };
if ipv4.get_version() != 4 || ipv4.get_next_level_protocol() != IpNextHeaderProtocols::Tcp {
return None;
} }
let mut real_dst_ip = ipv4.get_destination(); let origin_ip = {
let payload_bytes = packet.mut_payload();
let ipv4 = Ipv4Packet::new(payload_bytes)?;
if ipv4.get_version() != 4
|| ipv4.get_next_level_protocol() != IpNextHeaderProtocols::Tcp
{
return None;
}
ipv4.get_destination()
};
let mut real_dst_ip = origin_ip;
let hdr = packet.mut_peer_manager_header().unwrap();
if !self.connector.check_packet_from_peer( if !self.connector.check_packet_from_peer(
&self.cidr_set, &self.cidr_set,
&self.global_ctx, &self.global_ctx,
&hdr, hdr,
&ipv4, &origin_ip,
&mut real_dst_ip, &mut real_dst_ip,
) { ) {
return None; return None;
} }
tracing::trace!(ipv4 = ?ipv4, cidr_set = ?self.cidr_set, "proxy tcp packet received"); // restore to data packet
hdr.packet_type = PacketType::Data as u8;
tracing::trace!(ipv4 = ?origin_ip, cidr_set = ?self.cidr_set, "proxy tcp packet received");
let payload_bytes = packet.mut_payload();
let ip_packet = Ipv4Packet::new(payload_bytes).unwrap(); let ip_packet = Ipv4Packet::new(payload_bytes).unwrap();
let tcp_packet = TcpPacket::new(ip_packet.payload()).unwrap(); let tcp_packet = TcpPacket::new(ip_packet.payload()).unwrap();
+9 -3
View File
@@ -12,7 +12,7 @@ use pnet::packet::{
use tokio::io::{copy_bidirectional, AsyncRead, AsyncWrite}; use tokio::io::{copy_bidirectional, AsyncRead, AsyncWrite};
use tokio_util::io::InspectReader; use tokio_util::io::InspectReader;
use crate::tunnel::packet_def::PeerManagerHeader; use crate::tunnel::packet_def::{PacketType, PeerManagerHeader};
use crate::{ use crate::{
common::{acl_processor::PacketInfo, error::Result}, common::{acl_processor::PacketInfo, error::Result},
gateway::tcp_proxy::{NatDstConnector, TcpProxy}, gateway::tcp_proxy::{NatDstConnector, TcpProxy},
@@ -69,7 +69,7 @@ impl ProxyAclHandler {
pub(crate) trait TcpProxyForWrappedSrcTrait: Send + Sync + 'static { pub(crate) trait TcpProxyForWrappedSrcTrait: Send + Sync + 'static {
type Connector: NatDstConnector; type Connector: NatDstConnector;
fn get_tcp_proxy(&self) -> &Arc<TcpProxy<Self::Connector>>; fn get_tcp_proxy(&self) -> &Arc<TcpProxy<Self::Connector>>;
fn set_src_modified(hdr: &mut PeerManagerHeader, modified: bool) -> &mut PeerManagerHeader; fn mark_src_modified(hdr: &mut PeerManagerHeader) -> &mut PeerManagerHeader;
async fn check_dst_allow_wrapped_input(&self, dst_ip: &Ipv4Addr) -> bool; async fn check_dst_allow_wrapped_input(&self, dst_ip: &Ipv4Addr) -> bool;
} }
@@ -84,6 +84,12 @@ impl<C: NatDstConnector, T: TcpProxyForWrappedSrcTrait<Connector = C>> NicPacket
return true; return true;
} }
let hdr = zc_packet.mut_peer_manager_header().unwrap();
if hdr.packet_type != PacketType::Data as u8 {
// already handled by other proxy
return false;
}
let data = zc_packet.payload(); let data = zc_packet.payload();
let ip_packet = Ipv4Packet::new(data).unwrap(); let ip_packet = Ipv4Packet::new(data).unwrap();
if ip_packet.get_version() != 4 if ip_packet.get_version() != 4
@@ -141,7 +147,7 @@ impl<C: NatDstConnector, T: TcpProxyForWrappedSrcTrait<Connector = C>> NicPacket
let hdr = zc_packet.mut_peer_manager_header().unwrap(); let hdr = zc_packet.mut_peer_manager_header().unwrap();
hdr.to_peer_id = self.get_tcp_proxy().get_my_peer_id().into(); hdr.to_peer_id = self.get_tcp_proxy().get_my_peer_id().into();
Self::set_src_modified(hdr, true); Self::mark_src_modified(hdr);
true true
} }
} }
+15 -24
View File
@@ -77,6 +77,10 @@ pub enum PacketType {
NoiseHandshakeMsg1 = 13, NoiseHandshakeMsg1 = 13,
NoiseHandshakeMsg2 = 14, NoiseHandshakeMsg2 = 14,
NoiseHandshakeMsg3 = 15, NoiseHandshakeMsg3 = 15,
// used internally,
DataWithKcpSrcModified = 18,
DataWithQuicSrcModified = 19,
} }
bitflags::bitflags! { bitflags::bitflags! {
@@ -86,8 +90,9 @@ bitflags::bitflags! {
const EXIT_NODE = 0b0000_0100; const EXIT_NODE = 0b0000_0100;
const NO_PROXY = 0b0000_1000; const NO_PROXY = 0b0000_1000;
const COMPRESSED = 0b0001_0000; const COMPRESSED = 0b0001_0000;
const KCP_SRC_MODIFIED = 0b0010_0000; // deprecated flags, can be reused.
const QUIC_SRC_MODIFIED = 0b1000_0000; // const KCP_SRC_MODIFIED = 0b0010_0000;
// const QUIC_SRC_MODIFIED = 0b1000_0000;
const NOT_SEND_TO_TUN = 0b0100_0000; const NOT_SEND_TO_TUN = 0b0100_0000;
const _ = !0; const _ = !0;
@@ -192,38 +197,24 @@ impl PeerManagerHeader {
self self
} }
pub fn set_kcp_src_modified(&mut self, modified: bool) -> &mut Self { pub fn mark_kcp_src_modified(&mut self) -> &mut Self {
let mut flags = PeerManagerHeaderFlags::from_bits(self.flags).unwrap(); assert_eq!(self.packet_type, PacketType::Data as u8);
if modified { self.packet_type = PacketType::DataWithKcpSrcModified as u8;
flags.insert(PeerManagerHeaderFlags::KCP_SRC_MODIFIED);
} else {
flags.remove(PeerManagerHeaderFlags::KCP_SRC_MODIFIED);
}
self.flags = flags.bits();
self self
} }
pub fn is_kcp_src_modified(&self) -> bool { pub fn is_kcp_src_modified(&self) -> bool {
PeerManagerHeaderFlags::from_bits(self.flags) self.packet_type == PacketType::DataWithKcpSrcModified as u8
.unwrap()
.contains(PeerManagerHeaderFlags::KCP_SRC_MODIFIED)
} }
pub fn set_quic_src_modified(&mut self, modified: bool) -> &mut Self { pub fn mark_quic_src_modified(&mut self) -> &mut Self {
let mut flags = PeerManagerHeaderFlags::from_bits(self.flags).unwrap(); assert_eq!(self.packet_type, PacketType::Data as u8);
if modified { self.packet_type = PacketType::DataWithQuicSrcModified as u8;
flags.insert(PeerManagerHeaderFlags::QUIC_SRC_MODIFIED);
} else {
flags.remove(PeerManagerHeaderFlags::QUIC_SRC_MODIFIED);
}
self.flags = flags.bits();
self self
} }
pub fn is_quic_src_modified(&self) -> bool { pub fn is_quic_src_modified(&self) -> bool {
PeerManagerHeaderFlags::from_bits(self.flags) self.packet_type == PacketType::DataWithQuicSrcModified as u8
.unwrap()
.contains(PeerManagerHeaderFlags::QUIC_SRC_MODIFIED)
} }
pub fn set_not_send_to_tun(&mut self, not_send_to_tun: bool) -> &mut Self { pub fn set_not_send_to_tun(&mut self, not_send_to_tun: bool) -> &mut Self {