add two cmd line option (#241)

1. disable_p2p: only using specified peers to relay packets.
2. relay_all_peer_rpc: allow relay route info for networks not in whitelist
This commit is contained in:
Sijie.Sun
2024-08-10 00:26:54 +08:00
committed by GitHub
parent 1d22fdc972
commit b6fb7ac962
7 changed files with 100 additions and 19 deletions

View File

@@ -171,6 +171,10 @@ pub struct Flags {
pub use_smoltcp: bool,
#[derivative(Default(value = "\"*\".to_string()"))]
pub foreign_network_whitelist: String,
#[derivative(Default(value = "false"))]
pub disable_p2p: bool,
#[derivative(Default(value = "false"))]
pub relay_all_peer_rpc: bool,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]

View File

@@ -121,6 +121,10 @@ impl DirectConnectorManager {
}
pub fn run(&mut self) {
if self.global_ctx.get_flags().disable_p2p {
return;
}
self.run_as_server();
self.run_as_client();
}

View File

@@ -602,6 +602,10 @@ impl UdpHolePunchConnector {
}
pub async fn run(&mut self) -> Result<(), Error> {
if self.data.global_ctx.get_flags().disable_p2p {
return Ok(());
}
self.run_as_client().await?;
self.run_as_server().await?;

View File

@@ -259,6 +259,20 @@ struct Cli {
num_args = 0..
)]
relay_network_whitelist: Option<Vec<String>>,
#[arg(
long,
help = t!("core_clap.disable_p2p").to_string(),
default_value = "false"
)]
disable_p2p: bool,
#[arg(
long,
help = t!("core_clap.relay_all_peer_rpc").to_string(),
default_value = "false"
)]
relay_all_peer_rpc: bool,
}
rust_i18n::i18n!("locales");
@@ -494,6 +508,8 @@ impl From<Cli> for TomlConfigLoader {
if let Some(wl) = cli.relay_network_whitelist {
f.foreign_network_whitelist = wl.join(" ");
}
f.disable_p2p = cli.disable_p2p;
f.relay_all_peer_rpc = cli.relay_all_peer_rpc;
cfg.set_flags(f);
cfg.set_exit_nodes(cli.exit_nodes.clone());

View File

@@ -37,6 +37,7 @@ use super::{
struct ForeignNetworkEntry {
network: NetworkIdentity,
peer_map: Arc<PeerMap>,
relay_data: bool,
}
impl ForeignNetworkEntry {
@@ -45,9 +46,14 @@ impl ForeignNetworkEntry {
packet_sender: PacketRecvChan,
global_ctx: ArcGlobalCtx,
my_peer_id: PeerId,
relay_data: bool,
) -> Self {
let peer_map = Arc::new(PeerMap::new(packet_sender, global_ctx, my_peer_id));
Self { network, peer_map }
Self {
network,
peer_map,
relay_data,
}
}
}
@@ -195,9 +201,30 @@ impl ForeignNetworkManager {
}
}
fn check_network_in_whitelist(&self, network_name: &str) -> Result<(), Error> {
if self
.global_ctx
.get_flags()
.foreign_network_whitelist
.split(" ")
.map(wildmatch::WildMatch::new)
.any(|wl| wl.matches(network_name))
{
Ok(())
} else {
Err(anyhow::anyhow!("network {} not in whitelist", network_name).into())
}
}
pub async fn add_peer_conn(&self, peer_conn: PeerConn) -> Result<(), Error> {
tracing::info!(peer_conn = ?peer_conn.get_conn_info(), network = ?peer_conn.get_network_identity(), "add new peer conn in foreign network manager");
let relay_peer_rpc = self.global_ctx.get_flags().relay_all_peer_rpc;
let ret = self.check_network_in_whitelist(&peer_conn.get_network_identity().network_name);
if ret.is_err() && !relay_peer_rpc {
return ret;
}
let entry = self
.data
.network_peer_maps
@@ -208,6 +235,7 @@ impl ForeignNetworkManager {
self.packet_sender.clone(),
self.global_ctx.clone(),
self.my_peer_id,
!ret.is_err(),
))
})
.clone();
@@ -280,6 +308,10 @@ impl ForeignNetworkManager {
}
if let Some(entry) = data.get_network_entry(&from_network) {
if !entry.relay_data && hdr.packet_type == PacketType::Data as u8 {
continue;
}
let ret = entry
.peer_map
.send_msg(packet_bytes, to_peer_id, NextHopPolicy::LeastHop)
@@ -424,6 +456,31 @@ mod tests {
foreign_network_whitelist_helper("net2abc".to_string()).await;
}
#[tokio::test]
async fn only_relay_peer_rpc() {
let pm_center = create_mock_peer_manager_with_mock_stun(crate::rpc::NatType::Unknown).await;
let mut flag = pm_center.get_global_ctx().get_flags();
flag.foreign_network_whitelist = "".to_string();
flag.relay_all_peer_rpc = true;
pm_center.get_global_ctx().config.set_flags(flag);
tracing::debug!("pm_center: {:?}", pm_center.my_peer_id());
let pma_net1 = create_mock_peer_manager_for_foreign_network("net1").await;
let pmb_net1 = create_mock_peer_manager_for_foreign_network("net1").await;
tracing::debug!(
"pma_net1: {:?}, pmb_net1: {:?}",
pma_net1.my_peer_id(),
pmb_net1.my_peer_id()
);
connect_peer_manager(pma_net1.clone(), pm_center.clone()).await;
connect_peer_manager(pmb_net1.clone(), pm_center.clone()).await;
wait_route_appear(pma_net1.clone(), pmb_net1.clone())
.await
.unwrap();
assert_eq!(1, pma_net1.list_routes().await.len());
assert_eq!(1, pmb_net1.list_routes().await.len());
}
#[tokio::test]
#[should_panic]
async fn foreign_network_whitelist_fail() {

View File

@@ -309,21 +309,6 @@ impl PeerManager {
self.add_client_tunnel(t).await
}
fn check_network_in_whitelist(&self, network_name: &str) -> Result<(), Error> {
if self
.global_ctx
.get_flags()
.foreign_network_whitelist
.split(" ")
.map(wildmatch::WildMatch::new)
.any(|wl| wl.matches(network_name))
{
Ok(())
} else {
Err(anyhow::anyhow!("network {} not in whitelist", network_name).into())
}
}
#[tracing::instrument]
pub async fn add_tunnel_as_server(&self, tunnel: Box<dyn Tunnel>) -> Result<(), Error> {
tracing::info!("add tunnel as server start");
@@ -334,7 +319,6 @@ impl PeerManager {
{
self.add_new_peer_conn(peer).await?;
} else {
self.check_network_in_whitelist(&peer.get_network_identity().network_name)?;
self.foreign_network_manager.add_peer_conn(peer).await?;
}
tracing::info!("add tunnel as server done");