mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-07 10:14:35 +00:00
support mapping subnet proxy (#978)
- **support mapping subproxy network cidr** - **add command line option for proxy network mapping** - **fix Instance leak in tests.
This commit is contained in:
@@ -62,9 +62,9 @@ pub trait ConfigLoader: Send + Sync {
|
||||
fn get_dhcp(&self) -> bool;
|
||||
fn set_dhcp(&self, dhcp: bool);
|
||||
|
||||
fn add_proxy_cidr(&self, cidr: cidr::IpCidr);
|
||||
fn remove_proxy_cidr(&self, cidr: cidr::IpCidr);
|
||||
fn get_proxy_cidrs(&self) -> Vec<cidr::IpCidr>;
|
||||
fn add_proxy_cidr(&self, cidr: cidr::Ipv4Cidr, mapped_cidr: Option<cidr::Ipv4Cidr>);
|
||||
fn remove_proxy_cidr(&self, cidr: cidr::Ipv4Cidr);
|
||||
fn get_proxy_cidrs(&self) -> Vec<ProxyNetworkConfig>;
|
||||
|
||||
fn get_network_identity(&self) -> NetworkIdentity;
|
||||
fn set_network_identity(&self, identity: NetworkIdentity);
|
||||
@@ -171,7 +171,8 @@ pub struct PeerConfig {
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
||||
pub struct ProxyNetworkConfig {
|
||||
pub cidr: String,
|
||||
pub cidr: cidr::Ipv4Cidr, // the CIDR of the proxy network
|
||||
pub mapped_cidr: Option<cidr::Ipv4Cidr>, // allow remap the proxy CIDR to another CIDR
|
||||
pub allow: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
@@ -418,50 +419,52 @@ impl ConfigLoader for TomlConfigLoader {
|
||||
self.config.lock().unwrap().dhcp = Some(dhcp);
|
||||
}
|
||||
|
||||
fn add_proxy_cidr(&self, cidr: cidr::IpCidr) {
|
||||
fn add_proxy_cidr(&self, cidr: cidr::Ipv4Cidr, mapped_cidr: Option<cidr::Ipv4Cidr>) {
|
||||
let mut locked_config = self.config.lock().unwrap();
|
||||
if locked_config.proxy_network.is_none() {
|
||||
locked_config.proxy_network = Some(vec![]);
|
||||
}
|
||||
let cidr_str = cidr.to_string();
|
||||
if let Some(mapped_cidr) = mapped_cidr.as_ref() {
|
||||
assert_eq!(
|
||||
cidr.network_length(),
|
||||
mapped_cidr.network_length(),
|
||||
"Mapped CIDR must have the same network length as the original CIDR",
|
||||
);
|
||||
}
|
||||
// insert if no duplicate
|
||||
if !locked_config
|
||||
.proxy_network
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.any(|c| c.cidr == cidr_str)
|
||||
.any(|c| c.cidr == cidr)
|
||||
{
|
||||
locked_config
|
||||
.proxy_network
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.push(ProxyNetworkConfig {
|
||||
cidr: cidr_str,
|
||||
cidr,
|
||||
mapped_cidr,
|
||||
allow: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_proxy_cidr(&self, cidr: cidr::IpCidr) {
|
||||
fn remove_proxy_cidr(&self, cidr: cidr::Ipv4Cidr) {
|
||||
let mut locked_config = self.config.lock().unwrap();
|
||||
if let Some(proxy_cidrs) = &mut locked_config.proxy_network {
|
||||
let cidr_str = cidr.to_string();
|
||||
proxy_cidrs.retain(|c| c.cidr != cidr_str);
|
||||
proxy_cidrs.retain(|c| c.cidr != cidr);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_proxy_cidrs(&self) -> Vec<cidr::IpCidr> {
|
||||
fn get_proxy_cidrs(&self) -> Vec<ProxyNetworkConfig> {
|
||||
self.config
|
||||
.lock()
|
||||
.unwrap()
|
||||
.proxy_network
|
||||
.as_ref()
|
||||
.map(|v| {
|
||||
v.iter()
|
||||
.map(|c| c.cidr.parse().unwrap())
|
||||
.collect::<Vec<cidr::IpCidr>>()
|
||||
})
|
||||
.cloned()
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ use std::{
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use crate::common::config::ProxyNetworkConfig;
|
||||
use crate::proto::cli::PeerConnInfo;
|
||||
use crate::proto::common::{PeerFeatureFlag, PortForwardConfigPb};
|
||||
use crossbeam::atomic::AtomicCell;
|
||||
@@ -59,7 +60,7 @@ pub struct GlobalCtx {
|
||||
event_bus: EventBus,
|
||||
|
||||
cached_ipv4: AtomicCell<Option<cidr::Ipv4Inet>>,
|
||||
cached_proxy_cidrs: AtomicCell<Option<Vec<cidr::IpCidr>>>,
|
||||
cached_proxy_cidrs: AtomicCell<Option<Vec<ProxyNetworkConfig>>>,
|
||||
|
||||
ip_collector: Mutex<Option<Arc<IPCollector>>>,
|
||||
|
||||
@@ -182,29 +183,6 @@ impl GlobalCtx {
|
||||
self.cached_ipv4.store(None);
|
||||
}
|
||||
|
||||
pub fn add_proxy_cidr(&self, cidr: cidr::IpCidr) -> Result<(), std::io::Error> {
|
||||
self.config.add_proxy_cidr(cidr);
|
||||
self.cached_proxy_cidrs.store(None);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn remove_proxy_cidr(&self, cidr: cidr::IpCidr) -> Result<(), std::io::Error> {
|
||||
self.config.remove_proxy_cidr(cidr);
|
||||
self.cached_proxy_cidrs.store(None);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_proxy_cidrs(&self) -> Vec<cidr::IpCidr> {
|
||||
if let Some(proxy_cidrs) = self.cached_proxy_cidrs.take() {
|
||||
self.cached_proxy_cidrs.store(Some(proxy_cidrs.clone()));
|
||||
return proxy_cidrs;
|
||||
}
|
||||
|
||||
let ret = self.config.get_proxy_cidrs();
|
||||
self.cached_proxy_cidrs.store(Some(ret.clone()));
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn get_id(&self) -> uuid::Uuid {
|
||||
self.config.get_id()
|
||||
}
|
||||
|
||||
@@ -955,9 +955,18 @@ mod tests {
|
||||
async fn test_txt_public_stun_server() {
|
||||
let stun_servers = vec!["txt:stun.easytier.cn".to_string()];
|
||||
let detector = UdpNatTypeDetector::new(stun_servers, 1);
|
||||
let ret = detector.detect_nat_type(0).await;
|
||||
println!("{:#?}, {:?}", ret, ret.as_ref().unwrap().nat_type());
|
||||
assert!(!ret.unwrap().stun_resps.is_empty());
|
||||
for _ in 0..5 {
|
||||
let ret = detector.detect_nat_type(0).await;
|
||||
println!("{:#?}, {:?}", ret, ret.as_ref().unwrap().nat_type());
|
||||
if ret.is_ok() {
|
||||
assert!(!ret.unwrap().stun_resps.is_empty());
|
||||
return;
|
||||
}
|
||||
}
|
||||
debug_assert!(
|
||||
false,
|
||||
"should not reach here, stun server should be available"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
Reference in New Issue
Block a user