fix icmp/udp subnet proxy not work with public server relay (#431)

This commit is contained in:
Sijie.Sun
2024-10-17 00:22:42 +08:00
committed by GitHub
parent 4df8d7e976
commit 2134bc9139
2 changed files with 79 additions and 56 deletions

View File

@@ -700,11 +700,21 @@ impl PeerManager {
let policy = let policy =
Self::get_next_hop_policy(msg.peer_manager_header().unwrap().is_latency_first()); Self::get_next_hop_policy(msg.peer_manager_header().unwrap().is_latency_first());
if let Some(gateway) = peers.get_gateway_peer_id(dst_peer_id, policy).await { if let Some(gateway) = peers.get_gateway_peer_id(dst_peer_id, policy.clone()).await {
peers.send_msg_directly(msg, gateway).await if peers.has_peer(gateway) {
} else if foreign_network_client.has_next_hop(dst_peer_id) { peers.send_msg_directly(msg, gateway).await
foreign_network_client.send_msg(msg, dst_peer_id).await } else if foreign_network_client.has_next_hop(gateway) {
foreign_network_client.send_msg(msg, gateway).await
} else {
tracing::warn!(
?gateway,
?dst_peer_id,
"cannot send msg to peer through gateway"
);
Err(Error::RouteError(None))
}
} else { } else {
tracing::debug!(?dst_peer_id, "no gateway for peer");
Err(Error::RouteError(None)) Err(Error::RouteError(None))
} }
} }
@@ -767,10 +777,8 @@ impl PeerManager {
.unwrap() .unwrap()
.set_latency_first(is_latency_first) .set_latency_first(is_latency_first)
.set_exit_node(is_exit_node); .set_exit_node(is_exit_node);
let next_hop_policy = Self::get_next_hop_policy(is_latency_first);
let mut errs: Vec<Error> = vec![]; let mut errs: Vec<Error> = vec![];
let mut msg = Some(msg); let mut msg = Some(msg);
let total_dst_peers = dst_peers.len(); let total_dst_peers = dst_peers.len();
for i in 0..total_dst_peers { for i in 0..total_dst_peers {
@@ -786,28 +794,11 @@ impl PeerManager {
.to_peer_id .to_peer_id
.set(*peer_id); .set(*peer_id);
if let Some(gateway) = self if let Err(e) =
.peers Self::send_msg_internal(&self.peers, &self.foreign_network_client, msg, *peer_id)
.get_gateway_peer_id(*peer_id, next_hop_policy.clone()) .await
.await
{ {
if self.peers.has_peer(gateway) { errs.push(e);
if let Err(e) = self.peers.send_msg_directly(msg, gateway).await {
errs.push(e);
}
} else if self.foreign_network_client.has_next_hop(gateway) {
if let Err(e) = self.foreign_network_client.send_msg(msg, gateway).await {
errs.push(e);
}
} else {
tracing::warn!(
?gateway,
?peer_id,
"cannot send msg to peer through gateway"
);
}
} else {
tracing::debug!(?peer_id, "no gateway for peer");
} }
} }

View File

@@ -1,3 +1,4 @@
use core::panic;
use std::{ use std::{
sync::{atomic::AtomicU32, Arc}, sync::{atomic::AtomicU32, Arc},
time::Duration, time::Duration,
@@ -61,12 +62,13 @@ pub fn get_inst_config(inst_name: &str, ns: Option<&str>, ipv4: &str) -> TomlCon
} }
pub async fn init_three_node(proto: &str) -> Vec<Instance> { pub async fn init_three_node(proto: &str) -> Vec<Instance> {
init_three_node_ex(proto, |cfg| cfg).await init_three_node_ex(proto, |cfg| cfg, false).await
} }
pub async fn init_three_node_ex<F: Fn(TomlConfigLoader) -> TomlConfigLoader>( pub async fn init_three_node_ex<F: Fn(TomlConfigLoader) -> TomlConfigLoader>(
proto: &str, proto: &str,
cfg_cb: F, cfg_cb: F,
use_public_server: bool,
) -> Vec<Instance> { ) -> Vec<Instance> {
prepare_linux_namespaces(); prepare_linux_namespaces();
@@ -91,26 +93,26 @@ pub async fn init_three_node_ex<F: Fn(TomlConfigLoader) -> TomlConfigLoader>(
inst3.run().await.unwrap(); inst3.run().await.unwrap();
if proto == "tcp" { if proto == "tcp" {
inst2 inst1
.get_conn_manager() .get_conn_manager()
.add_connector(TcpTunnelConnector::new( .add_connector(TcpTunnelConnector::new(
"tcp://10.1.1.1:11010".parse().unwrap(), "tcp://10.1.1.2:11010".parse().unwrap(),
)); ));
} else if proto == "udp" { } else if proto == "udp" {
inst2 inst1
.get_conn_manager() .get_conn_manager()
.add_connector(UdpTunnelConnector::new( .add_connector(UdpTunnelConnector::new(
"udp://10.1.1.1:11010".parse().unwrap(), "udp://10.1.1.2:11010".parse().unwrap(),
)); ));
} else if proto == "wg" { } else if proto == "wg" {
#[cfg(feature = "wireguard")] #[cfg(feature = "wireguard")]
inst2 inst1
.get_conn_manager() .get_conn_manager()
.add_connector(WgTunnelConnector::new( .add_connector(WgTunnelConnector::new(
"wg://10.1.1.1:11011".parse().unwrap(), "wg://10.1.1.2:11011".parse().unwrap(),
WgConfig::new_from_network_identity( WgConfig::new_from_network_identity(
&inst1.get_global_ctx().get_network_identity().network_name, &inst2.get_global_ctx().get_network_identity().network_name,
&inst1 &inst2
.get_global_ctx() .get_global_ctx()
.get_network_identity() .get_network_identity()
.network_secret .network_secret
@@ -119,36 +121,53 @@ pub async fn init_three_node_ex<F: Fn(TomlConfigLoader) -> TomlConfigLoader>(
)); ));
} else if proto == "ws" { } else if proto == "ws" {
#[cfg(feature = "websocket")] #[cfg(feature = "websocket")]
inst2 inst1
.get_conn_manager() .get_conn_manager()
.add_connector(crate::tunnel::websocket::WSTunnelConnector::new( .add_connector(crate::tunnel::websocket::WSTunnelConnector::new(
"ws://10.1.1.1:11011".parse().unwrap(), "ws://10.1.1.2:11011".parse().unwrap(),
)); ));
} else if proto == "wss" { } else if proto == "wss" {
#[cfg(feature = "websocket")] #[cfg(feature = "websocket")]
inst2 inst1
.get_conn_manager() .get_conn_manager()
.add_connector(crate::tunnel::websocket::WSTunnelConnector::new( .add_connector(crate::tunnel::websocket::WSTunnelConnector::new(
"wss://10.1.1.1:11012".parse().unwrap(), "wss://10.1.1.2:11012".parse().unwrap(),
)); ));
} }
inst2 inst3
.get_conn_manager() .get_conn_manager()
.add_connector(RingTunnelConnector::new( .add_connector(RingTunnelConnector::new(
format!("ring://{}", inst3.id()).parse().unwrap(), format!("ring://{}", inst2.id()).parse().unwrap(),
)); ));
// wait inst2 have two route. // wait inst2 have two route.
wait_for_condition( wait_for_condition(
|| async { inst2.get_peer_manager().list_routes().await.len() == 2 }, || async {
Duration::from_secs(5000), if !use_public_server {
inst2.get_peer_manager().list_routes().await.len() == 2
} else {
inst2
.get_peer_manager()
.get_foreign_network_manager()
.list_foreign_networks()
.await
.foreign_networks
.len()
== 1
}
},
Duration::from_secs(5),
) )
.await; .await;
wait_for_condition( wait_for_condition(
|| async { inst1.get_peer_manager().list_routes().await.len() == 2 }, || async {
Duration::from_secs(5000), let routes = inst1.get_peer_manager().list_routes().await;
println!("routes: {:?}", routes);
routes.len() == 2
},
Duration::from_secs(5),
) )
.await; .await;
@@ -340,17 +359,30 @@ async fn subnet_proxy_test_icmp() {
#[serial_test::serial] #[serial_test::serial]
pub async fn subnet_proxy_three_node_test( pub async fn subnet_proxy_three_node_test(
#[values("tcp", "udp", "wg")] proto: &str, #[values("tcp", "udp", "wg")] proto: &str,
#[values(true)] no_tun: bool, #[values(true, false)] no_tun: bool,
#[values(true, false)] relay_by_public_server: bool,
) { ) {
let insts = init_three_node_ex(proto, |cfg| { let insts = init_three_node_ex(
if cfg.get_inst_name() == "inst3" { proto,
let mut flags = cfg.get_flags(); |cfg| {
flags.no_tun = no_tun; if cfg.get_inst_name() == "inst3" {
cfg.set_flags(flags); let mut flags = cfg.get_flags();
cfg.add_proxy_cidr("10.1.2.0/24".parse().unwrap()); flags.no_tun = no_tun;
} cfg.set_flags(flags);
cfg cfg.add_proxy_cidr("10.1.2.0/24".parse().unwrap());
}) }
if cfg.get_inst_name() == "inst2" && relay_by_public_server {
cfg.set_network_identity(NetworkIdentity::new(
"public".to_string(),
"public".to_string(),
));
}
cfg
},
relay_by_public_server,
)
.await; .await;
assert_eq!(insts[2].get_global_ctx().get_proxy_cidrs().len(), 1); assert_eq!(insts[2].get_global_ctx().get_proxy_cidrs().len(), 1);