mirror of
https://mirror.suhoan.cn/https://github.com/EasyTier/EasyTier.git
synced 2025-12-12 20:57:26 +08:00
make kcp proxy compitible with old version (#585)
* fix kcp not work with smoltcp * check if dst kcp input is enabled
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -3551,7 +3551,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "kcp-sys"
|
name = "kcp-sys"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/EasyTier/kcp-sys#a932f3ed394cad1ace9c56f90611b421d856e628"
|
source = "git+https://github.com/EasyTier/kcp-sys#9ce5c08807378ad0486291928994c4f80878c196"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"auto_impl",
|
"auto_impl",
|
||||||
|
|||||||
@@ -101,6 +101,10 @@ impl GlobalCtx {
|
|||||||
let enable_exit_node = config_fs.get_flags().enable_exit_node;
|
let enable_exit_node = config_fs.get_flags().enable_exit_node;
|
||||||
let no_tun = config_fs.get_flags().no_tun;
|
let no_tun = config_fs.get_flags().no_tun;
|
||||||
|
|
||||||
|
let mut feature_flags = PeerFeatureFlag::default();
|
||||||
|
feature_flags.kcp_input = !config_fs.get_flags().disable_kcp_input;
|
||||||
|
feature_flags.no_relay_kcp = config_fs.get_flags().disable_relay_kcp;
|
||||||
|
|
||||||
GlobalCtx {
|
GlobalCtx {
|
||||||
inst_name: config_fs.get_inst_name(),
|
inst_name: config_fs.get_inst_name(),
|
||||||
id,
|
id,
|
||||||
@@ -123,7 +127,7 @@ impl GlobalCtx {
|
|||||||
enable_exit_node,
|
enable_exit_node,
|
||||||
no_tun,
|
no_tun,
|
||||||
|
|
||||||
feature_flags: AtomicCell::new(PeerFeatureFlag::default()),
|
feature_flags: AtomicCell::new(feature_flags),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use std::{
|
use std::{
|
||||||
net::{IpAddr, SocketAddr},
|
net::{IpAddr, Ipv4Addr, SocketAddr},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
@@ -8,6 +8,7 @@ use anyhow::Context;
|
|||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use kcp_sys::{
|
use kcp_sys::{
|
||||||
endpoint::{KcpEndpoint, KcpPacketReceiver},
|
endpoint::{KcpEndpoint, KcpPacketReceiver},
|
||||||
|
ffi_safe::KcpConfig,
|
||||||
packet_def::KcpPacket,
|
packet_def::KcpPacket,
|
||||||
stream::KcpStream,
|
stream::KcpStream,
|
||||||
};
|
};
|
||||||
@@ -29,6 +30,16 @@ use crate::{
|
|||||||
tunnel::packet_def::{PacketType, PeerManagerHeader, ZCPacket},
|
tunnel::packet_def::{PacketType, PeerManagerHeader, ZCPacket},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fn create_kcp_endpoint() -> KcpEndpoint {
|
||||||
|
let mut kcp_endpoint = KcpEndpoint::new();
|
||||||
|
kcp_endpoint.set_kcp_config_factory(Box::new(|conv| {
|
||||||
|
let mut cfg = KcpConfig::new_turbo(conv);
|
||||||
|
cfg.interval = Some(5);
|
||||||
|
cfg
|
||||||
|
}));
|
||||||
|
kcp_endpoint
|
||||||
|
}
|
||||||
|
|
||||||
struct KcpEndpointFilter {
|
struct KcpEndpointFilter {
|
||||||
kcp_endpoint: Arc<KcpEndpoint>,
|
kcp_endpoint: Arc<KcpEndpoint>,
|
||||||
is_src: bool,
|
is_src: bool,
|
||||||
@@ -153,6 +164,20 @@ pub struct KcpProxySrc {
|
|||||||
tasks: JoinSet<()>,
|
tasks: JoinSet<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TcpProxyForKcpSrc {
|
||||||
|
async fn check_dst_allow_kcp_input(&self, dst_ip: &Ipv4Addr) -> bool {
|
||||||
|
let peer_map: Arc<crate::peers::peer_map::PeerMap> =
|
||||||
|
self.0.get_peer_manager().get_peer_map();
|
||||||
|
let Some(dst_peer_id) = peer_map.get_peer_id_by_ipv4(dst_ip).await else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
let Some(feature_flag) = peer_map.get_peer_feature_flag(dst_peer_id).await else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
feature_flag.kcp_input
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl NicPacketFilter for TcpProxyForKcpSrc {
|
impl NicPacketFilter for TcpProxyForKcpSrc {
|
||||||
async fn try_process_packet_from_nic(&self, zc_packet: &mut ZCPacket) -> bool {
|
async fn try_process_packet_from_nic(&self, zc_packet: &mut ZCPacket) -> bool {
|
||||||
@@ -161,7 +186,7 @@ impl NicPacketFilter for TcpProxyForKcpSrc {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(my_ipv4) = self.0.get_local_ip() else {
|
let Some(my_ipv4) = self.0.get_global_ctx().get_ipv4() else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -169,8 +194,9 @@ impl NicPacketFilter for TcpProxyForKcpSrc {
|
|||||||
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
|
||||||
// TODO: how to support net to net kcp proxy?
|
// TODO: how to support net to net kcp proxy?
|
||||||
|| ip_packet.get_source() != my_ipv4
|
|| ip_packet.get_source() != my_ipv4.address()
|
||||||
|| ip_packet.get_next_level_protocol() != IpNextHeaderProtocols::Tcp
|
|| ip_packet.get_next_level_protocol() != IpNextHeaderProtocols::Tcp
|
||||||
|
|| !self.check_dst_allow_kcp_input(&ip_packet.get_destination()).await
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -183,7 +209,7 @@ impl NicPacketFilter for TcpProxyForKcpSrc {
|
|||||||
|
|
||||||
impl KcpProxySrc {
|
impl KcpProxySrc {
|
||||||
pub async fn new(peer_manager: Arc<PeerManager>) -> Self {
|
pub async fn new(peer_manager: Arc<PeerManager>) -> Self {
|
||||||
let mut kcp_endpoint = KcpEndpoint::new();
|
let mut kcp_endpoint = create_kcp_endpoint();
|
||||||
kcp_endpoint.run().await;
|
kcp_endpoint.run().await;
|
||||||
|
|
||||||
let output_receiver = kcp_endpoint.output_receiver().unwrap();
|
let output_receiver = kcp_endpoint.output_receiver().unwrap();
|
||||||
@@ -238,7 +264,7 @@ pub struct KcpProxyDst {
|
|||||||
|
|
||||||
impl KcpProxyDst {
|
impl KcpProxyDst {
|
||||||
pub async fn new(peer_manager: Arc<PeerManager>) -> Self {
|
pub async fn new(peer_manager: Arc<PeerManager>) -> Self {
|
||||||
let mut kcp_endpoint = KcpEndpoint::new();
|
let mut kcp_endpoint = create_kcp_endpoint();
|
||||||
kcp_endpoint.run().await;
|
kcp_endpoint.run().await;
|
||||||
|
|
||||||
let mut tasks = JoinSet::new();
|
let mut tasks = JoinSet::new();
|
||||||
|
|||||||
@@ -700,6 +700,10 @@ impl<C: NatDstConnector> TcpProxy<C> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_global_ctx(&self) -> &ArcGlobalCtx {
|
||||||
|
&self.global_ctx
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_smoltcp_enabled(&self) -> bool {
|
pub fn is_smoltcp_enabled(&self) -> bool {
|
||||||
self.enable_smoltcp
|
self.enable_smoltcp
|
||||||
.load(std::sync::atomic::Ordering::Relaxed)
|
.load(std::sync::atomic::Ordering::Relaxed)
|
||||||
@@ -783,4 +787,8 @@ impl<C: NatDstConnector> TcpProxy<C> {
|
|||||||
|
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_peer_manager(&self) -> &Arc<PeerManager> {
|
||||||
|
&self.peer_manager
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use crate::{
|
|||||||
global_ctx::{ArcGlobalCtx, GlobalCtxEvent, NetworkIdentity},
|
global_ctx::{ArcGlobalCtx, GlobalCtxEvent, NetworkIdentity},
|
||||||
PeerId,
|
PeerId,
|
||||||
},
|
},
|
||||||
proto::cli::PeerConnInfo,
|
proto::{cli::PeerConnInfo, common::PeerFeatureFlag},
|
||||||
tunnel::{packet_def::ZCPacket, TunnelError},
|
tunnel::{packet_def::ZCPacket, TunnelError},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -167,6 +167,16 @@ impl PeerMap {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_peer_feature_flag(&self, peer_id: PeerId) -> Option<PeerFeatureFlag> {
|
||||||
|
for route in self.routes.read().await.iter() {
|
||||||
|
let feature_flag = route.get_feature_flag(peer_id).await;
|
||||||
|
if feature_flag.is_some() {
|
||||||
|
return feature_flag;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.peer_map.is_empty()
|
self.peer_map.is_empty()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
peers::route_trait::{Route, RouteInterfaceBox},
|
peers::route_trait::{Route, RouteInterfaceBox},
|
||||||
proto::{
|
proto::{
|
||||||
common::{Ipv4Inet, NatType, StunInfo},
|
common::{Ipv4Inet, NatType, PeerFeatureFlag, StunInfo},
|
||||||
peer_rpc::{
|
peer_rpc::{
|
||||||
route_foreign_network_infos, ForeignNetworkRouteInfoEntry, ForeignNetworkRouteInfoKey,
|
route_foreign_network_infos, ForeignNetworkRouteInfoEntry, ForeignNetworkRouteInfoKey,
|
||||||
OspfRouteRpc, OspfRouteRpcClientFactory, OspfRouteRpcServer, PeerIdVersion,
|
OspfRouteRpc, OspfRouteRpcClientFactory, OspfRouteRpcServer, PeerIdVersion,
|
||||||
@@ -2042,6 +2042,8 @@ impl Route for PeerRoute {
|
|||||||
route.cost_latency_first = next_hop_peer_latency_first.map(|x| x.path_latency);
|
route.cost_latency_first = next_hop_peer_latency_first.map(|x| x.path_latency);
|
||||||
route.path_latency_latency_first = next_hop_peer_latency_first.map(|x| x.path_latency);
|
route.path_latency_latency_first = next_hop_peer_latency_first.map(|x| x.path_latency);
|
||||||
|
|
||||||
|
route.feature_flag = item.feature_flag.clone();
|
||||||
|
|
||||||
routes.push(route);
|
routes.push(route);
|
||||||
}
|
}
|
||||||
routes
|
routes
|
||||||
@@ -2101,6 +2103,14 @@ impl Route for PeerRoute {
|
|||||||
.map(|x| x.clone())
|
.map(|x| x.clone())
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn get_feature_flag(&self, peer_id: PeerId) -> Option<PeerFeatureFlag> {
|
||||||
|
self.service_impl
|
||||||
|
.route_table
|
||||||
|
.peer_infos
|
||||||
|
.get(&peer_id)
|
||||||
|
.and_then(|x| x.feature_flag.clone())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PeerPacketFilter for Arc<PeerRoute> {}
|
impl PeerPacketFilter for Arc<PeerRoute> {}
|
||||||
|
|||||||
@@ -4,8 +4,11 @@ use dashmap::DashMap;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
common::{global_ctx::NetworkIdentity, PeerId},
|
common::{global_ctx::NetworkIdentity, PeerId},
|
||||||
proto::peer_rpc::{
|
proto::{
|
||||||
ForeignNetworkRouteInfoEntry, ForeignNetworkRouteInfoKey, RouteForeignNetworkInfos,
|
common::PeerFeatureFlag,
|
||||||
|
peer_rpc::{
|
||||||
|
ForeignNetworkRouteInfoEntry, ForeignNetworkRouteInfoKey, RouteForeignNetworkInfos,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -94,6 +97,8 @@ pub trait Route {
|
|||||||
|
|
||||||
async fn set_route_cost_fn(&self, _cost_fn: RouteCostCalculator) {}
|
async fn set_route_cost_fn(&self, _cost_fn: RouteCostCalculator) {}
|
||||||
|
|
||||||
|
async fn get_feature_flag(&self, peer_id: PeerId) -> Option<PeerFeatureFlag>;
|
||||||
|
|
||||||
async fn dump(&self) -> String {
|
async fn dump(&self) -> String {
|
||||||
"this route implementation does not support dump".to_string()
|
"this route implementation does not support dump".to_string()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,4 +151,6 @@ message StunInfo {
|
|||||||
message PeerFeatureFlag {
|
message PeerFeatureFlag {
|
||||||
bool is_public_server = 1;
|
bool is_public_server = 1;
|
||||||
bool avoid_relay_data = 2;
|
bool avoid_relay_data = 2;
|
||||||
|
bool kcp_input = 3;
|
||||||
|
bool no_relay_kcp = 4;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -365,6 +365,7 @@ pub async fn subnet_proxy_three_node_test(
|
|||||||
#[values(true, false)] no_tun: bool,
|
#[values(true, false)] no_tun: bool,
|
||||||
#[values(true, false)] relay_by_public_server: bool,
|
#[values(true, false)] relay_by_public_server: bool,
|
||||||
#[values(true, false)] enable_kcp_proxy: bool,
|
#[values(true, false)] enable_kcp_proxy: bool,
|
||||||
|
#[values(true, false)] disable_kcp_input: bool,
|
||||||
) {
|
) {
|
||||||
let insts = init_three_node_ex(
|
let insts = init_three_node_ex(
|
||||||
proto,
|
proto,
|
||||||
@@ -372,6 +373,7 @@ pub async fn subnet_proxy_three_node_test(
|
|||||||
if cfg.get_inst_name() == "inst3" {
|
if cfg.get_inst_name() == "inst3" {
|
||||||
let mut flags = cfg.get_flags();
|
let mut flags = cfg.get_flags();
|
||||||
flags.no_tun = no_tun;
|
flags.no_tun = no_tun;
|
||||||
|
flags.disable_kcp_input = disable_kcp_input;
|
||||||
cfg.set_flags(flags);
|
cfg.set_flags(flags);
|
||||||
cfg.add_proxy_cidr("10.1.2.0/24".parse().unwrap());
|
cfg.add_proxy_cidr("10.1.2.0/24".parse().unwrap());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user