clippy all codes (#1214)
1. clippy code 2. add fmt and clippy check in ci
This commit is contained in:
@@ -178,6 +178,12 @@ impl AclLogContext {
|
||||
}
|
||||
}
|
||||
|
||||
pub type SharedState = (
|
||||
Arc<DashMap<String, ConnTrackEntry>>,
|
||||
Arc<DashMap<RateLimitKey, Arc<TokenBucket>>>,
|
||||
Arc<DashMap<AclStatKey, u64>>,
|
||||
);
|
||||
|
||||
// High-performance ACL processor - No more internal locks!
|
||||
pub struct AclProcessor {
|
||||
// Immutable rule vectors - no locks needed since they're never modified after creation
|
||||
@@ -321,7 +327,7 @@ impl AclProcessor {
|
||||
.rules
|
||||
.iter()
|
||||
.filter(|rule| rule.enabled)
|
||||
.map(|rule| Self::convert_to_fast_lookup_rule(rule))
|
||||
.map(Self::convert_to_fast_lookup_rule)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Sort by priority (higher priority first)
|
||||
@@ -422,7 +428,7 @@ impl AclProcessor {
|
||||
|
||||
self.inc_cache_entry_stats(cache_entry, packet_info);
|
||||
|
||||
return cache_entry.acl_result.clone().unwrap();
|
||||
cache_entry.acl_result.clone().unwrap()
|
||||
}
|
||||
|
||||
fn inc_cache_entry_stats(&self, cache_entry: &AclCacheEntry, packet_info: &PacketInfo) {
|
||||
@@ -539,7 +545,7 @@ impl AclProcessor {
|
||||
cache_entry.rule_stats_vec.push(rule.rule_stats.clone());
|
||||
cache_entry.matched_rule = RuleId::Priority(rule.priority);
|
||||
cache_entry.acl_result = Some(AclResult {
|
||||
action: rule.action.clone(),
|
||||
action: rule.action,
|
||||
matched_rule: Some(RuleId::Priority(rule.priority)),
|
||||
should_log: false,
|
||||
log_context: Some(AclLogContext::RuleMatch {
|
||||
@@ -595,13 +601,7 @@ impl AclProcessor {
|
||||
}
|
||||
|
||||
/// Get shared state for preserving across hot reloads
|
||||
pub fn get_shared_state(
|
||||
&self,
|
||||
) -> (
|
||||
Arc<DashMap<String, ConnTrackEntry>>,
|
||||
Arc<DashMap<RateLimitKey, Arc<TokenBucket>>>,
|
||||
Arc<DashMap<AclStatKey, u64>>,
|
||||
) {
|
||||
pub fn get_shared_state(&self) -> SharedState {
|
||||
(
|
||||
self.conn_track.clone(),
|
||||
self.rate_limiters.clone(),
|
||||
@@ -698,9 +698,9 @@ impl AclProcessor {
|
||||
}
|
||||
|
||||
/// Check connection state for stateful rules
|
||||
fn check_connection_state(&self, conn_track_key: &String, packet_info: &PacketInfo) {
|
||||
fn check_connection_state(&self, conn_track_key: &str, packet_info: &PacketInfo) {
|
||||
self.conn_track
|
||||
.entry(conn_track_key.clone())
|
||||
.entry(conn_track_key.to_string())
|
||||
.and_modify(|x| {
|
||||
x.last_seen = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
@@ -764,13 +764,13 @@ impl AclProcessor {
|
||||
let src_ip_ranges = rule
|
||||
.source_ips
|
||||
.iter()
|
||||
.filter_map(|ip_inet| Self::convert_ip_inet_to_cidr(ip_inet))
|
||||
.filter_map(|x| Self::convert_ip_inet_to_cidr(x.as_str()))
|
||||
.collect();
|
||||
|
||||
let dst_ip_ranges = rule
|
||||
.destination_ips
|
||||
.iter()
|
||||
.filter_map(|ip_inet| Self::convert_ip_inet_to_cidr(ip_inet))
|
||||
.filter_map(|x| Self::convert_ip_inet_to_cidr(x.as_str()))
|
||||
.collect();
|
||||
|
||||
let src_port_ranges = rule
|
||||
@@ -820,8 +820,8 @@ impl AclProcessor {
|
||||
}
|
||||
|
||||
/// Convert IpInet to CIDR for fast lookup
|
||||
fn convert_ip_inet_to_cidr(input: &String) -> Option<cidr::IpCidr> {
|
||||
cidr::IpCidr::from_str(input.as_str()).ok()
|
||||
fn convert_ip_inet_to_cidr(input: &str) -> Option<cidr::IpCidr> {
|
||||
cidr::IpCidr::from_str(input).ok()
|
||||
}
|
||||
|
||||
/// Increment statistics counter
|
||||
@@ -898,17 +898,13 @@ impl AclProcessor {
|
||||
}
|
||||
|
||||
// 新增辅助函数
|
||||
fn parse_port_start(
|
||||
port_strs: &::prost::alloc::vec::Vec<::prost::alloc::string::String>,
|
||||
) -> Option<u16> {
|
||||
fn parse_port_start(port_strs: &[String]) -> Option<u16> {
|
||||
port_strs
|
||||
.iter()
|
||||
.filter_map(|s| parse_port_range(s).map(|(start, _)| start))
|
||||
.min()
|
||||
}
|
||||
fn parse_port_end(
|
||||
port_strs: &::prost::alloc::vec::Vec<::prost::alloc::string::String>,
|
||||
) -> Option<u16> {
|
||||
fn parse_port_end(port_strs: &[String]) -> Option<u16> {
|
||||
port_strs
|
||||
.iter()
|
||||
.filter_map(|s| parse_port_range(s).map(|(_, end)| end))
|
||||
@@ -1154,18 +1150,22 @@ mod tests {
|
||||
let mut acl_v1 = AclV1::default();
|
||||
|
||||
// Create inbound chain
|
||||
let mut chain = Chain::default();
|
||||
chain.name = "test_inbound".to_string();
|
||||
chain.chain_type = ChainType::Inbound as i32;
|
||||
chain.enabled = true;
|
||||
let mut chain = Chain {
|
||||
name: "test_inbound".to_string(),
|
||||
chain_type: ChainType::Inbound as i32,
|
||||
enabled: true,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// Allow all rule
|
||||
let mut rule = Rule::default();
|
||||
rule.name = "allow_all".to_string();
|
||||
rule.priority = 100;
|
||||
rule.enabled = true;
|
||||
rule.action = Action::Allow as i32;
|
||||
rule.protocol = Protocol::Any as i32;
|
||||
let rule = Rule {
|
||||
name: "allow_all".to_string(),
|
||||
priority: 100,
|
||||
enabled: true,
|
||||
action: Action::Allow as i32,
|
||||
protocol: Protocol::Any as i32,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
chain.rules.push(rule);
|
||||
acl_v1.chains.push(chain);
|
||||
@@ -1278,12 +1278,14 @@ mod tests {
|
||||
// 创建新配置(模拟热加载)
|
||||
let mut new_config = create_test_acl_config();
|
||||
if let Some(ref mut acl_v1) = new_config.acl_v1 {
|
||||
let mut drop_rule = Rule::default();
|
||||
drop_rule.name = "drop_all".to_string();
|
||||
drop_rule.priority = 200;
|
||||
drop_rule.enabled = true;
|
||||
drop_rule.action = Action::Drop as i32;
|
||||
drop_rule.protocol = Protocol::Any as i32;
|
||||
let drop_rule = Rule {
|
||||
name: "drop_all".to_string(),
|
||||
priority: 200,
|
||||
enabled: true,
|
||||
action: Action::Drop as i32,
|
||||
protocol: Protocol::Any as i32,
|
||||
..Default::default()
|
||||
};
|
||||
acl_v1.chains[0].rules.push(drop_rule);
|
||||
}
|
||||
|
||||
@@ -1321,40 +1323,48 @@ mod tests {
|
||||
let mut acl_config = Acl::default();
|
||||
|
||||
let mut acl_v1 = AclV1::default();
|
||||
let mut chain = Chain::default();
|
||||
chain.name = "performance_test".to_string();
|
||||
chain.chain_type = ChainType::Inbound as i32;
|
||||
chain.enabled = true;
|
||||
let mut chain = Chain {
|
||||
name: "performance_test".to_string(),
|
||||
chain_type: ChainType::Inbound as i32,
|
||||
enabled: true,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// 1. High-priority simple rule for UDP (can be cached efficiently)
|
||||
let mut simple_rule = Rule::default();
|
||||
simple_rule.name = "simple_udp".to_string();
|
||||
simple_rule.priority = 300;
|
||||
simple_rule.enabled = true;
|
||||
simple_rule.action = Action::Allow as i32;
|
||||
simple_rule.protocol = Protocol::Udp as i32;
|
||||
let simple_rule = Rule {
|
||||
name: "simple_udp".to_string(),
|
||||
priority: 300,
|
||||
enabled: true,
|
||||
action: Action::Allow as i32,
|
||||
protocol: Protocol::Udp as i32,
|
||||
..Default::default()
|
||||
};
|
||||
// No stateful or rate limit - can benefit from full cache optimization
|
||||
chain.rules.push(simple_rule);
|
||||
|
||||
// 2. Medium-priority stateful + rate-limited rule for TCP (security critical)
|
||||
let mut security_rule = Rule::default();
|
||||
security_rule.name = "security_tcp".to_string();
|
||||
security_rule.priority = 200;
|
||||
security_rule.enabled = true;
|
||||
security_rule.action = Action::Allow as i32;
|
||||
security_rule.protocol = Protocol::Tcp as i32;
|
||||
security_rule.stateful = true;
|
||||
security_rule.rate_limit = 100; // 100 packets/sec
|
||||
security_rule.burst_limit = 200;
|
||||
let security_rule = Rule {
|
||||
name: "security_tcp".to_string(),
|
||||
priority: 200,
|
||||
enabled: true,
|
||||
action: Action::Allow as i32,
|
||||
protocol: Protocol::Tcp as i32,
|
||||
stateful: true,
|
||||
rate_limit: 100,
|
||||
burst_limit: 200,
|
||||
..Default::default()
|
||||
};
|
||||
chain.rules.push(security_rule);
|
||||
|
||||
// 3. Low-priority default allow rule for Any
|
||||
let mut default_rule = Rule::default();
|
||||
default_rule.name = "default_allow".to_string();
|
||||
default_rule.priority = 100;
|
||||
default_rule.enabled = true;
|
||||
default_rule.action = Action::Allow as i32;
|
||||
default_rule.protocol = Protocol::Any as i32;
|
||||
let default_rule = Rule {
|
||||
name: "default_allow".to_string(),
|
||||
priority: 100,
|
||||
enabled: true,
|
||||
action: Action::Allow as i32,
|
||||
protocol: Protocol::Any as i32,
|
||||
..Default::default()
|
||||
};
|
||||
chain.rules.push(default_rule);
|
||||
|
||||
acl_v1.chains.push(chain);
|
||||
@@ -1441,15 +1451,16 @@ mod tests {
|
||||
|
||||
// Create a very restrictive rate-limited rule
|
||||
if let Some(ref mut acl_v1) = acl_config.acl_v1 {
|
||||
let mut rule = Rule::default();
|
||||
rule.name = "strict_rate_limit".to_string();
|
||||
rule.priority = 200;
|
||||
rule.enabled = true;
|
||||
rule.action = Action::Allow as i32;
|
||||
rule.protocol = Protocol::Any as i32;
|
||||
rule.rate_limit = 1; // Allow only 1 packet per second
|
||||
rule.burst_limit = 1; // Burst of 1 packet
|
||||
|
||||
let rule = Rule {
|
||||
name: "strict_rate_limit".to_string(),
|
||||
priority: 200,
|
||||
enabled: true,
|
||||
action: Action::Allow as i32,
|
||||
protocol: Protocol::Any as i32,
|
||||
rate_limit: 1, // Allow only 1 packet per second
|
||||
burst_limit: 1, // Burst of 1 packet
|
||||
..Default::default()
|
||||
};
|
||||
acl_v1.chains[0].rules.push(rule);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,12 @@ pub trait Compressor {
|
||||
|
||||
pub struct DefaultCompressor {}
|
||||
|
||||
impl Default for DefaultCompressor {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl DefaultCompressor {
|
||||
pub fn new() -> Self {
|
||||
DefaultCompressor {}
|
||||
@@ -195,11 +201,11 @@ pub mod tests {
|
||||
packet,
|
||||
packet.payload_len()
|
||||
);
|
||||
assert_eq!(packet.peer_manager_header().unwrap().is_compressed(), true);
|
||||
assert!(packet.peer_manager_header().unwrap().is_compressed());
|
||||
|
||||
compressor.decompress(&mut packet).await.unwrap();
|
||||
assert_eq!(packet.payload(), text);
|
||||
assert_eq!(packet.peer_manager_header().unwrap().is_compressed(), false);
|
||||
assert!(!packet.peer_manager_header().unwrap().is_compressed());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -215,10 +221,10 @@ pub mod tests {
|
||||
.compress(&mut packet, CompressorAlgo::ZstdDefault)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(packet.peer_manager_header().unwrap().is_compressed(), false);
|
||||
assert!(!packet.peer_manager_header().unwrap().is_compressed());
|
||||
|
||||
compressor.decompress(&mut packet).await.unwrap();
|
||||
assert_eq!(packet.payload(), text);
|
||||
assert_eq!(packet.peer_manager_header().unwrap().is_compressed(), false);
|
||||
assert!(!packet.peer_manager_header().unwrap().is_compressed());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use std::{
|
||||
hash::Hasher,
|
||||
net::{IpAddr, SocketAddr},
|
||||
path::PathBuf,
|
||||
sync::{Arc, Mutex},
|
||||
u64,
|
||||
};
|
||||
|
||||
use anyhow::Context;
|
||||
@@ -48,7 +48,7 @@ pub fn gen_default_flags() -> Flags {
|
||||
disable_quic_input: false,
|
||||
foreign_relay_bps_limit: u64::MAX,
|
||||
multi_thread_count: 2,
|
||||
encryption_algorithm: "".to_string(), // 空字符串表示使用默认的 AES-GCM
|
||||
encryption_algorithm: "aes-gcm".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ pub trait LoggingConfigLoader {
|
||||
|
||||
pub type NetworkSecretDigest = [u8; 32];
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, Default, Eq, Hash)]
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct NetworkIdentity {
|
||||
pub network_name: String,
|
||||
pub network_secret: Option<String>,
|
||||
@@ -218,27 +218,53 @@ pub struct NetworkIdentity {
|
||||
pub network_secret_digest: Option<NetworkSecretDigest>,
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Hash)]
|
||||
struct NetworkIdentityWithOnlyDigest {
|
||||
network_name: String,
|
||||
network_secret_digest: Option<NetworkSecretDigest>,
|
||||
}
|
||||
|
||||
impl From<NetworkIdentity> for NetworkIdentityWithOnlyDigest {
|
||||
fn from(identity: NetworkIdentity) -> Self {
|
||||
if identity.network_secret_digest.is_some() {
|
||||
Self {
|
||||
network_name: identity.network_name,
|
||||
network_secret_digest: identity.network_secret_digest,
|
||||
}
|
||||
} else if identity.network_secret.is_some() {
|
||||
let mut network_secret_digest = [0u8; 32];
|
||||
generate_digest_from_str(
|
||||
&identity.network_name,
|
||||
identity.network_secret.as_ref().unwrap(),
|
||||
&mut network_secret_digest,
|
||||
);
|
||||
Self {
|
||||
network_name: identity.network_name,
|
||||
network_secret_digest: Some(network_secret_digest),
|
||||
}
|
||||
} else {
|
||||
Self {
|
||||
network_name: identity.network_name,
|
||||
network_secret_digest: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for NetworkIdentity {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
if self.network_name != other.network_name {
|
||||
return false;
|
||||
}
|
||||
let self_with_digest = NetworkIdentityWithOnlyDigest::from(self.clone());
|
||||
let other_with_digest = NetworkIdentityWithOnlyDigest::from(other.clone());
|
||||
self_with_digest == other_with_digest
|
||||
}
|
||||
}
|
||||
|
||||
if self.network_secret.is_some()
|
||||
&& other.network_secret.is_some()
|
||||
&& self.network_secret != other.network_secret
|
||||
{
|
||||
return false;
|
||||
}
|
||||
impl Eq for NetworkIdentity {}
|
||||
|
||||
if self.network_secret_digest.is_some()
|
||||
&& other.network_secret_digest.is_some()
|
||||
&& self.network_secret_digest != other.network_secret_digest
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
impl std::hash::Hash for NetworkIdentity {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
let self_with_digest = NetworkIdentityWithOnlyDigest::from(self.clone());
|
||||
self_with_digest.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,8 +279,10 @@ impl NetworkIdentity {
|
||||
network_secret_digest: Some(network_secret_digest),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default() -> Self {
|
||||
impl Default for NetworkIdentity {
|
||||
fn default() -> Self {
|
||||
Self::new("default".to_string(), "".to_string())
|
||||
}
|
||||
}
|
||||
@@ -328,12 +356,12 @@ impl From<PortForwardConfigPb> for PortForwardConfig {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<PortForwardConfigPb> for PortForwardConfig {
|
||||
fn into(self) -> PortForwardConfigPb {
|
||||
impl From<PortForwardConfig> for PortForwardConfigPb {
|
||||
fn from(val: PortForwardConfig) -> Self {
|
||||
PortForwardConfigPb {
|
||||
bind_addr: Some(self.bind_addr.into()),
|
||||
dst_addr: Some(self.dst_addr.into()),
|
||||
socket_type: match self.proto.to_lowercase().as_str() {
|
||||
bind_addr: Some(val.bind_addr.into()),
|
||||
dst_addr: Some(val.dst_addr.into()),
|
||||
socket_type: match val.proto.to_lowercase().as_str() {
|
||||
"tcp" => SocketType::Tcp as i32,
|
||||
"udp" => SocketType::Udp as i32,
|
||||
_ => SocketType::Tcp as i32,
|
||||
@@ -493,8 +521,7 @@ impl ConfigLoader for TomlConfigLoader {
|
||||
locked_config
|
||||
.ipv4
|
||||
.as_ref()
|
||||
.map(|s| s.parse().ok())
|
||||
.flatten()
|
||||
.and_then(|s| s.parse().ok())
|
||||
.map(|c: cidr::Ipv4Inet| {
|
||||
if c.network_length() == 32 {
|
||||
cidr::Ipv4Inet::new(c.address(), 24).unwrap()
|
||||
@@ -505,28 +532,16 @@ impl ConfigLoader for TomlConfigLoader {
|
||||
}
|
||||
|
||||
fn set_ipv4(&self, addr: Option<cidr::Ipv4Inet>) {
|
||||
self.config.lock().unwrap().ipv4 = if let Some(addr) = addr {
|
||||
Some(addr.to_string())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.config.lock().unwrap().ipv4 = addr.map(|addr| addr.to_string());
|
||||
}
|
||||
|
||||
fn get_ipv6(&self) -> Option<cidr::Ipv6Inet> {
|
||||
let locked_config = self.config.lock().unwrap();
|
||||
locked_config
|
||||
.ipv6
|
||||
.as_ref()
|
||||
.map(|s| s.parse().ok())
|
||||
.flatten()
|
||||
locked_config.ipv6.as_ref().and_then(|s| s.parse().ok())
|
||||
}
|
||||
|
||||
fn set_ipv6(&self, addr: Option<cidr::Ipv6Inet>) {
|
||||
self.config.lock().unwrap().ipv6 = if let Some(addr) = addr {
|
||||
Some(addr.to_string())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.config.lock().unwrap().ipv6 = addr.map(|addr| addr.to_string());
|
||||
}
|
||||
|
||||
fn get_dhcp(&self) -> bool {
|
||||
@@ -600,7 +615,7 @@ impl ConfigLoader for TomlConfigLoader {
|
||||
locked_config.instance_id = Some(id);
|
||||
id
|
||||
} else {
|
||||
locked_config.instance_id.as_ref().unwrap().clone()
|
||||
*locked_config.instance_id.as_ref().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -614,7 +629,7 @@ impl ConfigLoader for TomlConfigLoader {
|
||||
.unwrap()
|
||||
.network_identity
|
||||
.clone()
|
||||
.unwrap_or_else(NetworkIdentity::default)
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn set_network_identity(&self, identity: NetworkIdentity) {
|
||||
|
||||
@@ -8,14 +8,14 @@ macro_rules! define_global_var {
|
||||
#[macro_export]
|
||||
macro_rules! use_global_var {
|
||||
($name:ident) => {
|
||||
crate::common::constants::$name.lock().unwrap().to_owned()
|
||||
$crate::common::constants::$name.lock().unwrap().to_owned()
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! set_global_var {
|
||||
($name:ident, $val:expr) => {
|
||||
*crate::common::constants::$name.lock().unwrap() = $val
|
||||
*$crate::common::constants::$name.lock().unwrap() = $val
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,9 @@ impl<F: FnOnce()> Defer<F> {
|
||||
|
||||
impl<F: FnOnce()> Drop for Defer<F> {
|
||||
fn drop(&mut self) {
|
||||
self.func.take().map(|f| f());
|
||||
if let Some(f) = self.func.take() {
|
||||
f()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,19 +48,15 @@ pub static RESOLVER: Lazy<Arc<Resolver<GenericConnector<TokioRuntimeProvider>>>>
|
||||
|
||||
pub async fn resolve_txt_record(domain_name: &str) -> Result<String, Error> {
|
||||
let r = RESOLVER.clone();
|
||||
let response = r.txt_lookup(domain_name).await.with_context(|| {
|
||||
format!(
|
||||
"txt_lookup failed, domain_name: {}",
|
||||
domain_name.to_string()
|
||||
)
|
||||
})?;
|
||||
let response = r
|
||||
.txt_lookup(domain_name)
|
||||
.await
|
||||
.with_context(|| format!("txt_lookup failed, domain_name: {}", domain_name))?;
|
||||
|
||||
let txt_record = response.iter().next().with_context(|| {
|
||||
format!(
|
||||
"no txt record found, domain_name: {}",
|
||||
domain_name.to_string()
|
||||
)
|
||||
})?;
|
||||
let txt_record = response
|
||||
.iter()
|
||||
.next()
|
||||
.with_context(|| format!("no txt record found, domain_name: {}", domain_name))?;
|
||||
|
||||
let txt_data = String::from_utf8_lossy(&txt_record.txt_data()[0]);
|
||||
tracing::info!(?txt_data, ?domain_name, "get txt record");
|
||||
|
||||
@@ -104,7 +104,7 @@ impl std::fmt::Debug for GlobalCtx {
|
||||
pub type ArcGlobalCtx = std::sync::Arc<GlobalCtx>;
|
||||
|
||||
impl GlobalCtx {
|
||||
pub fn new(config_fs: impl ConfigLoader + 'static + Send + Sync) -> Self {
|
||||
pub fn new(config_fs: impl ConfigLoader + 'static) -> Self {
|
||||
let id = config_fs.get_id();
|
||||
let network = config_fs.get_network_identity();
|
||||
let net_ns = NetNS::new(config_fs.get_netns());
|
||||
@@ -118,9 +118,11 @@ impl GlobalCtx {
|
||||
let proxy_forward_by_system = config_fs.get_flags().proxy_forward_by_system;
|
||||
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;
|
||||
let feature_flags = PeerFeatureFlag {
|
||||
kcp_input: !config_fs.get_flags().disable_kcp_input,
|
||||
no_relay_kcp: config_fs.get_flags().disable_relay_kcp,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
GlobalCtx {
|
||||
inst_name: config_fs.get_inst_name(),
|
||||
@@ -185,7 +187,7 @@ impl GlobalCtx {
|
||||
{
|
||||
Ok(())
|
||||
} else {
|
||||
Err(anyhow::anyhow!("network {} not in whitelist", network_name).into())
|
||||
Err(anyhow::anyhow!("network {} not in whitelist", network_name))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,8 +196,8 @@ impl GlobalCtx {
|
||||
return Some(ret);
|
||||
}
|
||||
let addr = self.config.get_ipv4();
|
||||
self.cached_ipv4.store(addr.clone());
|
||||
return addr;
|
||||
self.cached_ipv4.store(addr);
|
||||
addr
|
||||
}
|
||||
|
||||
pub fn set_ipv4(&self, addr: Option<cidr::Ipv4Inet>) {
|
||||
@@ -208,8 +210,8 @@ impl GlobalCtx {
|
||||
return Some(ret);
|
||||
}
|
||||
let addr = self.config.get_ipv6();
|
||||
self.cached_ipv6.store(addr.clone());
|
||||
return addr;
|
||||
self.cached_ipv6.store(addr);
|
||||
addr
|
||||
}
|
||||
|
||||
pub fn set_ipv6(&self, addr: Option<cidr::Ipv6Inet>) {
|
||||
@@ -376,18 +378,18 @@ pub mod tests {
|
||||
|
||||
let mut subscriber = global_ctx.subscribe();
|
||||
let peer_id = new_peer_id();
|
||||
global_ctx.issue_event(GlobalCtxEvent::PeerAdded(peer_id.clone()));
|
||||
global_ctx.issue_event(GlobalCtxEvent::PeerRemoved(peer_id.clone()));
|
||||
global_ctx.issue_event(GlobalCtxEvent::PeerAdded(peer_id));
|
||||
global_ctx.issue_event(GlobalCtxEvent::PeerRemoved(peer_id));
|
||||
global_ctx.issue_event(GlobalCtxEvent::PeerConnAdded(PeerConnInfo::default()));
|
||||
global_ctx.issue_event(GlobalCtxEvent::PeerConnRemoved(PeerConnInfo::default()));
|
||||
|
||||
assert_eq!(
|
||||
subscriber.recv().await.unwrap(),
|
||||
GlobalCtxEvent::PeerAdded(peer_id.clone())
|
||||
GlobalCtxEvent::PeerAdded(peer_id)
|
||||
);
|
||||
assert_eq!(
|
||||
subscriber.recv().await.unwrap(),
|
||||
GlobalCtxEvent::PeerRemoved(peer_id.clone())
|
||||
GlobalCtxEvent::PeerRemoved(peer_id)
|
||||
);
|
||||
assert_eq!(
|
||||
subscriber.recv().await.unwrap(),
|
||||
@@ -404,7 +406,7 @@ pub mod tests {
|
||||
) -> ArcGlobalCtx {
|
||||
let config_fs = TomlConfigLoader::default();
|
||||
config_fs.set_inst_name(format!("test_{}", config_fs.get_id()));
|
||||
config_fs.set_network_identity(network_identy.unwrap_or(NetworkIdentity::default()));
|
||||
config_fs.set_network_identity(network_identy.unwrap_or_default());
|
||||
|
||||
let ctx = Arc::new(GlobalCtx::new(config_fs));
|
||||
ctx.replace_stun_info_collector(Box::new(MockStunInfoCollector {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
|
||||
mod darwin;
|
||||
#[cfg(any(target_os = "linux"))]
|
||||
#[cfg(target_os = "linux")]
|
||||
mod netlink;
|
||||
#[cfg(target_os = "windows")]
|
||||
mod win;
|
||||
@@ -141,7 +141,7 @@ pub struct DummyIfConfiger {}
|
||||
#[async_trait]
|
||||
impl IfConfiguerTrait for DummyIfConfiger {}
|
||||
|
||||
#[cfg(any(target_os = "linux"))]
|
||||
#[cfg(target_os = "linux")]
|
||||
pub type IfConfiger = netlink::NetlinkIfConfiger;
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
|
||||
|
||||
@@ -85,14 +85,14 @@ fn send_netlink_req_and_wait_one_resp<T: NetlinkDeserializable + NetlinkSerializ
|
||||
match ret.payload {
|
||||
NetlinkPayload::Error(e) => {
|
||||
if e.code == NonZero::new(0) {
|
||||
return Ok(());
|
||||
Ok(())
|
||||
} else {
|
||||
return Err(e.to_io().into());
|
||||
Err(e.to_io().into())
|
||||
}
|
||||
}
|
||||
p => {
|
||||
tracing::error!("Unexpected netlink response: {:?}", p);
|
||||
return Err(anyhow::anyhow!("Unexpected netlink response").into());
|
||||
Err(anyhow::anyhow!("Unexpected netlink response").into())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -263,8 +263,8 @@ impl NetlinkIfConfiger {
|
||||
|
||||
let (address, netmask) = match (address.family(), netmask.family()) {
|
||||
(Some(Inet), Some(Inet)) => (
|
||||
IpAddr::V4(address.as_sockaddr_in().unwrap().ip().into()),
|
||||
IpAddr::V4(netmask.as_sockaddr_in().unwrap().ip().into()),
|
||||
IpAddr::V4(address.as_sockaddr_in().unwrap().ip()),
|
||||
IpAddr::V4(netmask.as_sockaddr_in().unwrap().ip()),
|
||||
),
|
||||
(Some(Inet6), Some(Inet6)) => (
|
||||
IpAddr::V6(address.as_sockaddr_in6().unwrap().ip()),
|
||||
@@ -333,7 +333,7 @@ impl NetlinkIfConfiger {
|
||||
|
||||
let mut resp = Vec::<u8>::new();
|
||||
loop {
|
||||
if resp.len() == 0 {
|
||||
if resp.is_empty() {
|
||||
let (new_resp, _) = s.recv_from_full()?;
|
||||
resp = new_resp;
|
||||
}
|
||||
|
||||
@@ -727,7 +727,7 @@ impl InterfaceLuid {
|
||||
if family == (AF_INET6 as ADDRESS_FAMILY) {
|
||||
// ipv6 mtu must be at least 1280
|
||||
mtu = 1280.max(mtu);
|
||||
}
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/54857292/setipinterfaceentry-returns-error-invalid-parameter
|
||||
row.SitePrefixLength = 0;
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
pub mod luid;
|
||||
pub mod netsh;
|
||||
pub mod types;
|
||||
pub mod luid;
|
||||
@@ -115,4 +115,4 @@ pub fn add_dns_ipv6(if_index: u32, dnses: &[Ipv6Addr]) -> Result<(), String> {
|
||||
}
|
||||
let dnses_str: Vec<String> = dnses.iter().map(|addr| addr.to_string()).collect();
|
||||
add_dns(AF_INET6 as _, if_index, &dnses_str)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,4 +100,4 @@ pub fn u16_ptr_to_string(ptr: *const u16) -> String {
|
||||
let slice = unsafe { std::slice::from_raw_parts(ptr, len) };
|
||||
|
||||
String::from_utf16_lossy(slice)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,8 +140,8 @@ pub fn get_machine_id() -> uuid::Uuid {
|
||||
)))]
|
||||
let gen_mid = None;
|
||||
|
||||
if gen_mid.is_some() {
|
||||
return gen_mid.unwrap();
|
||||
if let Some(mid) = gen_mid {
|
||||
return mid;
|
||||
}
|
||||
|
||||
let gen_mid = uuid::Uuid::new_v4();
|
||||
|
||||
@@ -34,13 +34,12 @@ impl NetNSGuard {
|
||||
return;
|
||||
}
|
||||
|
||||
let ns_path: String;
|
||||
let name = name.unwrap();
|
||||
if name == ROOT_NETNS_NAME {
|
||||
ns_path = "/proc/1/ns/net".to_string();
|
||||
let ns_path: String = if name == ROOT_NETNS_NAME {
|
||||
"/proc/1/ns/net".to_string()
|
||||
} else {
|
||||
ns_path = format!("/var/run/netns/{}", name);
|
||||
}
|
||||
format!("/var/run/netns/{}", name)
|
||||
};
|
||||
|
||||
let ns = std::fs::File::open(ns_path).unwrap();
|
||||
tracing::info!(
|
||||
|
||||
@@ -211,7 +211,7 @@ impl IPCollector {
|
||||
cached_ip_list.read().await.public_ipv6
|
||||
);
|
||||
|
||||
let sleep_sec = if !cached_ip_list.read().await.public_ipv4.is_none() {
|
||||
let sleep_sec = if cached_ip_list.read().await.public_ipv4.is_some() {
|
||||
CACHED_IP_LIST_TIMEOUT_SEC
|
||||
} else {
|
||||
3
|
||||
@@ -252,14 +252,11 @@ impl IPCollector {
|
||||
for iface in ifaces {
|
||||
for ip in iface.ips {
|
||||
let ip: std::net::IpAddr = ip.ip();
|
||||
match ip {
|
||||
std::net::IpAddr::V4(v4) => {
|
||||
if ip.is_loopback() || ip.is_multicast() {
|
||||
continue;
|
||||
}
|
||||
ret.interface_ipv4s.push(v4.into());
|
||||
if let std::net::IpAddr::V4(v4) = ip {
|
||||
if ip.is_loopback() || ip.is_multicast() {
|
||||
continue;
|
||||
}
|
||||
_ => {}
|
||||
ret.interface_ipv4s.push(v4.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -269,14 +266,11 @@ impl IPCollector {
|
||||
for iface in ifaces {
|
||||
for ip in iface.ips {
|
||||
let ip: std::net::IpAddr = ip.ip();
|
||||
match ip {
|
||||
std::net::IpAddr::V6(v6) => {
|
||||
if v6.is_multicast() || v6.is_loopback() || v6.is_unicast_link_local() {
|
||||
continue;
|
||||
}
|
||||
ret.interface_ipv6s.push(v6.into());
|
||||
if let std::net::IpAddr::V6(v6) = ip {
|
||||
if v6.is_multicast() || v6.is_loopback() || v6.is_unicast_link_local() {
|
||||
continue;
|
||||
}
|
||||
_ => {}
|
||||
ret.interface_ipv6s.push(v6.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,6 +277,12 @@ pub struct UnsafeCounter {
|
||||
value: UnsafeCell<u64>,
|
||||
}
|
||||
|
||||
impl Default for UnsafeCounter {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl UnsafeCounter {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
@@ -396,14 +402,15 @@ impl MetricKey {
|
||||
fn new(name: MetricName, labels: LabelSet) -> Self {
|
||||
Self { name, labels }
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate a string representation for this metric key
|
||||
fn to_string(&self) -> String {
|
||||
impl fmt::Display for MetricKey {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let label_str = self.labels.to_key();
|
||||
if label_str.is_empty() {
|
||||
self.name.to_string()
|
||||
f.write_str(self.name.to_string().as_str())
|
||||
} else {
|
||||
format!("{}[{}]", self.name, label_str)
|
||||
f.write_str(format!("{}[{}]", self.name, label_str).as_str())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+23
-28
@@ -282,9 +282,7 @@ impl StunClient {
|
||||
.with_context(|| "encode stun message")?;
|
||||
tids.push(tid);
|
||||
tracing::trace!(?message, ?msg, tid, "send stun request");
|
||||
self.socket
|
||||
.send_to(msg.as_slice().into(), &stun_host)
|
||||
.await?;
|
||||
self.socket.send_to(msg.as_slice(), &stun_host).await?;
|
||||
}
|
||||
|
||||
let now = Instant::now();
|
||||
@@ -372,7 +370,7 @@ impl StunClientBuilder {
|
||||
|
||||
pub async fn stop(&mut self) {
|
||||
self.task_set.abort_all();
|
||||
while let Some(_) = self.task_set.join_next().await {}
|
||||
while self.task_set.join_next().await.is_some() {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,7 +415,7 @@ impl UdpNatTypeDetectResult {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
false
|
||||
}
|
||||
|
||||
fn is_pat(&self) -> bool {
|
||||
@@ -457,16 +455,16 @@ impl UdpNatTypeDetectResult {
|
||||
if self.is_cone() {
|
||||
if self.has_ip_changed_resp() {
|
||||
if self.is_open_internet() {
|
||||
return NatType::OpenInternet;
|
||||
NatType::OpenInternet
|
||||
} else if self.is_pat() {
|
||||
return NatType::NoPat;
|
||||
NatType::NoPat
|
||||
} else {
|
||||
return NatType::FullCone;
|
||||
NatType::FullCone
|
||||
}
|
||||
} else if self.has_port_changed_resp() {
|
||||
return NatType::Restricted;
|
||||
NatType::Restricted
|
||||
} else {
|
||||
return NatType::PortRestricted;
|
||||
NatType::PortRestricted
|
||||
}
|
||||
} else if !self.stun_resps.is_empty() {
|
||||
if self.public_ips().len() != 1
|
||||
@@ -480,7 +478,7 @@ impl UdpNatTypeDetectResult {
|
||||
.mapped_socket_addr
|
||||
.is_none()
|
||||
{
|
||||
return NatType::Symmetric;
|
||||
NatType::Symmetric
|
||||
} else {
|
||||
let extra_bind_test = self.extra_bind_test.as_ref().unwrap();
|
||||
let extra_port = extra_bind_test.mapped_socket_addr.unwrap().port();
|
||||
@@ -488,15 +486,15 @@ impl UdpNatTypeDetectResult {
|
||||
let max_port_diff = extra_port.saturating_sub(self.max_port());
|
||||
let min_port_diff = self.min_port().saturating_sub(extra_port);
|
||||
if max_port_diff != 0 && max_port_diff < 100 {
|
||||
return NatType::SymmetricEasyInc;
|
||||
NatType::SymmetricEasyInc
|
||||
} else if min_port_diff != 0 && min_port_diff < 100 {
|
||||
return NatType::SymmetricEasyDec;
|
||||
NatType::SymmetricEasyDec
|
||||
} else {
|
||||
return NatType::Symmetric;
|
||||
NatType::Symmetric
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return NatType::Unknown;
|
||||
NatType::Unknown
|
||||
}
|
||||
}
|
||||
|
||||
@@ -679,7 +677,7 @@ impl StunInfoCollectorTrait for StunInfoCollector {
|
||||
.unwrap()
|
||||
.clone()
|
||||
.map(|x| x.collect_available_stun_server())
|
||||
.unwrap_or(vec![]);
|
||||
.unwrap_or_default();
|
||||
|
||||
if stun_servers.is_empty() {
|
||||
let mut host_resolver =
|
||||
@@ -740,7 +738,7 @@ impl StunInfoCollector {
|
||||
pub fn get_default_servers() -> Vec<String> {
|
||||
// NOTICE: we may need to choose stun stun server based on geo location
|
||||
// stun server cross nation may return a external ip address with high latency and loss rate
|
||||
vec![
|
||||
[
|
||||
"txt:stun.easytier.cn",
|
||||
"stun.miwifi.com",
|
||||
"stun.chat.bilibili.com",
|
||||
@@ -752,16 +750,16 @@ impl StunInfoCollector {
|
||||
}
|
||||
|
||||
pub fn get_default_servers_v6() -> Vec<String> {
|
||||
vec!["txt:stun-v6.easytier.cn"]
|
||||
["txt:stun-v6.easytier.cn"]
|
||||
.iter()
|
||||
.map(|x| x.to_string())
|
||||
.collect()
|
||||
}
|
||||
|
||||
async fn get_public_ipv6(servers: &Vec<String>) -> Option<Ipv6Addr> {
|
||||
async fn get_public_ipv6(servers: &[String]) -> Option<Ipv6Addr> {
|
||||
let mut ips = HostResolverIter::new(servers.to_vec(), 10, true);
|
||||
while let Some(ip) = ips.next().await {
|
||||
let Ok(udp_socket) = UdpSocket::bind(format!("[::]:0")).await else {
|
||||
let Ok(udp_socket) = UdpSocket::bind("[::]:0".to_string()).await else {
|
||||
break;
|
||||
};
|
||||
let udp = Arc::new(udp_socket);
|
||||
@@ -770,11 +768,8 @@ impl StunInfoCollector {
|
||||
.bind_request(false, false)
|
||||
.await;
|
||||
tracing::debug!(?ret, "finish ipv6 udp nat type detect");
|
||||
match ret.map(|x| x.mapped_socket_addr.map(|x| x.ip())) {
|
||||
Ok(Some(IpAddr::V6(v6))) => {
|
||||
return Some(v6);
|
||||
}
|
||||
_ => {}
|
||||
if let Ok(Some(IpAddr::V6(v6))) = ret.map(|x| x.mapped_socket_addr.map(|x| x.ip())) {
|
||||
return Some(v6);
|
||||
}
|
||||
}
|
||||
None
|
||||
@@ -854,9 +849,9 @@ impl StunInfoCollector {
|
||||
self.tasks.lock().unwrap().spawn(async move {
|
||||
loop {
|
||||
let servers = stun_servers.read().unwrap().clone();
|
||||
Self::get_public_ipv6(&servers)
|
||||
.await
|
||||
.map(|x| stored_ipv6.store(Some(x)));
|
||||
if let Some(x) = Self::get_public_ipv6(&servers).await {
|
||||
stored_ipv6.store(Some(x))
|
||||
}
|
||||
|
||||
let sleep_sec = if stored_ipv6.load().is_none() {
|
||||
60
|
||||
|
||||
@@ -34,7 +34,7 @@ impl From<LimiterConfig> for BucketConfig {
|
||||
.unwrap_or(Duration::from_millis(10));
|
||||
BucketConfig {
|
||||
capacity: burst_rate * fill_rate,
|
||||
fill_rate: fill_rate,
|
||||
fill_rate,
|
||||
refill_interval,
|
||||
}
|
||||
}
|
||||
@@ -162,6 +162,12 @@ pub struct TokenBucketManager {
|
||||
retain_task: ScopedTask<()>,
|
||||
}
|
||||
|
||||
impl Default for TokenBucketManager {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl TokenBucketManager {
|
||||
/// Creates a new TokenBucketManager
|
||||
pub fn new() -> Self {
|
||||
@@ -318,7 +324,7 @@ mod tests {
|
||||
// Should have accumulated about 100 tokens (10,000 tokens/s * 0.001s)
|
||||
let tokens = bucket.available_tokens.load(Ordering::Relaxed);
|
||||
assert!(
|
||||
tokens >= 100 && tokens <= 200,
|
||||
(100..=200).contains(&tokens),
|
||||
"Unexpected token count: {}",
|
||||
tokens
|
||||
);
|
||||
@@ -355,8 +361,7 @@ mod tests {
|
||||
.list_foreign_networks()
|
||||
.await
|
||||
.foreign_networks
|
||||
.len()
|
||||
== 0
|
||||
.is_empty()
|
||||
},
|
||||
Duration::from_secs(5),
|
||||
)
|
||||
@@ -370,8 +375,7 @@ mod tests {
|
||||
.get_global_ctx()
|
||||
.token_bucket_manager()
|
||||
.buckets
|
||||
.len()
|
||||
== 0
|
||||
.is_empty()
|
||||
},
|
||||
Duration::from_secs(10),
|
||||
)
|
||||
|
||||
@@ -180,16 +180,13 @@ impl DirectConnectorManagerData {
|
||||
// ask remote to send v6 hole punch packet
|
||||
// and no matter what the result is, continue to connect
|
||||
let _ = self
|
||||
.remote_send_v6_hole_punch_packet(dst_peer_id, &local_socket, &remote_url)
|
||||
.remote_send_v6_hole_punch_packet(dst_peer_id, &local_socket, remote_url)
|
||||
.await;
|
||||
|
||||
let udp_connector = UdpTunnelConnector::new(remote_url.clone());
|
||||
let remote_addr = super::check_scheme_and_get_socket_addr::<SocketAddr>(
|
||||
&remote_url,
|
||||
"udp",
|
||||
IpVersion::V6,
|
||||
)
|
||||
.await?;
|
||||
let remote_addr =
|
||||
super::check_scheme_and_get_socket_addr::<SocketAddr>(remote_url, "udp", IpVersion::V6)
|
||||
.await?;
|
||||
let ret = udp_connector
|
||||
.try_connect_with_socket(local_socket, remote_addr)
|
||||
.await?;
|
||||
@@ -233,8 +230,8 @@ impl DirectConnectorManagerData {
|
||||
dst_peer_id: PeerId,
|
||||
addr: String,
|
||||
) -> Result<(), Error> {
|
||||
let mut rand_gen = rand::rngs::OsRng::default();
|
||||
let backoff_ms = vec![1000, 2000, 4000];
|
||||
let mut rand_gen = rand::rngs::OsRng;
|
||||
let backoff_ms = [1000, 2000, 4000];
|
||||
let mut backoff_idx = 0;
|
||||
|
||||
tracing::debug!(?dst_peer_id, ?addr, "try_connect_to_ip start");
|
||||
@@ -243,10 +240,7 @@ impl DirectConnectorManagerData {
|
||||
|
||||
if self
|
||||
.dst_listener_blacklist
|
||||
.contains(&DstListenerUrlBlackListItem(
|
||||
dst_peer_id.clone(),
|
||||
addr.clone(),
|
||||
))
|
||||
.contains(&DstListenerUrlBlackListItem(dst_peer_id, addr.clone()))
|
||||
{
|
||||
return Err(Error::UrlInBlacklist);
|
||||
}
|
||||
@@ -281,7 +275,7 @@ impl DirectConnectorManagerData {
|
||||
continue;
|
||||
} else {
|
||||
self.dst_listener_blacklist.insert(
|
||||
DstListenerUrlBlackListItem(dst_peer_id.clone(), addr),
|
||||
DstListenerUrlBlackListItem(dst_peer_id, addr),
|
||||
(),
|
||||
std::time::Duration::from_secs(DIRECT_CONNECTOR_BLACKLIST_TIMEOUT_SEC),
|
||||
);
|
||||
@@ -315,7 +309,7 @@ impl DirectConnectorManagerData {
|
||||
if addr.set_host(Some(ip.to_string().as_str())).is_ok() {
|
||||
tasks.spawn(Self::try_connect_to_ip(
|
||||
self.clone(),
|
||||
dst_peer_id.clone(),
|
||||
dst_peer_id,
|
||||
addr.to_string(),
|
||||
));
|
||||
} else {
|
||||
@@ -330,7 +324,7 @@ impl DirectConnectorManagerData {
|
||||
} else if !s_addr.ip().is_loopback() || TESTING.load(Ordering::Relaxed) {
|
||||
tasks.spawn(Self::try_connect_to_ip(
|
||||
self.clone(),
|
||||
dst_peer_id.clone(),
|
||||
dst_peer_id,
|
||||
listener.to_string(),
|
||||
));
|
||||
}
|
||||
@@ -355,13 +349,10 @@ impl DirectConnectorManagerData {
|
||||
.iter()
|
||||
.for_each(|ip| {
|
||||
let mut addr = (*listener).clone();
|
||||
if addr
|
||||
.set_host(Some(format!("[{}]", ip.to_string()).as_str()))
|
||||
.is_ok()
|
||||
{
|
||||
if addr.set_host(Some(format!("[{}]", ip).as_str())).is_ok() {
|
||||
tasks.spawn(Self::try_connect_to_ip(
|
||||
self.clone(),
|
||||
dst_peer_id.clone(),
|
||||
dst_peer_id,
|
||||
addr.to_string(),
|
||||
));
|
||||
} else {
|
||||
@@ -376,7 +367,7 @@ impl DirectConnectorManagerData {
|
||||
} else if !s_addr.ip().is_loopback() || TESTING.load(Ordering::Relaxed) {
|
||||
tasks.spawn(Self::try_connect_to_ip(
|
||||
self.clone(),
|
||||
dst_peer_id.clone(),
|
||||
dst_peer_id,
|
||||
listener.to_string(),
|
||||
));
|
||||
}
|
||||
@@ -436,13 +427,8 @@ impl DirectConnectorManagerData {
|
||||
}
|
||||
|
||||
tracing::debug!("try direct connect to peer with listener: {}", listener);
|
||||
self.spawn_direct_connect_task(
|
||||
dst_peer_id.clone(),
|
||||
&ip_list,
|
||||
&listener,
|
||||
&mut tasks,
|
||||
)
|
||||
.await;
|
||||
self.spawn_direct_connect_task(dst_peer_id, &ip_list, listener, &mut tasks)
|
||||
.await;
|
||||
|
||||
listener_list.push(listener.clone().to_string());
|
||||
available_listeners.pop();
|
||||
|
||||
@@ -124,11 +124,11 @@ impl DNSTunnelConnector {
|
||||
let responses = responses.clone();
|
||||
async move {
|
||||
let response = resolver.srv_lookup(srv_domain).await.with_context(|| {
|
||||
format!("srv_lookup failed, srv_domain: {}", srv_domain.to_string())
|
||||
format!("srv_lookup failed, srv_domain: {}", srv_domain)
|
||||
})?;
|
||||
tracing::info!(?response, ?srv_domain, "srv_lookup response");
|
||||
for record in response.iter() {
|
||||
let parsed_record = Self::handle_one_srv_record(record, &protocol);
|
||||
let parsed_record = Self::handle_one_srv_record(record, protocol);
|
||||
tracing::info!(?parsed_record, ?srv_domain, "parsed_record");
|
||||
if parsed_record.is_err() {
|
||||
eprintln!(
|
||||
@@ -153,8 +153,7 @@ impl DNSTunnelConnector {
|
||||
let url = weighted_choice(srv_records.as_slice()).with_context(|| {
|
||||
format!(
|
||||
"failed to choose a srv record, domain_name: {}, srv_records: {:?}",
|
||||
domain_name.to_string(),
|
||||
srv_records
|
||||
domain_name, srv_records
|
||||
)
|
||||
})?;
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ impl HttpTunnelConnector {
|
||||
tracing::info!("try to create connector by url: {}", query[0]);
|
||||
self.redirect_type = HttpRedirectType::RedirectToQuery;
|
||||
return create_connector_by_url(
|
||||
&query[0].to_string(),
|
||||
query[0].as_ref(),
|
||||
&self.global_ctx,
|
||||
self.ip_version,
|
||||
)
|
||||
@@ -193,7 +193,7 @@ impl HttpTunnelConnector {
|
||||
.ok_or_else(|| Error::InvalidUrl("no redirect address found".to_string()))?;
|
||||
let new_url = url::Url::parse(redirect_url.as_str())
|
||||
.with_context(|| format!("parsing redirect url failed. url: {}", redirect_url))?;
|
||||
return self.handle_302_redirect(new_url, &redirect_url).await;
|
||||
return self.handle_302_redirect(new_url, redirect_url).await;
|
||||
} else if res.status_code().is_success() {
|
||||
return self.handle_200_success(&body).await;
|
||||
} else {
|
||||
|
||||
@@ -131,7 +131,7 @@ impl ManualConnectorManager {
|
||||
.data
|
||||
.connectors
|
||||
.iter()
|
||||
.map(|x| x.key().clone().into())
|
||||
.map(|x| x.key().clone())
|
||||
.collect();
|
||||
|
||||
let dead_urls: BTreeSet<String> = Self::collect_dead_conns(self.data.clone())
|
||||
@@ -155,12 +155,8 @@ impl ManualConnectorManager {
|
||||
);
|
||||
}
|
||||
|
||||
let reconnecting_urls: BTreeSet<String> = self
|
||||
.data
|
||||
.reconnecting
|
||||
.iter()
|
||||
.map(|x| x.clone().into())
|
||||
.collect();
|
||||
let reconnecting_urls: BTreeSet<String> =
|
||||
self.data.reconnecting.iter().map(|x| x.clone()).collect();
|
||||
|
||||
for conn_url in reconnecting_urls {
|
||||
ret.insert(
|
||||
@@ -282,7 +278,7 @@ impl ManualConnectorManager {
|
||||
let remove_later = DashSet::new();
|
||||
for it in data.removed_conn_urls.iter() {
|
||||
let url = it.key();
|
||||
if let Some(_) = data.connectors.remove(url) {
|
||||
if data.connectors.remove(url).is_some() {
|
||||
tracing::warn!("connector: {}, removed", url);
|
||||
continue;
|
||||
} else if data.reconnecting.contains(url) {
|
||||
@@ -301,11 +297,7 @@ impl ManualConnectorManager {
|
||||
|
||||
async fn collect_dead_conns(data: Arc<ConnectorManagerData>) -> BTreeSet<String> {
|
||||
Self::handle_remove_connector(data.clone());
|
||||
let all_urls: BTreeSet<String> = data
|
||||
.connectors
|
||||
.iter()
|
||||
.map(|x| x.key().clone().into())
|
||||
.collect();
|
||||
let all_urls: BTreeSet<String> = data.connectors.iter().map(|x| x.key().clone()).collect();
|
||||
let mut ret = BTreeSet::new();
|
||||
for url in all_urls.iter() {
|
||||
if !data.alive_conn_urls.contains(url) {
|
||||
@@ -400,21 +392,28 @@ impl ManualConnectorManager {
|
||||
.await;
|
||||
tracing::info!("reconnect: {} done, ret: {:?}", dead_url, ret);
|
||||
|
||||
if ret.is_ok() && ret.as_ref().unwrap().is_ok() {
|
||||
reconn_ret = ret.unwrap();
|
||||
break;
|
||||
} else {
|
||||
if ret.is_err() {
|
||||
reconn_ret = Err(ret.unwrap_err().into());
|
||||
} else if ret.as_ref().unwrap().is_err() {
|
||||
reconn_ret = Err(ret.unwrap().unwrap_err());
|
||||
match ret {
|
||||
Ok(Ok(_)) => {
|
||||
// 外层和内层都成功:解包并跳出
|
||||
reconn_ret = ret.unwrap();
|
||||
break;
|
||||
}
|
||||
Ok(Err(e)) => {
|
||||
// 外层成功,内层失败
|
||||
reconn_ret = Err(e);
|
||||
}
|
||||
Err(e) => {
|
||||
// 外层失败
|
||||
reconn_ret = Err(e.into());
|
||||
}
|
||||
data.global_ctx.issue_event(GlobalCtxEvent::ConnectError(
|
||||
dead_url.clone(),
|
||||
format!("{:?}", ip_version),
|
||||
format!("{:?}", reconn_ret),
|
||||
));
|
||||
}
|
||||
|
||||
// 发送事件(只有在未 break 时才执行)
|
||||
data.global_ctx.issue_event(GlobalCtxEvent::ConnectError(
|
||||
dead_url.clone(),
|
||||
format!("{:?}", ip_version),
|
||||
format!("{:?}", reconn_ret),
|
||||
));
|
||||
}
|
||||
|
||||
reconn_ret
|
||||
|
||||
@@ -389,7 +389,7 @@ pub mod tests {
|
||||
let udp1 = Arc::new(UdpSocket::bind("0.0.0.0:40164").await.unwrap());
|
||||
// 144 - DST_PORT_OFFSET = 124
|
||||
let udp2 = Arc::new(UdpSocket::bind("0.0.0.0:40124").await.unwrap());
|
||||
let udps = vec![udp1, udp2];
|
||||
let udps = [udp1, udp2];
|
||||
|
||||
let counter = Arc::new(AtomicU32::new(0));
|
||||
|
||||
|
||||
@@ -67,9 +67,9 @@ impl From<NatType> for UdpNatType {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<NatType> for UdpNatType {
|
||||
fn into(self) -> NatType {
|
||||
match self {
|
||||
impl From<UdpNatType> for NatType {
|
||||
fn from(val: UdpNatType) -> Self {
|
||||
match val {
|
||||
UdpNatType::Unknown => NatType::Unknown,
|
||||
UdpNatType::Open(nat_type) => nat_type,
|
||||
UdpNatType::Cone(nat_type) => nat_type,
|
||||
@@ -249,7 +249,7 @@ impl UdpSocketArray {
|
||||
tracing::info!(?addr, ?tid, "got hole punching packet with intreast tid");
|
||||
tid_to_socket
|
||||
.entry(tid)
|
||||
.or_insert_with(Vec::new)
|
||||
.or_default()
|
||||
.push(PunchedUdpSocket {
|
||||
socket: socket.clone(),
|
||||
tid,
|
||||
@@ -556,7 +556,7 @@ impl PunchHoleServerCommon {
|
||||
|
||||
#[tracing::instrument(err, ret(level=Level::DEBUG), skip(ports))]
|
||||
pub(crate) async fn send_symmetric_hole_punch_packet(
|
||||
ports: &Vec<u16>,
|
||||
ports: &[u16],
|
||||
udp: Arc<UdpSocket>,
|
||||
transaction_id: u32,
|
||||
public_ips: &Vec<Ipv4Addr>,
|
||||
@@ -628,5 +628,5 @@ pub(crate) async fn try_connect_with_socket(
|
||||
connector
|
||||
.try_connect_with_socket(socket, remote_mapped_addr)
|
||||
.await
|
||||
.map_err(|e| Error::from(e))
|
||||
.map_err(Error::from)
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ impl PunchConeHoleClient {
|
||||
udp_array
|
||||
.send_with_all(
|
||||
&new_hole_punch_packet(tid, HOLE_PUNCH_PACKET_BODY_LEN).into_bytes(),
|
||||
remote_mapped_addr.clone().into(),
|
||||
remote_mapped_addr.into(),
|
||||
)
|
||||
.await
|
||||
.with_context(|| "failed to send hole punch packet from local")
|
||||
@@ -188,7 +188,7 @@ impl PunchConeHoleClient {
|
||||
..Default::default()
|
||||
},
|
||||
SendPunchPacketConeRequest {
|
||||
listener_mapped_addr: Some(remote_mapped_addr.into()),
|
||||
listener_mapped_addr: Some(remote_mapped_addr),
|
||||
dest_addr: Some(local_mapped_addr.into()),
|
||||
transaction_id: tid,
|
||||
packet_count_per_batch: 2,
|
||||
|
||||
@@ -39,7 +39,7 @@ pub(crate) mod cone;
|
||||
pub(crate) mod sym_to_cone;
|
||||
|
||||
// sym punch should be serialized
|
||||
static SYM_PUNCH_LOCK: Lazy<DashMap<PeerId, Arc<Mutex<()>>>> = Lazy::new(|| DashMap::new());
|
||||
static SYM_PUNCH_LOCK: Lazy<DashMap<PeerId, Arc<Mutex<()>>>> = Lazy::new(DashMap::new);
|
||||
pub static RUN_TESTING: Lazy<AtomicBool> = Lazy::new(|| AtomicBool::new(false));
|
||||
|
||||
// Blacklist timeout in seconds
|
||||
@@ -223,7 +223,7 @@ impl UdpHoePunchConnectorData {
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn handle_punch_result(
|
||||
self: &Self,
|
||||
&self,
|
||||
ret: Result<Option<Box<dyn Tunnel>>, Error>,
|
||||
backoff: Option<&mut BackOff>,
|
||||
round: Option<&mut u32>,
|
||||
@@ -236,10 +236,8 @@ impl UdpHoePunchConnectorData {
|
||||
if let Some(round) = round {
|
||||
*round = round.saturating_sub(1);
|
||||
}
|
||||
} else {
|
||||
if let Some(round) = round {
|
||||
*round += 1;
|
||||
}
|
||||
} else if let Some(round) = round {
|
||||
*round += 1;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -464,7 +462,7 @@ impl PeerTaskLauncher for UdpHolePunchPeerTaskLauncher {
|
||||
}
|
||||
|
||||
let conns = data.peer_mgr.list_peer_conns(peer_id).await;
|
||||
if conns.is_some() && conns.unwrap().len() > 0 {
|
||||
if conns.is_some() && !conns.unwrap().is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,9 +80,9 @@ impl PunchSymToConeHoleServer {
|
||||
let public_ips = request
|
||||
.public_ips
|
||||
.into_iter()
|
||||
.map(|ip| std::net::Ipv4Addr::from(ip))
|
||||
.map(std::net::Ipv4Addr::from)
|
||||
.collect::<Vec<_>>();
|
||||
if public_ips.len() == 0 {
|
||||
if public_ips.is_empty() {
|
||||
tracing::warn!("send_punch_packet_easy_sym got zero len public ip");
|
||||
return Err(
|
||||
anyhow::anyhow!("send_punch_packet_easy_sym got zero len public ip").into(),
|
||||
@@ -158,9 +158,9 @@ impl PunchSymToConeHoleServer {
|
||||
let public_ips = request
|
||||
.public_ips
|
||||
.into_iter()
|
||||
.map(|ip| std::net::Ipv4Addr::from(ip))
|
||||
.map(std::net::Ipv4Addr::from)
|
||||
.collect::<Vec<_>>();
|
||||
if public_ips.len() == 0 {
|
||||
if public_ips.is_empty() {
|
||||
tracing::warn!("try_punch_symmetric got zero len public ip");
|
||||
return Err(anyhow::anyhow!("try_punch_symmetric got zero len public ip").into());
|
||||
}
|
||||
@@ -281,7 +281,7 @@ impl PunchSymToConeHoleClient {
|
||||
return;
|
||||
};
|
||||
let req = SendPunchPacketEasySymRequest {
|
||||
listener_mapped_addr: remote_mapped_addr.clone().into(),
|
||||
listener_mapped_addr: remote_mapped_addr.into(),
|
||||
public_ips: public_ips.clone().into_iter().map(|x| x.into()).collect(),
|
||||
transaction_id: tid,
|
||||
base_port_num: base_port_for_easy_sym.unwrap() as u32,
|
||||
@@ -313,7 +313,7 @@ impl PunchSymToConeHoleClient {
|
||||
port_index: u32,
|
||||
) -> Option<u32> {
|
||||
let req = SendPunchPacketHardSymRequest {
|
||||
listener_mapped_addr: remote_mapped_addr.clone().into(),
|
||||
listener_mapped_addr: remote_mapped_addr.into(),
|
||||
public_ips: public_ips.clone().into_iter().map(|x| x.into()).collect(),
|
||||
transaction_id: tid,
|
||||
round,
|
||||
@@ -333,9 +333,9 @@ impl PunchSymToConeHoleClient {
|
||||
{
|
||||
Err(e) => {
|
||||
tracing::error!(?e, "failed to send punch packet for hard sym");
|
||||
return None;
|
||||
None
|
||||
}
|
||||
Ok(resp) => return Some(resp.next_port_index),
|
||||
Ok(resp) => Some(resp.next_port_index),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,7 +366,7 @@ impl PunchSymToConeHoleClient {
|
||||
let mut finish_time: Option<Instant> = None;
|
||||
while finish_time.is_none() || finish_time.as_ref().unwrap().elapsed().as_millis() < 1000 {
|
||||
udp_array
|
||||
.send_with_all(&packet, remote_mapped_addr.into())
|
||||
.send_with_all(packet, remote_mapped_addr.into())
|
||||
.await?;
|
||||
|
||||
tokio::time::sleep(Duration::from_millis(200)).await;
|
||||
@@ -484,7 +484,7 @@ impl PunchSymToConeHoleClient {
|
||||
rpc_stub,
|
||||
base_port_for_easy_sym,
|
||||
my_nat_info,
|
||||
remote_mapped_addr.clone(),
|
||||
remote_mapped_addr,
|
||||
public_ips.clone(),
|
||||
tid,
|
||||
))
|
||||
@@ -494,7 +494,7 @@ impl PunchSymToConeHoleClient {
|
||||
&udp_array,
|
||||
&packet,
|
||||
tid,
|
||||
remote_mapped_addr.clone(),
|
||||
remote_mapped_addr,
|
||||
&scoped_punch_task,
|
||||
)
|
||||
.await?;
|
||||
@@ -510,7 +510,7 @@ impl PunchSymToConeHoleClient {
|
||||
let scoped_punch_task: ScopedTask<Option<u32>> =
|
||||
tokio::spawn(Self::remote_send_hole_punch_packet_random(
|
||||
rpc_stub,
|
||||
remote_mapped_addr.clone(),
|
||||
remote_mapped_addr,
|
||||
public_ips.clone(),
|
||||
tid,
|
||||
round,
|
||||
@@ -522,7 +522,7 @@ impl PunchSymToConeHoleClient {
|
||||
&udp_array,
|
||||
&packet,
|
||||
tid,
|
||||
remote_mapped_addr.clone(),
|
||||
remote_mapped_addr,
|
||||
&scoped_punch_task,
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -4,7 +4,6 @@ use std::{
|
||||
net::{IpAddr, SocketAddr},
|
||||
path::PathBuf,
|
||||
str::FromStr,
|
||||
sync::Mutex,
|
||||
time::Duration,
|
||||
vec,
|
||||
};
|
||||
@@ -30,15 +29,16 @@ use easytier::{
|
||||
cli::{
|
||||
list_peer_route_pair, AclManageRpc, AclManageRpcClientFactory, AddPortForwardRequest,
|
||||
ConnectorManageRpc, ConnectorManageRpcClientFactory, DumpRouteRequest,
|
||||
GetAclStatsRequest, GetPrometheusStatsRequest, GetStatsRequest, GetVpnPortalInfoRequest, GetWhitelistRequest, ListConnectorRequest,
|
||||
GetAclStatsRequest, GetPrometheusStatsRequest, GetStatsRequest,
|
||||
GetVpnPortalInfoRequest, GetWhitelistRequest, ListConnectorRequest,
|
||||
ListForeignNetworkRequest, ListGlobalForeignNetworkRequest, ListMappedListenerRequest,
|
||||
ListPeerRequest, ListPeerResponse, ListPortForwardRequest, ListRouteRequest,
|
||||
ListRouteResponse, ManageMappedListenerRequest, MappedListenerManageAction,
|
||||
MappedListenerManageRpc, MappedListenerManageRpcClientFactory, NodeInfo, PeerManageRpc,
|
||||
PeerManageRpcClientFactory, PortForwardManageRpc, PortForwardManageRpcClientFactory,
|
||||
RemovePortForwardRequest, SetWhitelistRequest, ShowNodeInfoRequest, StatsRpc, StatsRpcClientFactory, TcpProxyEntryState,
|
||||
TcpProxyEntryTransportType, TcpProxyRpc, TcpProxyRpcClientFactory, VpnPortalRpc,
|
||||
VpnPortalRpcClientFactory,
|
||||
RemovePortForwardRequest, SetWhitelistRequest, ShowNodeInfoRequest, StatsRpc,
|
||||
StatsRpcClientFactory, TcpProxyEntryState, TcpProxyEntryTransportType, TcpProxyRpc,
|
||||
TcpProxyRpcClientFactory, VpnPortalRpc, VpnPortalRpcClientFactory,
|
||||
},
|
||||
common::{NatType, SocketType},
|
||||
peer_rpc::{GetGlobalPeerMapRequest, PeerCenterRpc, PeerCenterRpcClientFactory},
|
||||
@@ -325,7 +325,7 @@ struct InstallArgs {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
struct CommandHandler<'a> {
|
||||
client: Mutex<RpcClient>,
|
||||
client: tokio::sync::Mutex<RpcClient>,
|
||||
verbose: bool,
|
||||
output_format: &'a OutputFormat,
|
||||
}
|
||||
@@ -339,7 +339,7 @@ impl CommandHandler<'_> {
|
||||
Ok(self
|
||||
.client
|
||||
.lock()
|
||||
.unwrap()
|
||||
.await
|
||||
.scoped_client::<PeerManageRpcClientFactory<BaseController>>("".to_string())
|
||||
.await
|
||||
.with_context(|| "failed to get peer manager client")?)
|
||||
@@ -351,7 +351,7 @@ impl CommandHandler<'_> {
|
||||
Ok(self
|
||||
.client
|
||||
.lock()
|
||||
.unwrap()
|
||||
.await
|
||||
.scoped_client::<ConnectorManageRpcClientFactory<BaseController>>("".to_string())
|
||||
.await
|
||||
.with_context(|| "failed to get connector manager client")?)
|
||||
@@ -363,7 +363,7 @@ impl CommandHandler<'_> {
|
||||
Ok(self
|
||||
.client
|
||||
.lock()
|
||||
.unwrap()
|
||||
.await
|
||||
.scoped_client::<MappedListenerManageRpcClientFactory<BaseController>>("".to_string())
|
||||
.await
|
||||
.with_context(|| "failed to get mapped listener manager client")?)
|
||||
@@ -375,7 +375,7 @@ impl CommandHandler<'_> {
|
||||
Ok(self
|
||||
.client
|
||||
.lock()
|
||||
.unwrap()
|
||||
.await
|
||||
.scoped_client::<PeerCenterRpcClientFactory<BaseController>>("".to_string())
|
||||
.await
|
||||
.with_context(|| "failed to get peer center client")?)
|
||||
@@ -387,7 +387,7 @@ impl CommandHandler<'_> {
|
||||
Ok(self
|
||||
.client
|
||||
.lock()
|
||||
.unwrap()
|
||||
.await
|
||||
.scoped_client::<VpnPortalRpcClientFactory<BaseController>>("".to_string())
|
||||
.await
|
||||
.with_context(|| "failed to get vpn portal client")?)
|
||||
@@ -399,7 +399,7 @@ impl CommandHandler<'_> {
|
||||
Ok(self
|
||||
.client
|
||||
.lock()
|
||||
.unwrap()
|
||||
.await
|
||||
.scoped_client::<AclManageRpcClientFactory<BaseController>>("".to_string())
|
||||
.await
|
||||
.with_context(|| "failed to get acl manager client")?)
|
||||
@@ -412,7 +412,7 @@ impl CommandHandler<'_> {
|
||||
Ok(self
|
||||
.client
|
||||
.lock()
|
||||
.unwrap()
|
||||
.await
|
||||
.scoped_client::<TcpProxyRpcClientFactory<BaseController>>(transport_type.to_string())
|
||||
.await
|
||||
.with_context(|| "failed to get vpn portal client")?)
|
||||
@@ -424,7 +424,7 @@ impl CommandHandler<'_> {
|
||||
Ok(self
|
||||
.client
|
||||
.lock()
|
||||
.unwrap()
|
||||
.await
|
||||
.scoped_client::<PortForwardManageRpcClientFactory<BaseController>>("".to_string())
|
||||
.await
|
||||
.with_context(|| "failed to get port forward manager client")?)
|
||||
@@ -436,7 +436,7 @@ impl CommandHandler<'_> {
|
||||
Ok(self
|
||||
.client
|
||||
.lock()
|
||||
.unwrap()
|
||||
.await
|
||||
.scoped_client::<StatsRpcClientFactory<BaseController>>("".to_string())
|
||||
.await
|
||||
.with_context(|| "failed to get stats client")?)
|
||||
@@ -865,7 +865,7 @@ impl CommandHandler<'_> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_mapped_listener_add(&self, url: &String) -> Result<(), Error> {
|
||||
async fn handle_mapped_listener_add(&self, url: &str) -> Result<(), Error> {
|
||||
let url = Self::mapped_listener_validate_url(url)?;
|
||||
let client = self.get_mapped_listener_manager_client().await?;
|
||||
let request = ManageMappedListenerRequest {
|
||||
@@ -878,7 +878,7 @@ impl CommandHandler<'_> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_mapped_listener_remove(&self, url: &String) -> Result<(), Error> {
|
||||
async fn handle_mapped_listener_remove(&self, url: &str) -> Result<(), Error> {
|
||||
let url = Self::mapped_listener_validate_url(url)?;
|
||||
let client = self.get_mapped_listener_manager_client().await?;
|
||||
let request = ManageMappedListenerRequest {
|
||||
@@ -891,7 +891,7 @@ impl CommandHandler<'_> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn mapped_listener_validate_url(url: &String) -> Result<url::Url, Error> {
|
||||
fn mapped_listener_validate_url(url: &str) -> Result<url::Url, Error> {
|
||||
let url = url::Url::parse(url)?;
|
||||
if url.scheme() != "tcp" && url.scheme() != "udp" {
|
||||
return Err(anyhow::anyhow!(
|
||||
@@ -925,8 +925,8 @@ impl CommandHandler<'_> {
|
||||
cfg: Some(
|
||||
PortForwardConfig {
|
||||
proto: protocol.to_string(),
|
||||
bind_addr: bind_addr.into(),
|
||||
dst_addr: dst_addr.into(),
|
||||
bind_addr,
|
||||
dst_addr,
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
@@ -961,11 +961,10 @@ impl CommandHandler<'_> {
|
||||
cfg: Some(
|
||||
PortForwardConfig {
|
||||
proto: protocol.to_string(),
|
||||
bind_addr: bind_addr.into(),
|
||||
bind_addr,
|
||||
dst_addr: dst_addr
|
||||
.map(|s| s.parse::<SocketAddr>().unwrap())
|
||||
.map(Into::into)
|
||||
.unwrap_or("0.0.0.0:0".parse::<SocketAddr>().unwrap().into()),
|
||||
.unwrap_or("0.0.0.0:0".parse::<SocketAddr>().unwrap()),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
@@ -1458,7 +1457,7 @@ async fn main() -> Result<(), Error> {
|
||||
.unwrap(),
|
||||
));
|
||||
let handler = CommandHandler {
|
||||
client: Mutex::new(client),
|
||||
client: tokio::sync::Mutex::new(client),
|
||||
verbose: cli.verbose,
|
||||
output_format: &cli.output_format,
|
||||
};
|
||||
@@ -1716,16 +1715,10 @@ async fn main() -> Result<(), Error> {
|
||||
format!("{:?}", stun_info.udp_nat_type()).as_str(),
|
||||
]);
|
||||
ip_list.interface_ipv4s.iter().for_each(|ip| {
|
||||
builder.push_record(vec![
|
||||
"Interface IPv4",
|
||||
format!("{}", ip.to_string()).as_str(),
|
||||
]);
|
||||
builder.push_record(vec!["Interface IPv4", ip.to_string().as_str()]);
|
||||
});
|
||||
ip_list.interface_ipv6s.iter().for_each(|ip| {
|
||||
builder.push_record(vec![
|
||||
"Interface IPv6",
|
||||
format!("{}", ip.to_string()).as_str(),
|
||||
]);
|
||||
builder.push_record(vec!["Interface IPv6", ip.to_string().as_str()]);
|
||||
});
|
||||
for (idx, l) in node_info.listeners.iter().enumerate() {
|
||||
if l.starts_with("ring") {
|
||||
@@ -1911,9 +1904,7 @@ async fn main() -> Result<(), Error> {
|
||||
Some(StatsSubCommand::Show) | None => {
|
||||
let client = handler.get_stats_client().await?;
|
||||
let request = GetStatsRequest {};
|
||||
let response = client
|
||||
.get_stats(BaseController::default(), request)
|
||||
.await?;
|
||||
let response = client.get_stats(BaseController::default(), request).await?;
|
||||
|
||||
if cli.output_format == OutputFormat::Json {
|
||||
println!("{}", serde_json::to_string_pretty(&response.metrics)?);
|
||||
@@ -1942,7 +1933,7 @@ async fn main() -> Result<(), Error> {
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
};
|
||||
|
||||
|
||||
let formatted_value = if metric.name.contains("bytes") {
|
||||
format_size(metric.value, humansize::BINARY)
|
||||
} else if metric.name.contains("duration") {
|
||||
|
||||
@@ -61,7 +61,7 @@ pub static malloc_conf: &[u8] = b"prof:true,prof_active:true,lg_prof_sample:19\0
|
||||
fn set_prof_active(_active: bool) {
|
||||
#[cfg(feature = "jemalloc-prof")]
|
||||
{
|
||||
const PROF_ACTIVE: &'static [u8] = b"prof.active\0";
|
||||
const PROF_ACTIVE: &[u8] = b"prof.active\0";
|
||||
let name = PROF_ACTIVE.name();
|
||||
name.write(_active).expect("Should succeed to set prof");
|
||||
}
|
||||
@@ -70,7 +70,7 @@ fn set_prof_active(_active: bool) {
|
||||
fn dump_profile(_cur_allocated: usize) {
|
||||
#[cfg(feature = "jemalloc-prof")]
|
||||
{
|
||||
const PROF_DUMP: &'static [u8] = b"prof.dump\0";
|
||||
const PROF_DUMP: &[u8] = b"prof.dump\0";
|
||||
static mut PROF_DUMP_FILE_NAME: [u8; 128] = [0; 128];
|
||||
let file_name_str = format!(
|
||||
"profile-{}-{}.out",
|
||||
@@ -701,7 +701,7 @@ impl NetworkOptions {
|
||||
.map(|s| s.parse().unwrap())
|
||||
.collect(),
|
||||
);
|
||||
} else if cfg.get_listeners() == None {
|
||||
} else if cfg.get_listeners().is_none() {
|
||||
cfg.set_listeners(
|
||||
Cli::parse_listeners(false, vec!["11010".to_string()])?
|
||||
.into_iter()
|
||||
@@ -740,7 +740,7 @@ impl NetworkOptions {
|
||||
}
|
||||
|
||||
for n in self.proxy_networks.iter() {
|
||||
add_proxy_network_to_config(n, &cfg)?;
|
||||
add_proxy_network_to_config(n, cfg)?;
|
||||
}
|
||||
|
||||
let rpc_portal = if let Some(r) = &self.rpc_portal {
|
||||
@@ -754,9 +754,9 @@ impl NetworkOptions {
|
||||
cfg.set_rpc_portal(rpc_portal);
|
||||
|
||||
if let Some(rpc_portal_whitelist) = &self.rpc_portal_whitelist {
|
||||
let mut whitelist = cfg.get_rpc_portal_whitelist().unwrap_or_else(|| Vec::new());
|
||||
let mut whitelist = cfg.get_rpc_portal_whitelist().unwrap_or_default();
|
||||
for cidr in rpc_portal_whitelist {
|
||||
whitelist.push((*cidr).clone());
|
||||
whitelist.push(*cidr);
|
||||
}
|
||||
cfg.set_rpc_portal_whitelist(Some(whitelist));
|
||||
}
|
||||
@@ -825,18 +825,18 @@ impl NetworkOptions {
|
||||
port_forward.port().expect("local bind port is missing")
|
||||
)
|
||||
.parse()
|
||||
.expect(format!("failed to parse local bind addr {}", example_str).as_str());
|
||||
.unwrap_or_else(|_| panic!("failed to parse local bind addr {}", example_str));
|
||||
|
||||
let dst_addr = format!(
|
||||
"{}",
|
||||
port_forward
|
||||
.path_segments()
|
||||
.expect(format!("remote destination addr is missing {}", example_str).as_str())
|
||||
.next()
|
||||
.expect(format!("remote destination addr is missing {}", example_str).as_str())
|
||||
)
|
||||
.parse()
|
||||
.expect(format!("failed to parse remote destination addr {}", example_str).as_str());
|
||||
let dst_addr = port_forward
|
||||
.path_segments()
|
||||
.unwrap_or_else(|| panic!("remote destination addr is missing {}", example_str))
|
||||
.next()
|
||||
.unwrap_or_else(|| panic!("remote destination addr is missing {}", example_str))
|
||||
.to_string()
|
||||
.parse()
|
||||
.unwrap_or_else(|_| {
|
||||
panic!("failed to parse remote destination addr {}", example_str)
|
||||
});
|
||||
|
||||
let port_forward_item = PortForwardConfig {
|
||||
bind_addr,
|
||||
@@ -1141,7 +1141,7 @@ async fn run_main(cli: Cli) -> anyhow::Result<()> {
|
||||
let mut cfg = TomlConfigLoader::default();
|
||||
cli.network_options
|
||||
.merge_into(&mut cfg)
|
||||
.with_context(|| format!("failed to create config from cli"))?;
|
||||
.with_context(|| "failed to create config from cli".to_string())?;
|
||||
println!("Starting easytier from cli with config:");
|
||||
println!("############### TOML ###############\n");
|
||||
println!("{}", cfg.dump());
|
||||
@@ -1156,7 +1156,7 @@ async fn run_main(cli: Cli) -> anyhow::Result<()> {
|
||||
.into_values()
|
||||
.filter_map(|info| info.error_msg)
|
||||
.collect::<Vec<_>>();
|
||||
if errs.len() > 0 {
|
||||
if !errs.is_empty() {
|
||||
return Err(anyhow::anyhow!("some instances stopped with errors"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,7 +294,7 @@ pub fn new_udp_header<T: ToTargetAddr>(target_addr: T) -> Result<Vec<u8>> {
|
||||
}
|
||||
|
||||
/// Parse data from UDP client on raw buffer, return (frag, target_addr, payload).
|
||||
pub async fn parse_udp_request<'a>(mut req: &'a [u8]) -> Result<(u8, TargetAddr, &'a [u8])> {
|
||||
pub async fn parse_udp_request(mut req: &[u8]) -> Result<(u8, TargetAddr, &[u8])> {
|
||||
let rsv = read_exact!(req, [0u8; 2]).context("Malformed request")?;
|
||||
|
||||
if !rsv.eq(&[0u8; 2]) {
|
||||
|
||||
@@ -455,16 +455,16 @@ impl<T: AsyncRead + AsyncWrite + Unpin, A: Authentication, C: AsyncTcpConnector>
|
||||
|
||||
info!("User logged successfully.");
|
||||
|
||||
return Ok(credentials);
|
||||
Ok(credentials)
|
||||
} else {
|
||||
self.inner
|
||||
.write_all(&[1, consts::SOCKS5_AUTH_METHOD_NOT_ACCEPTABLE])
|
||||
.await
|
||||
.context("Can't reply with auth method not acceptable.")?;
|
||||
|
||||
return Err(SocksError::AuthenticationRejected(format!(
|
||||
"Authentication, rejected."
|
||||
)));
|
||||
Err(SocksError::AuthenticationRejected(
|
||||
"Authentication, rejected.".to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,10 +72,7 @@ impl TargetAddr {
|
||||
}
|
||||
|
||||
pub fn is_ip(&self) -> bool {
|
||||
match self {
|
||||
TargetAddr::Ip(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(self, TargetAddr::Ip(_))
|
||||
}
|
||||
|
||||
pub fn is_domain(&self) -> bool {
|
||||
@@ -104,7 +101,7 @@ impl TargetAddr {
|
||||
}
|
||||
TargetAddr::Domain(ref domain, port) => {
|
||||
debug!("TargetAddr::Domain");
|
||||
if domain.len() > u8::max_value() as usize {
|
||||
if domain.len() > u8::MAX as usize {
|
||||
return Err(SocksError::ExceededMaxDomainLen(domain.len()).into());
|
||||
}
|
||||
buf.extend_from_slice(&[consts::SOCKS5_ADDR_TYPE_DOMAIN_NAME, domain.len() as u8]);
|
||||
@@ -125,8 +122,7 @@ impl std::net::ToSocketAddrs for TargetAddr {
|
||||
fn to_socket_addrs(&self) -> io::Result<IntoIter<SocketAddr>> {
|
||||
match *self {
|
||||
TargetAddr::Ip(addr) => Ok(vec![addr].into_iter()),
|
||||
TargetAddr::Domain(_, _) => Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
TargetAddr::Domain(_, _) => Err(io::Error::other(
|
||||
"Domain name has to be explicitly resolved, please use TargetAddr::resolve_dns().",
|
||||
)),
|
||||
}
|
||||
@@ -149,7 +145,7 @@ pub trait ToTargetAddr {
|
||||
fn to_target_addr(&self) -> io::Result<TargetAddr>;
|
||||
}
|
||||
|
||||
impl<'a> ToTargetAddr for (&'a str, u16) {
|
||||
impl ToTargetAddr for (&str, u16) {
|
||||
fn to_target_addr(&self) -> io::Result<TargetAddr> {
|
||||
// try to parse as an IP first
|
||||
if let Ok(addr) = self.0.parse::<Ipv4Addr>() {
|
||||
|
||||
@@ -23,6 +23,7 @@ use tracing::Instrument;
|
||||
|
||||
use crate::{
|
||||
common::{error::Error, global_ctx::ArcGlobalCtx, PeerId},
|
||||
gateway::ip_reassembler::ComposeIpv4PacketArgs,
|
||||
peers::{peer_manager::PeerManager, PeerPacketFilter},
|
||||
tunnel::packet_def::{PacketType, ZCPacket},
|
||||
};
|
||||
@@ -118,7 +119,7 @@ fn socket_recv_loop(
|
||||
}
|
||||
};
|
||||
|
||||
if len <= 0 {
|
||||
if len == 0 {
|
||||
tracing::error!("recv empty packet, len: {}", len);
|
||||
return;
|
||||
}
|
||||
@@ -158,20 +159,18 @@ fn socket_recv_loop(
|
||||
let payload_len = len - ipv4_packet.get_header_length() as usize * 4;
|
||||
let id = ipv4_packet.get_identification();
|
||||
let _ = compose_ipv4_packet(
|
||||
&mut buf[..],
|
||||
&v.mapped_dst_ip,
|
||||
&dest_ip,
|
||||
IpNextHeaderProtocols::Icmp,
|
||||
payload_len,
|
||||
1200,
|
||||
id,
|
||||
ComposeIpv4PacketArgs {
|
||||
buf: &mut buf[..],
|
||||
src_v4: &v.mapped_dst_ip,
|
||||
dst_v4: &dest_ip,
|
||||
next_protocol: IpNextHeaderProtocols::Icmp,
|
||||
payload_len,
|
||||
payload_mtu: 1200,
|
||||
ip_id: id,
|
||||
},
|
||||
|buf| {
|
||||
let mut p = ZCPacket::new_with_payload(buf);
|
||||
p.fill_peer_manager_hdr(
|
||||
v.my_peer_id.into(),
|
||||
v.src_peer_id.into(),
|
||||
PacketType::Data as u8,
|
||||
);
|
||||
p.fill_peer_manager_hdr(v.my_peer_id, v.src_peer_id, PacketType::Data as u8);
|
||||
p.mut_peer_manager_header().unwrap().set_no_proxy(true);
|
||||
|
||||
if let Err(e) = sender.send(p) {
|
||||
@@ -186,7 +185,7 @@ fn socket_recv_loop(
|
||||
#[async_trait::async_trait]
|
||||
impl PeerPacketFilter for IcmpProxy {
|
||||
async fn try_process_packet_from_peer(&self, packet: ZCPacket) -> Option<ZCPacket> {
|
||||
if let Some(_) = self.try_handle_peer_packet(&packet).await {
|
||||
if self.try_handle_peer_packet(&packet).await.is_some() {
|
||||
return None;
|
||||
} else {
|
||||
return Some(packet);
|
||||
@@ -320,10 +319,7 @@ impl IcmpProxy {
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
.with_context(|| "icmp socket not created")?
|
||||
.send_to(
|
||||
icmp_packet.packet(),
|
||||
&SocketAddrV4::new(dst_ip.into(), 0).into(),
|
||||
)?;
|
||||
.send_to(icmp_packet.packet(), &SocketAddrV4::new(dst_ip, 0).into())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -349,13 +345,15 @@ impl IcmpProxy {
|
||||
|
||||
let len = buf.len() - 20;
|
||||
let _ = compose_ipv4_packet(
|
||||
&mut buf[..],
|
||||
src_ip,
|
||||
dst_ip,
|
||||
IpNextHeaderProtocols::Icmp,
|
||||
len,
|
||||
1200,
|
||||
rand::random(),
|
||||
ComposeIpv4PacketArgs {
|
||||
buf: &mut buf[..],
|
||||
src_v4: src_ip,
|
||||
dst_v4: dst_ip,
|
||||
next_protocol: IpNextHeaderProtocols::Icmp,
|
||||
payload_len: len,
|
||||
payload_mtu: 1200,
|
||||
ip_id: rand::random(),
|
||||
},
|
||||
|buf| {
|
||||
let mut packet = ZCPacket::new_with_payload(buf);
|
||||
packet.fill_peer_manager_hdr(src_peer_id, dst_peer_id, PacketType::Data as u8);
|
||||
@@ -387,7 +385,7 @@ impl IcmpProxy {
|
||||
return None;
|
||||
};
|
||||
|
||||
let ipv4 = Ipv4Packet::new(&packet.payload())?;
|
||||
let ipv4 = Ipv4Packet::new(packet.payload())?;
|
||||
|
||||
if ipv4.get_version() != 4 || ipv4.get_next_level_protocol() != IpNextHeaderProtocols::Icmp
|
||||
{
|
||||
@@ -396,17 +394,17 @@ impl IcmpProxy {
|
||||
|
||||
let mut real_dst_ip = ipv4.get_destination();
|
||||
|
||||
if !self
|
||||
if !(self
|
||||
.cidr_set
|
||||
.contains_v4(ipv4.get_destination(), &mut real_dst_ip)
|
||||
&& !is_exit_node
|
||||
&& !(self.global_ctx.no_tun()
|
||||
|| is_exit_node
|
||||
|| (self.global_ctx.no_tun()
|
||||
&& Some(ipv4.get_destination())
|
||||
== self
|
||||
.global_ctx
|
||||
.get_ipv4()
|
||||
.as_ref()
|
||||
.map(cidr::Ipv4Inet::address))
|
||||
.map(cidr::Ipv4Inet::address)))
|
||||
{
|
||||
return None;
|
||||
}
|
||||
@@ -416,12 +414,10 @@ impl IcmpProxy {
|
||||
resembled_buf =
|
||||
self.ip_resemmbler
|
||||
.add_fragment(ipv4.get_source(), ipv4.get_destination(), &ipv4);
|
||||
if resembled_buf.is_none() {
|
||||
return None;
|
||||
};
|
||||
resembled_buf.as_ref()?;
|
||||
icmp::echo_request::EchoRequestPacket::new(resembled_buf.as_ref().unwrap())?
|
||||
} else {
|
||||
icmp::echo_request::EchoRequestPacket::new(&ipv4.payload())?
|
||||
icmp::echo_request::EchoRequestPacket::new(ipv4.payload())?
|
||||
};
|
||||
|
||||
if icmp_packet.get_icmp_type() != IcmpTypes::EchoRequest {
|
||||
@@ -484,10 +480,9 @@ impl Drop for IcmpProxy {
|
||||
"dropping icmp proxy, {:?}",
|
||||
self.socket.lock().unwrap().as_ref()
|
||||
);
|
||||
self.socket.lock().unwrap().as_ref().and_then(|s| {
|
||||
if let Some(s) = self.socket.lock().unwrap().as_ref() {
|
||||
tracing::info!("shutting down icmp socket");
|
||||
let _ = s.shutdown(std::net::Shutdown::Both);
|
||||
Some(())
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,33 +190,36 @@ impl IpReassembler {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ComposeIpv4PacketArgs<'a> {
|
||||
pub buf: &'a mut [u8],
|
||||
pub src_v4: &'a Ipv4Addr,
|
||||
pub dst_v4: &'a Ipv4Addr,
|
||||
pub next_protocol: IpNextHeaderProtocol,
|
||||
pub payload_len: usize,
|
||||
pub payload_mtu: usize,
|
||||
pub ip_id: u16,
|
||||
}
|
||||
|
||||
// ip payload should be in buf[20..]
|
||||
pub fn compose_ipv4_packet<F>(
|
||||
buf: &mut [u8],
|
||||
src_v4: &Ipv4Addr,
|
||||
dst_v4: &Ipv4Addr,
|
||||
next_protocol: IpNextHeaderProtocol,
|
||||
payload_len: usize,
|
||||
payload_mtu: usize,
|
||||
ip_id: u16,
|
||||
cb: F,
|
||||
) -> Result<(), Error>
|
||||
pub fn compose_ipv4_packet<F>(args: ComposeIpv4PacketArgs, cb: F) -> Result<(), Error>
|
||||
where
|
||||
F: Fn(&[u8]) -> Result<(), Error>,
|
||||
{
|
||||
let total_pieces = (payload_len + payload_mtu - 1) / payload_mtu;
|
||||
let total_pieces = args.payload_len.div_ceil(args.payload_mtu);
|
||||
let mut buf_offset = 0;
|
||||
let mut fragment_offset = 0;
|
||||
let mut cur_piece = 0;
|
||||
while fragment_offset < payload_len {
|
||||
let next_fragment_offset = std::cmp::min(fragment_offset + payload_mtu, payload_len);
|
||||
while fragment_offset < args.payload_len {
|
||||
let next_fragment_offset =
|
||||
std::cmp::min(fragment_offset + args.payload_mtu, args.payload_len);
|
||||
let fragment_len = next_fragment_offset - fragment_offset;
|
||||
let mut ipv4_packet =
|
||||
MutableIpv4Packet::new(&mut buf[buf_offset..buf_offset + fragment_len + 20]).unwrap();
|
||||
MutableIpv4Packet::new(&mut args.buf[buf_offset..buf_offset + fragment_len + 20])
|
||||
.unwrap();
|
||||
ipv4_packet.set_version(4);
|
||||
ipv4_packet.set_header_length(5);
|
||||
ipv4_packet.set_total_length((fragment_len + 20) as u16);
|
||||
ipv4_packet.set_identification(ip_id);
|
||||
ipv4_packet.set_identification(args.ip_id);
|
||||
if total_pieces > 1 {
|
||||
if cur_piece != total_pieces - 1 {
|
||||
ipv4_packet.set_flags(Ipv4Flags::MoreFragments);
|
||||
@@ -232,9 +235,9 @@ where
|
||||
ipv4_packet.set_ecn(0);
|
||||
ipv4_packet.set_dscp(0);
|
||||
ipv4_packet.set_ttl(32);
|
||||
ipv4_packet.set_source(src_v4.clone());
|
||||
ipv4_packet.set_destination(dst_v4.clone());
|
||||
ipv4_packet.set_next_level_protocol(next_protocol);
|
||||
ipv4_packet.set_source(*args.src_v4);
|
||||
ipv4_packet.set_destination(*args.dst_v4);
|
||||
ipv4_packet.set_next_level_protocol(args.next_protocol);
|
||||
ipv4_packet.set_checksum(ipv4::checksum(&ipv4_packet.to_immutable()));
|
||||
|
||||
tracing::trace!(?ipv4_packet, "udp nat packet response send");
|
||||
@@ -254,7 +257,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn resembler() {
|
||||
let raw_packets = vec![
|
||||
let raw_packets = [
|
||||
// last packet
|
||||
vec![
|
||||
0x45, 0x00, 0x00, 0x1c, 0x1c, 0x46, 0x20, 0x01, 0x40, 0x06, 0xb1, 0xe6, 0xc0, 0xa8,
|
||||
@@ -282,7 +285,7 @@ mod tests {
|
||||
let resembler = IpReassembler::new(Duration::from_secs(1));
|
||||
|
||||
for (idx, raw_packet) in raw_packets.iter().enumerate() {
|
||||
if let Some(packet) = Ipv4Packet::new(&raw_packet) {
|
||||
if let Some(packet) = Ipv4Packet::new(raw_packet) {
|
||||
let ret = resembler.add_fragment(source, destination, &packet);
|
||||
if idx != 2 {
|
||||
assert!(ret.is_none());
|
||||
|
||||
@@ -70,7 +70,9 @@ impl PeerPacketFilter for KcpEndpointFilter {
|
||||
async fn try_process_packet_from_peer(&self, packet: ZCPacket) -> Option<ZCPacket> {
|
||||
let t = packet.peer_manager_header().unwrap().packet_type;
|
||||
if t == PacketType::KcpSrc as u8 && !self.is_src {
|
||||
// src packet, but we are dst
|
||||
} else if t == PacketType::KcpDst as u8 && self.is_src {
|
||||
// dst packet, but we are src
|
||||
} else {
|
||||
return Some(packet);
|
||||
}
|
||||
@@ -103,7 +105,7 @@ async fn handle_kcp_output(
|
||||
PacketType::KcpDst as u8
|
||||
};
|
||||
let mut packet = ZCPacket::new_with_payload(&packet.inner().freeze());
|
||||
packet.fill_peer_manager_hdr(peer_mgr.my_peer_id(), dst_peer_id, packet_type as u8);
|
||||
packet.fill_peer_manager_hdr(peer_mgr.my_peer_id(), dst_peer_id, packet_type);
|
||||
|
||||
if let Err(e) = peer_mgr.send_msg(packet, dst_peer_id).await {
|
||||
tracing::error!("failed to send kcp packet to peer: {:?}", e);
|
||||
@@ -171,7 +173,7 @@ impl NatDstConnector for NatDstKcpConnector {
|
||||
|
||||
let kcp_endpoint = self.kcp_endpoint.clone();
|
||||
let my_peer_id = peer_mgr.my_peer_id();
|
||||
let conn_data_clone = conn_data.clone();
|
||||
let conn_data_clone = conn_data;
|
||||
|
||||
connect_tasks.spawn(async move {
|
||||
kcp_endpoint
|
||||
@@ -182,9 +184,7 @@ impl NatDstConnector for NatDstKcpConnector {
|
||||
Bytes::from(conn_data_clone.encode_to_vec()),
|
||||
)
|
||||
.await
|
||||
.with_context(|| {
|
||||
format!("failed to connect to nat dst: {}", nat_dst.to_string())
|
||||
})
|
||||
.with_context(|| format!("failed to connect to nat dst: {}", nat_dst))
|
||||
});
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ impl NatDstConnector for NatDstKcpConnector {
|
||||
_ipv4: &Ipv4Packet,
|
||||
_real_dst_ip: &mut Ipv4Addr,
|
||||
) -> bool {
|
||||
return 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()
|
||||
}
|
||||
|
||||
fn transport_type(&self) -> TcpProxyEntryTransportType {
|
||||
@@ -230,7 +230,10 @@ impl TcpProxyForKcpSrcTrait for TcpProxyForKcpSrc {
|
||||
}
|
||||
|
||||
async fn check_dst_allow_kcp_input(&self, dst_ip: &Ipv4Addr) -> bool {
|
||||
self.0.get_peer_manager().check_allow_kcp_to_dst(&IpAddr::V4(*dst_ip)).await
|
||||
self.0
|
||||
.get_peer_manager()
|
||||
.check_allow_kcp_to_dst(&IpAddr::V4(*dst_ip))
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -456,14 +459,11 @@ impl KcpProxyDst {
|
||||
.into();
|
||||
let src_socket: SocketAddr = parsed_conn_data.src.unwrap_or_default().into();
|
||||
|
||||
match dst_socket.ip() {
|
||||
IpAddr::V4(dst_v4_ip) => {
|
||||
let mut real_ip = dst_v4_ip;
|
||||
if cidr_set.contains_v4(dst_v4_ip, &mut real_ip) {
|
||||
dst_socket.set_ip(real_ip.into());
|
||||
}
|
||||
if let IpAddr::V4(dst_v4_ip) = dst_socket.ip() {
|
||||
let mut real_ip = dst_v4_ip;
|
||||
if cidr_set.contains_v4(dst_v4_ip, &mut real_ip) {
|
||||
dst_socket.set_ip(real_ip.into());
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
let conn_id = kcp_stream.conn_id();
|
||||
@@ -578,7 +578,7 @@ impl TcpProxyRpc for KcpProxyDstRpcService {
|
||||
let mut reply = ListTcpProxyEntryResponse::default();
|
||||
if let Some(tcp_proxy) = self.0.upgrade() {
|
||||
for item in tcp_proxy.iter() {
|
||||
reply.entries.push(item.value().clone());
|
||||
reply.entries.push(*item.value());
|
||||
}
|
||||
}
|
||||
Ok(reply)
|
||||
|
||||
@@ -56,11 +56,11 @@ impl CidrSet {
|
||||
cidr_set.lock().unwrap().clear();
|
||||
for cidr in cidrs.iter() {
|
||||
let real_cidr = cidr.cidr;
|
||||
let mapped = cidr.mapped_cidr.unwrap_or(real_cidr.clone());
|
||||
cidr_set.lock().unwrap().push(mapped.clone());
|
||||
let mapped = cidr.mapped_cidr.unwrap_or(real_cidr);
|
||||
cidr_set.lock().unwrap().push(mapped);
|
||||
|
||||
if mapped != real_cidr {
|
||||
mapped_to_real.insert(mapped.clone(), real_cidr.clone());
|
||||
mapped_to_real.insert(mapped, real_cidr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,11 +70,11 @@ impl CidrSet {
|
||||
}
|
||||
|
||||
pub fn contains_v4(&self, ipv4: std::net::Ipv4Addr, real_ip: &mut std::net::Ipv4Addr) -> bool {
|
||||
let ip = ipv4.into();
|
||||
let ip = ipv4;
|
||||
let s = self.cidr_set.lock().unwrap();
|
||||
for cidr in s.iter() {
|
||||
if cidr.contains(&ip) {
|
||||
if let Some(real_cidr) = self.mapped_to_real.get(&cidr).map(|v| v.value().clone()) {
|
||||
if let Some(real_cidr) = self.mapped_to_real.get(cidr).map(|v| *v.value()) {
|
||||
let origin_network_bits = real_cidr.first().address().to_bits();
|
||||
let network_mask = cidr.mask().to_bits();
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ impl NatDstConnector for NatDstQUICConnector {
|
||||
_ipv4: &Ipv4Packet,
|
||||
_real_dst_ip: &mut Ipv4Addr,
|
||||
) -> bool {
|
||||
return 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()
|
||||
}
|
||||
|
||||
fn transport_type(&self) -> TcpProxyEntryTransportType {
|
||||
@@ -457,7 +457,7 @@ impl TcpProxyRpc for QUICProxyDstRpcService {
|
||||
let mut reply = ListTcpProxyEntryResponse::default();
|
||||
if let Some(tcp_proxy) = self.0.upgrade() {
|
||||
for item in tcp_proxy.iter() {
|
||||
reply.entries.push(item.value().clone());
|
||||
reply.entries.push(*item.value());
|
||||
}
|
||||
}
|
||||
Ok(reply)
|
||||
|
||||
@@ -72,9 +72,9 @@ impl SocksUdpSocket {
|
||||
}
|
||||
|
||||
enum SocksTcpStream {
|
||||
TcpStream(tokio::net::TcpStream),
|
||||
SmolTcpStream(super::tokio_smoltcp::TcpStream),
|
||||
KcpStream(KcpStream),
|
||||
Tcp(tokio::net::TcpStream),
|
||||
SmolTcp(super::tokio_smoltcp::TcpStream),
|
||||
Kcp(KcpStream),
|
||||
}
|
||||
|
||||
impl AsyncRead for SocksTcpStream {
|
||||
@@ -84,15 +84,11 @@ impl AsyncRead for SocksTcpStream {
|
||||
buf: &mut tokio::io::ReadBuf<'_>,
|
||||
) -> std::task::Poll<std::io::Result<()>> {
|
||||
match self.get_mut() {
|
||||
SocksTcpStream::TcpStream(ref mut stream) => {
|
||||
std::pin::Pin::new(stream).poll_read(cx, buf)
|
||||
}
|
||||
SocksTcpStream::SmolTcpStream(ref mut stream) => {
|
||||
std::pin::Pin::new(stream).poll_read(cx, buf)
|
||||
}
|
||||
SocksTcpStream::KcpStream(ref mut stream) => {
|
||||
SocksTcpStream::Tcp(ref mut stream) => std::pin::Pin::new(stream).poll_read(cx, buf),
|
||||
SocksTcpStream::SmolTcp(ref mut stream) => {
|
||||
std::pin::Pin::new(stream).poll_read(cx, buf)
|
||||
}
|
||||
SocksTcpStream::Kcp(ref mut stream) => std::pin::Pin::new(stream).poll_read(cx, buf),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,15 +100,11 @@ impl AsyncWrite for SocksTcpStream {
|
||||
buf: &[u8],
|
||||
) -> std::task::Poll<Result<usize, std::io::Error>> {
|
||||
match self.get_mut() {
|
||||
SocksTcpStream::TcpStream(ref mut stream) => {
|
||||
std::pin::Pin::new(stream).poll_write(cx, buf)
|
||||
}
|
||||
SocksTcpStream::SmolTcpStream(ref mut stream) => {
|
||||
std::pin::Pin::new(stream).poll_write(cx, buf)
|
||||
}
|
||||
SocksTcpStream::KcpStream(ref mut stream) => {
|
||||
SocksTcpStream::Tcp(ref mut stream) => std::pin::Pin::new(stream).poll_write(cx, buf),
|
||||
SocksTcpStream::SmolTcp(ref mut stream) => {
|
||||
std::pin::Pin::new(stream).poll_write(cx, buf)
|
||||
}
|
||||
SocksTcpStream::Kcp(ref mut stream) => std::pin::Pin::new(stream).poll_write(cx, buf),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,11 +113,9 @@ impl AsyncWrite for SocksTcpStream {
|
||||
cx: &mut std::task::Context<'_>,
|
||||
) -> std::task::Poll<Result<(), std::io::Error>> {
|
||||
match self.get_mut() {
|
||||
SocksTcpStream::TcpStream(ref mut stream) => std::pin::Pin::new(stream).poll_flush(cx),
|
||||
SocksTcpStream::SmolTcpStream(ref mut stream) => {
|
||||
std::pin::Pin::new(stream).poll_flush(cx)
|
||||
}
|
||||
SocksTcpStream::KcpStream(ref mut stream) => std::pin::Pin::new(stream).poll_flush(cx),
|
||||
SocksTcpStream::Tcp(ref mut stream) => std::pin::Pin::new(stream).poll_flush(cx),
|
||||
SocksTcpStream::SmolTcp(ref mut stream) => std::pin::Pin::new(stream).poll_flush(cx),
|
||||
SocksTcpStream::Kcp(ref mut stream) => std::pin::Pin::new(stream).poll_flush(cx),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,15 +124,9 @@ impl AsyncWrite for SocksTcpStream {
|
||||
cx: &mut std::task::Context<'_>,
|
||||
) -> std::task::Poll<Result<(), std::io::Error>> {
|
||||
match self.get_mut() {
|
||||
SocksTcpStream::TcpStream(ref mut stream) => {
|
||||
std::pin::Pin::new(stream).poll_shutdown(cx)
|
||||
}
|
||||
SocksTcpStream::SmolTcpStream(ref mut stream) => {
|
||||
std::pin::Pin::new(stream).poll_shutdown(cx)
|
||||
}
|
||||
SocksTcpStream::KcpStream(ref mut stream) => {
|
||||
std::pin::Pin::new(stream).poll_shutdown(cx)
|
||||
}
|
||||
SocksTcpStream::Tcp(ref mut stream) => std::pin::Pin::new(stream).poll_shutdown(cx),
|
||||
SocksTcpStream::SmolTcp(ref mut stream) => std::pin::Pin::new(stream).poll_shutdown(cx),
|
||||
SocksTcpStream::Kcp(ref mut stream) => std::pin::Pin::new(stream).poll_shutdown(cx),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,7 +180,7 @@ impl AsyncTcpConnector for SmolTcpConnector {
|
||||
let modified_addr =
|
||||
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), addr.port());
|
||||
|
||||
Ok(SocksTcpStream::TcpStream(
|
||||
Ok(SocksTcpStream::Tcp(
|
||||
tcp_connect_with_timeout(modified_addr, timeout_s).await?,
|
||||
))
|
||||
} else {
|
||||
@@ -207,9 +191,9 @@ impl AsyncTcpConnector for SmolTcpConnector {
|
||||
.await
|
||||
.with_context(|| "connect to remote timeout")?;
|
||||
|
||||
Ok(SocksTcpStream::SmolTcpStream(remote_socket.map_err(
|
||||
|e| super::fast_socks5::SocksError::Other(e.into()),
|
||||
)?))
|
||||
Ok(SocksTcpStream::SmolTcp(remote_socket.map_err(|e| {
|
||||
super::fast_socks5::SocksError::Other(e.into())
|
||||
})?))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -249,7 +233,7 @@ impl AsyncTcpConnector for Socks5KcpConnector {
|
||||
.connect(self.src_addr, addr)
|
||||
.await
|
||||
.map_err(|e| super::fast_socks5::SocksError::Other(e.into()))?;
|
||||
Ok(SocksTcpStream::KcpStream(ret))
|
||||
Ok(SocksTcpStream::Kcp(ret))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -560,16 +544,16 @@ impl Socks5Server {
|
||||
tcp_forward_task.lock().unwrap().abort_all();
|
||||
udp_client_map.clear();
|
||||
|
||||
if cur_ipv4.is_none() {
|
||||
let _ = net.lock().await.take();
|
||||
} else {
|
||||
if let Some(cur_ipv4) = cur_ipv4 {
|
||||
net.lock().await.replace(Socks5ServerNet::new(
|
||||
cur_ipv4.unwrap(),
|
||||
cur_ipv4,
|
||||
None,
|
||||
peer_manager.clone(),
|
||||
packet_recv.clone(),
|
||||
entries.clone(),
|
||||
));
|
||||
} else {
|
||||
let _ = net.lock().await.take();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -621,7 +605,7 @@ impl Socks5Server {
|
||||
|
||||
let cfgs = self.global_ctx.config.get_port_forwards();
|
||||
self.reload_port_forwards(&cfgs).await?;
|
||||
need_start = need_start || cfgs.len() > 0;
|
||||
need_start = need_start || !cfgs.is_empty();
|
||||
|
||||
if need_start {
|
||||
self.peer_manager
|
||||
@@ -756,23 +740,21 @@ impl Socks5Server {
|
||||
continue;
|
||||
};
|
||||
|
||||
let dst_allow_kcp = peer_mgr_arc.check_allow_kcp_to_dst(&dst_addr.ip()).await;
|
||||
let dst_allow_kcp = peer_mgr_arc.check_allow_kcp_to_dst(&dst_addr.ip()).await;
|
||||
tracing::debug!("dst_allow_kcp: {:?}", dst_allow_kcp);
|
||||
|
||||
let connector: Box<dyn AsyncTcpConnector<S = SocksTcpStream> + Send> =
|
||||
if kcp_endpoint.is_none() || !dst_allow_kcp {
|
||||
Box::new(SmolTcpConnector {
|
||||
match (&kcp_endpoint, dst_allow_kcp) {
|
||||
(Some(kcp_endpoint), true) => Box::new(Socks5KcpConnector {
|
||||
kcp_endpoint: kcp_endpoint.clone(),
|
||||
peer_mgr: peer_mgr.clone(),
|
||||
src_addr: addr,
|
||||
}),
|
||||
(_, _) => Box::new(SmolTcpConnector {
|
||||
net: net.smoltcp_net.clone(),
|
||||
entries: entries.clone(),
|
||||
current_entry: std::sync::Mutex::new(None),
|
||||
})
|
||||
} else {
|
||||
let kcp_endpoint = kcp_endpoint.as_ref().unwrap().clone();
|
||||
Box::new(Socks5KcpConnector {
|
||||
kcp_endpoint,
|
||||
peer_mgr: peer_mgr.clone(),
|
||||
src_addr: addr,
|
||||
})
|
||||
}),
|
||||
};
|
||||
|
||||
forward_tasks
|
||||
@@ -962,10 +944,10 @@ impl Socks5Server {
|
||||
udp_client_map.retain(|_, client_info| {
|
||||
now.duration_since(client_info.last_active.load()).as_secs() < 600
|
||||
});
|
||||
udp_forward_task.retain(|k, _| udp_client_map.contains_key(&k));
|
||||
udp_forward_task.retain(|k, _| udp_client_map.contains_key(k));
|
||||
entries.retain(|_, data| match data {
|
||||
Socks5EntryData::Udp((_, udp_client_key)) => {
|
||||
udp_client_map.contains_key(&udp_client_key)
|
||||
udp_client_map.contains_key(udp_client_key)
|
||||
}
|
||||
_ => true,
|
||||
});
|
||||
|
||||
@@ -109,9 +109,9 @@ impl NatDstConnector for NatDstTcpConnector {
|
||||
) -> bool {
|
||||
let is_exit_node = hdr.is_exit_node();
|
||||
|
||||
if !cidr_set.contains_v4(ipv4.get_destination(), real_dst_ip)
|
||||
&& !is_exit_node
|
||||
&& !(global_ctx.no_tun()
|
||||
if !(cidr_set.contains_v4(ipv4.get_destination(), real_dst_ip)
|
||||
|| is_exit_node
|
||||
|| global_ctx.no_tun()
|
||||
&& Some(ipv4.get_destination())
|
||||
== global_ctx.get_ipv4().as_ref().map(Ipv4Inet::address))
|
||||
{
|
||||
@@ -154,10 +154,10 @@ impl NatDstEntry {
|
||||
}
|
||||
}
|
||||
|
||||
fn into_pb(&self, transport_type: TcpProxyEntryTransportType) -> TcpProxyEntry {
|
||||
fn parse_as_pb(&self, transport_type: TcpProxyEntryTransportType) -> TcpProxyEntry {
|
||||
TcpProxyEntry {
|
||||
src: Some(self.src.clone().into()),
|
||||
dst: Some(self.real_dst.clone().into()),
|
||||
src: Some(self.src.into()),
|
||||
dst: Some(self.real_dst.into()),
|
||||
start_time: self.start_time_local.timestamp() as u64,
|
||||
state: self.state.load().into(),
|
||||
transport_type: transport_type.into(),
|
||||
@@ -332,16 +332,14 @@ pub struct TcpProxy<C: NatDstConnector> {
|
||||
#[async_trait::async_trait]
|
||||
impl<C: NatDstConnector> PeerPacketFilter for TcpProxy<C> {
|
||||
async fn try_process_packet_from_peer(&self, mut packet: ZCPacket) -> Option<ZCPacket> {
|
||||
if let Some(_) = self.try_handle_peer_packet(&mut packet).await {
|
||||
if self.try_handle_peer_packet(&mut packet).await.is_some() {
|
||||
if self.is_smoltcp_enabled() {
|
||||
let smoltcp_stack_sender = self.smoltcp_stack_sender.as_ref().unwrap();
|
||||
if let Err(e) = smoltcp_stack_sender.try_send(packet) {
|
||||
tracing::error!("send to smoltcp stack failed: {:?}", e);
|
||||
}
|
||||
} else {
|
||||
if let Err(e) = self.peer_manager.get_nic_channel().send(packet).await {
|
||||
tracing::error!("send to nic failed: {:?}", e);
|
||||
}
|
||||
} else if let Err(e) = self.peer_manager.get_nic_channel().send(packet).await {
|
||||
tracing::error!("send to nic failed: {:?}", e);
|
||||
}
|
||||
return None;
|
||||
} else {
|
||||
@@ -610,7 +608,7 @@ impl<C: NatDstConnector> TcpProxy<C> {
|
||||
self.enable_smoltcp
|
||||
.store(false, std::sync::atomic::Ordering::Relaxed);
|
||||
|
||||
return Ok(ProxyTcpListener::KernelTcpListener(tcp_listener));
|
||||
Ok(ProxyTcpListener::KernelTcpListener(tcp_listener))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -917,10 +915,10 @@ impl<C: NatDstConnector> TcpProxy<C> {
|
||||
let mut entries: Vec<TcpProxyEntry> = Vec::new();
|
||||
let transport_type = self.connector.transport_type();
|
||||
for entry in self.syn_map.iter() {
|
||||
entries.push(entry.value().as_ref().into_pb(transport_type));
|
||||
entries.push(entry.value().as_ref().parse_as_pb(transport_type));
|
||||
}
|
||||
for entry in self.conn_map.iter() {
|
||||
entries.push(entry.value().as_ref().into_pb(transport_type));
|
||||
entries.push(entry.value().as_ref().parse_as_pb(transport_type));
|
||||
}
|
||||
entries
|
||||
}
|
||||
|
||||
@@ -17,11 +17,17 @@ pub struct ChannelDevice {
|
||||
caps: DeviceCapabilities,
|
||||
}
|
||||
|
||||
pub type ChannelDeviceNewRet = (
|
||||
ChannelDevice,
|
||||
Sender<io::Result<Vec<u8>>>,
|
||||
Receiver<Vec<u8>>,
|
||||
);
|
||||
|
||||
impl ChannelDevice {
|
||||
/// Make a new `ChannelDevice` with the given `recv` and `send` channels.
|
||||
///
|
||||
/// The `caps` is used to determine the device capabilities. `DeviceCapabilities::max_transmission_unit` must be set.
|
||||
pub fn new(caps: DeviceCapabilities) -> (Self, Sender<io::Result<Vec<u8>>>, Receiver<Vec<u8>>) {
|
||||
pub fn new(caps: DeviceCapabilities) -> ChannelDeviceNewRet {
|
||||
let (tx1, rx1) = channel(1000);
|
||||
let (tx2, rx2) = channel(1000);
|
||||
(
|
||||
@@ -45,7 +51,7 @@ impl Stream for ChannelDevice {
|
||||
}
|
||||
|
||||
fn map_err(e: PollSendError<Vec<u8>>) -> io::Error {
|
||||
io::Error::new(io::ErrorKind::Other, e)
|
||||
io::Error::other(e)
|
||||
}
|
||||
|
||||
impl Sink<Vec<u8>> for ChannelDevice {
|
||||
|
||||
@@ -46,8 +46,8 @@ impl RxToken for BufferRxToken {
|
||||
F: FnOnce(&[u8]) -> R,
|
||||
{
|
||||
let p = &mut self.0;
|
||||
let result = f(p);
|
||||
result
|
||||
|
||||
f(p)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,10 +79,9 @@ impl Device for BufferDevice {
|
||||
Self: 'a;
|
||||
|
||||
fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
|
||||
match self.recv_queue.pop_front() {
|
||||
Some(p) => Some((BufferRxToken(p), BufferTxToken(self))),
|
||||
None => None,
|
||||
}
|
||||
self.recv_queue
|
||||
.pop_front()
|
||||
.map(|p| (BufferRxToken(p), BufferTxToken(self)))
|
||||
}
|
||||
|
||||
fn transmit(&mut self, _timestamp: Instant) -> Option<Self::TxToken<'_>> {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
use std::{
|
||||
io,
|
||||
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
|
||||
net::{IpAddr, SocketAddr},
|
||||
sync::{
|
||||
atomic::{AtomicU16, Ordering},
|
||||
Arc,
|
||||
@@ -34,7 +34,7 @@ mod socket_allocator;
|
||||
/// Can be used to create a forever timestamp in neighbor.
|
||||
// The 60_000 is the same as NeighborCache::ENTRY_LIFETIME.
|
||||
pub const FOREVER: Instant =
|
||||
Instant::from_micros_const(i64::max_value() - Duration::from_millis(60_000).micros() as i64);
|
||||
Instant::from_micros_const(i64::MAX - Duration::from_millis(60_000).micros() as i64);
|
||||
|
||||
pub struct Neighbor {
|
||||
pub protocol_addr: IpAddress,
|
||||
@@ -173,8 +173,8 @@ impl Net {
|
||||
fn set_address(&self, mut addr: SocketAddr) -> SocketAddr {
|
||||
if addr.ip().is_unspecified() {
|
||||
addr.set_ip(match self.ip_addr.address() {
|
||||
IpAddress::Ipv4(ip) => Ipv4Addr::from(ip).into(),
|
||||
IpAddress::Ipv6(ip) => Ipv6Addr::from(ip).into(),
|
||||
IpAddress::Ipv4(ip) => ip.into(),
|
||||
IpAddress::Ipv6(ip) => ip.into(),
|
||||
#[allow(unreachable_patterns)]
|
||||
_ => panic!("address must not be unspecified"),
|
||||
});
|
||||
|
||||
@@ -51,9 +51,7 @@ async fn run(
|
||||
loop {
|
||||
let packets = device.take_send_queue();
|
||||
|
||||
async_iface
|
||||
.send_all(&mut iter(packets).map(|p| Ok(p)))
|
||||
.await?;
|
||||
async_iface.send_all(&mut iter(packets).map(Ok)).await?;
|
||||
|
||||
if recv_buf.is_empty() && device.need_wait() {
|
||||
let start = Instant::now();
|
||||
@@ -94,14 +92,10 @@ async fn run(
|
||||
|
||||
// wake up all closed sockets (smoltcp seems have a bug that it doesn't wake up closed sockets)
|
||||
for (_, socket) in socket_allocator.sockets().lock().iter_mut() {
|
||||
match socket {
|
||||
Socket::Tcp(tcp) => {
|
||||
if tcp.state() == smoltcp::socket::tcp::State::Closed {
|
||||
tcp.abort();
|
||||
}
|
||||
if let Socket::Tcp(tcp) = socket {
|
||||
if tcp.state() == smoltcp::socket::tcp::State::Closed {
|
||||
tcp.abort();
|
||||
}
|
||||
#[allow(unreachable_patterns)]
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,10 +158,8 @@ impl Reactor {
|
||||
impl Drop for Reactor {
|
||||
fn drop(&mut self) {
|
||||
for (_, socket) in self.socket_allocator.sockets().lock().iter_mut() {
|
||||
match socket {
|
||||
Socket::Tcp(tcp) => tcp.close(),
|
||||
#[allow(unreachable_patterns)]
|
||||
_ => {}
|
||||
if let Socket::Tcp(tcp) = socket {
|
||||
tcp.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ pub use smoltcp::socket::tcp;
|
||||
use smoltcp::socket::udp;
|
||||
use smoltcp::wire::{IpAddress, IpEndpoint};
|
||||
use std::mem::replace;
|
||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
use std::net::IpAddr;
|
||||
use std::{
|
||||
io,
|
||||
net::SocketAddr,
|
||||
@@ -25,7 +25,7 @@ pub struct TcpListener {
|
||||
}
|
||||
|
||||
fn map_err<E: std::error::Error>(e: E) -> io::Error {
|
||||
io::Error::new(io::ErrorKind::Other, e.to_string())
|
||||
io::Error::other(e.to_string())
|
||||
}
|
||||
|
||||
impl TcpListener {
|
||||
@@ -95,8 +95,8 @@ impl Stream for Incoming {
|
||||
|
||||
fn ep2sa(ep: &IpEndpoint) -> SocketAddr {
|
||||
match ep.addr {
|
||||
IpAddress::Ipv4(v4) => SocketAddr::new(IpAddr::V4(Ipv4Addr::from(v4)), ep.port),
|
||||
IpAddress::Ipv6(v6) => SocketAddr::new(IpAddr::V6(Ipv6Addr::from(v6)), ep.port),
|
||||
IpAddress::Ipv4(v4) => SocketAddr::new(IpAddr::V4(v4), ep.port),
|
||||
IpAddress::Ipv6(v6) => SocketAddr::new(IpAddr::V6(v6), ep.port),
|
||||
#[allow(unreachable_patterns)]
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ use tracing::Level;
|
||||
|
||||
use crate::{
|
||||
common::{error::Error, global_ctx::ArcGlobalCtx, scoped_task::ScopedTask, PeerId},
|
||||
gateway::ip_reassembler::compose_ipv4_packet,
|
||||
gateway::ip_reassembler::{compose_ipv4_packet, ComposeIpv4PacketArgs},
|
||||
peers::{peer_manager::PeerManager, PeerPacketFilter},
|
||||
tunnel::{
|
||||
common::{reserve_buf, setup_sokcet2},
|
||||
@@ -110,13 +110,15 @@ impl UdpNatEntry {
|
||||
));
|
||||
|
||||
compose_ipv4_packet(
|
||||
&mut buf[..],
|
||||
src_v4.ip(),
|
||||
nat_src_v4.ip(),
|
||||
IpNextHeaderProtocols::Udp,
|
||||
payload_len + 8, // include udp header
|
||||
payload_mtu,
|
||||
ip_id,
|
||||
ComposeIpv4PacketArgs {
|
||||
buf: &mut buf[..],
|
||||
src_v4: src_v4.ip(),
|
||||
dst_v4: nat_src_v4.ip(),
|
||||
next_protocol: IpNextHeaderProtocols::Udp,
|
||||
payload_len: payload_len + 8, // include udp header
|
||||
payload_mtu,
|
||||
ip_id,
|
||||
},
|
||||
|buf| {
|
||||
let mut p = ZCPacket::new_with_payload(buf);
|
||||
p.fill_peer_manager_hdr(self.my_peer_id, self.src_peer_id, PacketType::Data as u8);
|
||||
@@ -273,11 +275,12 @@ impl UdpProxy {
|
||||
}
|
||||
|
||||
let mut real_dst_ip = ipv4.get_destination();
|
||||
if !self
|
||||
|
||||
if !(self
|
||||
.cidr_set
|
||||
.contains_v4(ipv4.get_destination(), &mut real_dst_ip)
|
||||
&& !is_exit_node
|
||||
&& !(self.global_ctx.no_tun()
|
||||
|| is_exit_node
|
||||
|| self.global_ctx.no_tun()
|
||||
&& Some(ipv4.get_destination())
|
||||
== self.global_ctx.get_ipv4().as_ref().map(Ipv4Inet::address))
|
||||
{
|
||||
@@ -289,9 +292,7 @@ impl UdpProxy {
|
||||
resembled_buf =
|
||||
self.ip_resemmbler
|
||||
.add_fragment(ipv4.get_source(), ipv4.get_destination(), &ipv4);
|
||||
if resembled_buf.is_none() {
|
||||
return None;
|
||||
};
|
||||
resembled_buf.as_ref()?;
|
||||
udp::UdpPacket::new(resembled_buf.as_ref().unwrap())?
|
||||
} else {
|
||||
udp::UdpPacket::new(ipv4.payload())?
|
||||
@@ -374,7 +375,7 @@ impl UdpProxy {
|
||||
#[async_trait::async_trait]
|
||||
impl PeerPacketFilter for UdpProxy {
|
||||
async fn try_process_packet_from_peer(&self, packet: ZCPacket) -> Option<ZCPacket> {
|
||||
if let Some(_) = self.try_handle_packet(&packet).await {
|
||||
if self.try_handle_packet(&packet).await.is_some() {
|
||||
return None;
|
||||
} else {
|
||||
return Some(packet);
|
||||
|
||||
@@ -59,7 +59,7 @@ impl MagicDnsClientInstance {
|
||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
continue;
|
||||
}
|
||||
prev_last_update = Some(last_update);
|
||||
|
||||
let mut routes = peer_mgr.list_routes().await;
|
||||
// add self as a route
|
||||
let ctx = peer_mgr.get_global_ctx();
|
||||
@@ -79,6 +79,11 @@ impl MagicDnsClientInstance {
|
||||
rpc_stub
|
||||
.update_dns_record(BaseController::default(), req)
|
||||
.await?;
|
||||
|
||||
let last_update_after_rpc = peer_mgr.get_route_peer_info_last_update_time().await;
|
||||
if last_update_after_rpc == last_update {
|
||||
prev_last_update = Some(last_update);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ impl Record {
|
||||
}
|
||||
|
||||
fn rr_type(&self) -> rr::RecordType {
|
||||
self.rr_type.clone().into()
|
||||
self.rr_type
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ ttl = "61s"
|
||||
let (domain, records) = config
|
||||
.zones
|
||||
.get_key_value("et.internal")
|
||||
.map_or(Err(anyhow!("parse error")), |x| Ok(x))?;
|
||||
.ok_or(anyhow!("et.internal not found"))?;
|
||||
assert_eq!(domain, "et.internal");
|
||||
assert_eq!(records.len(), 1);
|
||||
let record = &records[0];
|
||||
@@ -179,7 +179,7 @@ ttl = "61s"
|
||||
let (domain, records) = config
|
||||
.zones
|
||||
.get_key_value("et.top")
|
||||
.map_or(Err(anyhow!("parse error")), |x| Ok(x))?;
|
||||
.ok_or(anyhow!("et.top not found"))?;
|
||||
assert_eq!(domain, "et.top");
|
||||
assert_eq!(records.len(), 1);
|
||||
let record = &records[0];
|
||||
|
||||
@@ -65,7 +65,7 @@ impl DnsRunner {
|
||||
self.client = Some(client);
|
||||
self.client.as_mut().unwrap().run_and_wait().await;
|
||||
|
||||
return Err(anyhow::anyhow!("Client instance exit"));
|
||||
Err(anyhow::anyhow!("Client instance exit"))
|
||||
}
|
||||
|
||||
pub async fn run(&mut self, canel_token: CancellationToken) {
|
||||
|
||||
@@ -96,12 +96,12 @@ impl Server {
|
||||
.0
|
||||
.name_servers()
|
||||
.iter()
|
||||
.cloned()
|
||||
.filter(|x| {
|
||||
.filter(|&x| {
|
||||
!config
|
||||
.excluded_forward_nameservers()
|
||||
.contains(&x.socket_addr.ip())
|
||||
})
|
||||
.cloned()
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
options: Some(system_conf.1),
|
||||
@@ -148,7 +148,7 @@ impl Server {
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"DNS Server failed to create UDP socket for address {}",
|
||||
address.to_string()
|
||||
address
|
||||
)
|
||||
})?;
|
||||
socket2::SockRef::from(&socket)
|
||||
@@ -156,7 +156,7 @@ impl Server {
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"DNS Server failed to set reuse address on socket {}",
|
||||
address.to_string()
|
||||
address
|
||||
)
|
||||
})?;
|
||||
socket.bind(&bind_addr.into()).with_context(|| {
|
||||
@@ -164,17 +164,17 @@ impl Server {
|
||||
})?;
|
||||
socket
|
||||
.set_nonblocking(true)
|
||||
.with_context(|| format!("DNS Server failed to set socket to non-blocking"))?;
|
||||
.with_context(|| "DNS Server failed to set socket to non-blocking".to_string())?;
|
||||
let socket = UdpSocket::from_std(socket.into()).with_context(|| {
|
||||
format!(
|
||||
"DNS Server failed to convert socket to UdpSocket for address {}",
|
||||
address.to_string()
|
||||
address
|
||||
)
|
||||
})?;
|
||||
|
||||
let local_addr = socket
|
||||
.local_addr()
|
||||
.with_context(|| format!("DNS Server failed to get local address"))?;
|
||||
.with_context(|| "DNS Server failed to get local address".to_string())?;
|
||||
self.server.register_socket(socket);
|
||||
|
||||
Ok(local_addr)
|
||||
|
||||
@@ -70,6 +70,20 @@ pub(super) struct MagicDnsServerInstanceData {
|
||||
}
|
||||
|
||||
impl MagicDnsServerInstanceData {
|
||||
fn is_valid_subdomain_label(s: &str) -> bool {
|
||||
let s = s.trim();
|
||||
|
||||
// 长度检查:1-63 个字符
|
||||
if s.is_empty() || s.len() > 63 {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查每个字符是否合法,并确保不以 '-' 开头或结尾
|
||||
s.chars().all(|c| matches!(c, 'a'..='z' | '0'..='9' | '-'))
|
||||
&& !s.starts_with('-')
|
||||
&& !s.ends_with('-')
|
||||
}
|
||||
|
||||
pub async fn update_dns_records<'a, T: Iterator<Item = &'a Route>>(
|
||||
&self,
|
||||
routes: T,
|
||||
@@ -81,6 +95,11 @@ impl MagicDnsServerInstanceData {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check host name valid for dns
|
||||
if !Self::is_valid_subdomain_label(&route.hostname) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let Some(ipv4_addr) = route.ipv4_addr.unwrap_or_default().address else {
|
||||
continue;
|
||||
};
|
||||
@@ -432,7 +451,7 @@ impl MagicDnsServerInstance {
|
||||
if !self.tun_inet.contains(&self.data.fake_ip) && self.data.tun_dev.is_some() {
|
||||
let ifcfg = IfConfiger {};
|
||||
let _ = ifcfg
|
||||
.remove_ipv4_route(&self.data.tun_dev.as_ref().unwrap(), self.data.fake_ip, 32)
|
||||
.remove_ipv4_route(self.data.tun_dev.as_ref().unwrap(), self.data.fake_ip, 32)
|
||||
.await;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,13 +26,19 @@ struct DNSConfigError {
|
||||
source: Option<anyhow::Error>,
|
||||
}
|
||||
|
||||
type DbusPingFn = dyn Fn(&str, &str) -> Result<()>;
|
||||
type DbusReadStringFn = dyn Fn(&str, &str, &str, &str) -> Result<String>;
|
||||
type NmIsUsingResolvedFn = dyn Fn() -> Result<()>;
|
||||
type NmVersionBetweenFn = dyn Fn(&str, &str) -> Result<bool>;
|
||||
type ResolvconfStyleFn = dyn Fn() -> String;
|
||||
|
||||
// 配置环境结构体
|
||||
struct OSConfigEnv {
|
||||
fs: Box<dyn FileSystem>,
|
||||
dbus_ping: Box<dyn Fn(&str, &str) -> Result<()>>,
|
||||
dbus_read_string: Box<dyn Fn(&str, &str, &str, &str) -> Result<String>>,
|
||||
nm_is_using_resolved: Box<dyn Fn() -> Result<()>>,
|
||||
nm_version_between: Box<dyn Fn(&str, &str) -> Result<bool>>,
|
||||
dbus_ping: Box<DbusPingFn>,
|
||||
dbus_read_string: Box<DbusReadStringFn>,
|
||||
nm_is_using_resolved: Box<NmIsUsingResolvedFn>,
|
||||
nm_version_between: Box<NmVersionBetweenFn>,
|
||||
resolvconf_style: Box<dyn Fn() -> String>,
|
||||
}
|
||||
|
||||
@@ -86,8 +92,7 @@ pub fn nm_is_using_resolved() -> Result<()> {
|
||||
return Err(anyhow::anyhow!(
|
||||
"NetworkManager is not using systemd-resolved, found: {:?}",
|
||||
value
|
||||
)
|
||||
.into());
|
||||
));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -41,7 +41,7 @@ pub async fn prepare_env(dns_name: &str, tun_ip: Ipv4Inet) -> (Arc<PeerManager>,
|
||||
|
||||
pub async fn check_dns_record(fake_ip: &Ipv4Addr, domain: &str, expected_ip: &str) {
|
||||
let stream = UdpClientStream::builder(
|
||||
SocketAddr::new(fake_ip.clone().into(), 53),
|
||||
SocketAddr::new((*fake_ip).into(), 53),
|
||||
TokioRuntimeProvider::default(),
|
||||
)
|
||||
.build();
|
||||
|
||||
@@ -258,7 +258,7 @@ pub struct Instance {
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
pub fn new(config: impl ConfigLoader + Send + Sync + 'static) -> Self {
|
||||
pub fn new(config: impl ConfigLoader + 'static) -> Self {
|
||||
let global_ctx = Arc::new(GlobalCtx::new(config));
|
||||
|
||||
tracing::info!(
|
||||
@@ -304,10 +304,10 @@ impl Instance {
|
||||
#[cfg(feature = "socks5")]
|
||||
let socks5_server = Socks5Server::new(global_ctx.clone(), peer_manager.clone(), None);
|
||||
|
||||
let rpc_server = global_ctx.config.get_rpc_portal().and_then(|s| {
|
||||
Some(StandAloneServer::new(TcpTunnelListener::new(
|
||||
let rpc_server = global_ctx.config.get_rpc_portal().map(|s| {
|
||||
StandAloneServer::new(TcpTunnelListener::new(
|
||||
format!("tcp://{}", s).parse().unwrap(),
|
||||
)))
|
||||
))
|
||||
});
|
||||
|
||||
Instance {
|
||||
@@ -470,7 +470,7 @@ impl Instance {
|
||||
continue;
|
||||
}
|
||||
|
||||
let last_ip = current_dhcp_ip.clone();
|
||||
let last_ip = current_dhcp_ip;
|
||||
tracing::debug!(
|
||||
?current_dhcp_ip,
|
||||
?candidate_ipv4_addr,
|
||||
@@ -509,11 +509,7 @@ impl Instance {
|
||||
Self::use_new_nic_ctx(
|
||||
nic_ctx.clone(),
|
||||
new_nic_ctx,
|
||||
Self::create_magic_dns_runner(
|
||||
peer_manager_c.clone(),
|
||||
ifname,
|
||||
ip.clone(),
|
||||
),
|
||||
Self::create_magic_dns_runner(peer_manager_c.clone(), ifname, ip),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
@@ -890,7 +886,7 @@ impl Instance {
|
||||
) -> Result<GetStatsResponse, rpc_types::error::Error> {
|
||||
let stats_manager = self.global_ctx.stats_manager();
|
||||
let snapshots = stats_manager.get_all_metrics();
|
||||
|
||||
|
||||
let metrics = snapshots
|
||||
.into_iter()
|
||||
.map(|snapshot| {
|
||||
@@ -898,7 +894,7 @@ impl Instance {
|
||||
for label in snapshot.labels.labels() {
|
||||
labels.insert(label.key.clone(), label.value.clone());
|
||||
}
|
||||
|
||||
|
||||
MetricSnapshot {
|
||||
name: snapshot.name_str(),
|
||||
value: snapshot.value,
|
||||
@@ -906,7 +902,7 @@ impl Instance {
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
||||
Ok(GetStatsResponse { metrics })
|
||||
}
|
||||
|
||||
@@ -917,7 +913,7 @@ impl Instance {
|
||||
) -> Result<GetPrometheusStatsResponse, rpc_types::error::Error> {
|
||||
let stats_manager = self.global_ctx.stats_manager();
|
||||
let prometheus_text = stats_manager.export_prometheus();
|
||||
|
||||
|
||||
Ok(GetPrometheusStatsResponse { prometheus_text })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ pub fn get_listener_by_url(
|
||||
}
|
||||
|
||||
pub fn is_url_host_ipv6(l: &url::Url) -> bool {
|
||||
l.host_str().map_or(false, |h| h.contains(':'))
|
||||
l.host_str().is_some_and(|h| h.contains(':'))
|
||||
}
|
||||
|
||||
pub fn is_url_host_unspecified(l: &url::Url) -> bool {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
pub mod dns_server;
|
||||
#[allow(clippy::module_inception)]
|
||||
pub mod instance;
|
||||
|
||||
pub mod listeners;
|
||||
|
||||
#[cfg(feature = "tun")]
|
||||
|
||||
@@ -68,10 +68,10 @@ impl Stream for TunStream {
|
||||
type Item = StreamItem;
|
||||
|
||||
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<StreamItem>> {
|
||||
let mut self_mut = self.project();
|
||||
let self_mut = self.project();
|
||||
let mut g = ready!(self_mut.l.poll_lock(cx));
|
||||
reserve_buf(&mut self_mut.cur_buf, 2500, 4 * 1024);
|
||||
if self_mut.cur_buf.len() == 0 {
|
||||
reserve_buf(self_mut.cur_buf, 2500, 4 * 1024);
|
||||
if self_mut.cur_buf.is_empty() {
|
||||
unsafe {
|
||||
self_mut.cur_buf.set_len(*self_mut.payload_offset);
|
||||
}
|
||||
@@ -117,10 +117,7 @@ impl PacketProtocol {
|
||||
match self {
|
||||
PacketProtocol::IPv4 => Ok(libc::ETH_P_IP as u16),
|
||||
PacketProtocol::IPv6 => Ok(libc::ETH_P_IPV6 as u16),
|
||||
PacketProtocol::Other(_) => Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"neither an IPv4 nor IPv6 packet",
|
||||
)),
|
||||
PacketProtocol::Other(_) => Err(io::Error::other("neither an IPv4 nor IPv6 packet")),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,7 +172,7 @@ impl TunZCPacketToBytes {
|
||||
}
|
||||
|
||||
impl ZCPacketToBytes for TunZCPacketToBytes {
|
||||
fn into_bytes(&self, zc_packet: ZCPacket) -> Result<Bytes, TunnelError> {
|
||||
fn zcpacket_into_bytes(&self, zc_packet: ZCPacket) -> Result<Bytes, TunnelError> {
|
||||
let payload_offset = zc_packet.payload_offset();
|
||||
let mut inner = zc_packet.inner();
|
||||
// we have peer manager header, so payload offset must larger than 4
|
||||
@@ -383,11 +380,11 @@ impl VirtualNic {
|
||||
|
||||
let dev_name = self.global_ctx.get_flags().dev_name;
|
||||
if !dev_name.is_empty() {
|
||||
config.tun_name(format!("{}", dev_name));
|
||||
config.tun_name(&dev_name);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos"))]
|
||||
#[cfg(target_os = "macos")]
|
||||
config.platform_config(|config| {
|
||||
// disable packet information so we can process the header by ourselves, see tun2 impl for more details
|
||||
config.packet_information(false);
|
||||
@@ -515,9 +512,7 @@ impl VirtualNic {
|
||||
{
|
||||
// set mtu by ourselves, rust-tun does not handle it correctly on windows
|
||||
let _g = self.global_ctx.net_ns.guard();
|
||||
self.ifcfg
|
||||
.set_mtu(ifname.as_str(), mtu_in_config as u32)
|
||||
.await?;
|
||||
self.ifcfg.set_mtu(ifname.as_str(), mtu_in_config).await?;
|
||||
}
|
||||
|
||||
let has_packet_info = cfg!(target_os = "macos");
|
||||
@@ -643,7 +638,7 @@ impl NicCtx {
|
||||
) -> Self {
|
||||
NicCtx {
|
||||
global_ctx: global_ctx.clone(),
|
||||
peer_mgr: Arc::downgrade(&peer_manager),
|
||||
peer_mgr: Arc::downgrade(peer_manager),
|
||||
peer_packet_receiver,
|
||||
nic: Arc::new(Mutex::new(VirtualNic::new(global_ctx))),
|
||||
tasks: JoinSet::new(),
|
||||
|
||||
@@ -18,6 +18,12 @@ pub struct NetworkInstanceManager {
|
||||
stop_check_notifier: Arc<tokio::sync::Notify>,
|
||||
}
|
||||
|
||||
impl Default for NetworkInstanceManager {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl NetworkInstanceManager {
|
||||
pub fn new() -> Self {
|
||||
NetworkInstanceManager {
|
||||
@@ -65,11 +71,9 @@ impl NetworkInstanceManager {
|
||||
let Some(instance_stop_notifier) = instance_stop_notifier else {
|
||||
return;
|
||||
};
|
||||
let _t = if let Some(event) = instance_event_receiver.flatten() {
|
||||
Some(ScopedTask::from(handle_event(instance_id, event)))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let _t = instance_event_receiver
|
||||
.flatten()
|
||||
.map(|event| ScopedTask::from(handle_event(instance_id, event)));
|
||||
instance_stop_notifier.notified().await;
|
||||
if let Some(instance) = instance_map.get(&instance_id) {
|
||||
if let Some(e) = instance.get_latest_error_msg() {
|
||||
@@ -124,17 +128,14 @@ impl NetworkInstanceManager {
|
||||
let mut ret = BTreeMap::new();
|
||||
for instance in self.instance_map.iter() {
|
||||
if let Some(info) = instance.get_running_info() {
|
||||
ret.insert(instance.key().clone(), info);
|
||||
ret.insert(*instance.key(), info);
|
||||
}
|
||||
}
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
pub fn list_network_instance_ids(&self) -> Vec<uuid::Uuid> {
|
||||
self.instance_map
|
||||
.iter()
|
||||
.map(|item| item.key().clone())
|
||||
.collect()
|
||||
self.instance_map.iter().map(|item| *item.key()).collect()
|
||||
}
|
||||
|
||||
pub fn get_network_instance_name(&self, instance_id: &uuid::Uuid) -> Option<String> {
|
||||
@@ -299,8 +300,8 @@ fn handle_event(
|
||||
instance_id,
|
||||
format!(
|
||||
"port forward added. local: {}, remote: {}, proto: {}",
|
||||
cfg.bind_addr.unwrap().to_string(),
|
||||
cfg.dst_addr.unwrap().to_string(),
|
||||
cfg.bind_addr.unwrap(),
|
||||
cfg.dst_addr.unwrap(),
|
||||
cfg.socket_type().as_str_name()
|
||||
),
|
||||
);
|
||||
@@ -347,9 +348,8 @@ mod tests {
|
||||
let instance_id1 = manager
|
||||
.run_network_instance(
|
||||
TomlConfigLoader::new_from_str(cfg_str)
|
||||
.map(|c| {
|
||||
.inspect(|c| {
|
||||
c.set_listeners(vec![format!("tcp://0.0.0.0:{}", port).parse().unwrap()]);
|
||||
c
|
||||
})
|
||||
.unwrap(),
|
||||
ConfigSource::Cli,
|
||||
@@ -426,9 +426,8 @@ mod tests {
|
||||
assert!(manager
|
||||
.run_network_instance(
|
||||
TomlConfigLoader::new_from_str(cfg_str)
|
||||
.map(|c| {
|
||||
.inspect(|c| {
|
||||
c.set_listeners(vec![format!("tcp://0.0.0.0:{}", port).parse().unwrap()]);
|
||||
c
|
||||
})
|
||||
.unwrap(),
|
||||
ConfigSource::GUI,
|
||||
|
||||
+38
-41
@@ -1,8 +1,5 @@
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
sync::{atomic::AtomicBool, Arc, RwLock},
|
||||
};
|
||||
use std::net::SocketAddr;
|
||||
use crate::common::config::PortForwardConfig;
|
||||
use crate::proto::web;
|
||||
use crate::{
|
||||
common::{
|
||||
config::{
|
||||
@@ -19,9 +16,12 @@ use crate::{
|
||||
};
|
||||
use anyhow::Context;
|
||||
use chrono::{DateTime, Local};
|
||||
use std::net::SocketAddr;
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
sync::{atomic::AtomicBool, Arc, RwLock},
|
||||
};
|
||||
use tokio::{sync::broadcast, task::JoinSet};
|
||||
use crate::common::config::PortForwardConfig;
|
||||
use crate::proto::web;
|
||||
|
||||
pub type MyNodeInfo = crate::proto::web::MyNodeInfo;
|
||||
|
||||
@@ -89,7 +89,7 @@ impl EasyTierLauncher {
|
||||
let _ = data.event_subscriber.read().unwrap().send(event.clone());
|
||||
events.push_front(Event {
|
||||
time: chrono::Local::now(),
|
||||
event: event,
|
||||
event,
|
||||
});
|
||||
if events.len() > 20 {
|
||||
events.pop_back();
|
||||
@@ -380,9 +380,7 @@ impl NetworkInstance {
|
||||
}
|
||||
|
||||
pub fn get_running_info(&self) -> Option<NetworkInstanceRunningInfo> {
|
||||
if self.launcher.is_none() {
|
||||
return None;
|
||||
}
|
||||
self.launcher.as_ref()?;
|
||||
|
||||
let launcher = self.launcher.as_ref().unwrap();
|
||||
|
||||
@@ -434,19 +432,15 @@ impl NetworkInstance {
|
||||
}
|
||||
|
||||
pub fn subscribe_event(&self) -> Option<broadcast::Receiver<GlobalCtxEvent>> {
|
||||
if let Some(launcher) = self.launcher.as_ref() {
|
||||
Some(launcher.data.event_subscriber.read().unwrap().subscribe())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
self.launcher
|
||||
.as_ref()
|
||||
.map(|launcher| launcher.data.event_subscriber.read().unwrap().subscribe())
|
||||
}
|
||||
|
||||
pub fn get_stop_notifier(&self) -> Option<Arc<tokio::sync::Notify>> {
|
||||
if let Some(launcher) = self.launcher.as_ref() {
|
||||
Some(launcher.data.instance_stop_notifier.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
self.launcher
|
||||
.as_ref()
|
||||
.map(|launcher| launcher.data.instance_stop_notifier.clone())
|
||||
}
|
||||
|
||||
pub fn get_latest_error_msg(&self) -> Option<String> {
|
||||
@@ -511,7 +505,7 @@ impl NetworkConfig {
|
||||
|
||||
if !cfg.get_dhcp() {
|
||||
let virtual_ipv4 = self.virtual_ipv4.clone().unwrap_or_default();
|
||||
if virtual_ipv4.len() > 0 {
|
||||
if !virtual_ipv4.is_empty() {
|
||||
let ip = format!("{}/{}", virtual_ipv4, self.network_length.unwrap_or(24))
|
||||
.parse()
|
||||
.with_context(|| {
|
||||
@@ -596,8 +590,10 @@ impl NetworkConfig {
|
||||
.iter()
|
||||
.filter(|pf| !pf.bind_ip.is_empty() && !pf.dst_ip.is_empty())
|
||||
.filter_map(|pf| {
|
||||
let bind_addr = format!("{}:{}", pf.bind_ip, pf.bind_port).parse::<SocketAddr>();
|
||||
let dst_addr = format!("{}:{}", pf.dst_ip, pf.dst_port).parse::<SocketAddr>();
|
||||
let bind_addr =
|
||||
format!("{}:{}", pf.bind_ip, pf.bind_port).parse::<SocketAddr>();
|
||||
let dst_addr =
|
||||
format!("{}:{}", pf.dst_ip, pf.dst_port).parse::<SocketAddr>();
|
||||
|
||||
match (bind_addr, dst_addr) {
|
||||
(Ok(bind_addr), Ok(dst_addr)) => Some(PortForwardConfig {
|
||||
@@ -608,7 +604,7 @@ impl NetworkConfig {
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -650,7 +646,7 @@ impl NetworkConfig {
|
||||
cfg.set_routes(Some(routes));
|
||||
}
|
||||
|
||||
if self.exit_nodes.len() > 0 {
|
||||
if !self.exit_nodes.is_empty() {
|
||||
let mut exit_nodes = Vec::<std::net::IpAddr>::with_capacity(self.exit_nodes.len());
|
||||
for node in self.exit_nodes.iter() {
|
||||
exit_nodes.push(
|
||||
@@ -669,7 +665,7 @@ impl NetworkConfig {
|
||||
}
|
||||
}
|
||||
|
||||
if self.mapped_listeners.len() > 0 {
|
||||
if !self.mapped_listeners.is_empty() {
|
||||
cfg.set_mapped_listeners(Some(
|
||||
self.mapped_listeners
|
||||
.iter()
|
||||
@@ -754,7 +750,7 @@ impl NetworkConfig {
|
||||
}
|
||||
|
||||
if self.enable_relay_network_whitelist.unwrap_or_default() {
|
||||
if self.relay_network_whitelist.len() > 0 {
|
||||
if !self.relay_network_whitelist.is_empty() {
|
||||
flags.relay_network_whitelist = self.relay_network_whitelist.join(" ");
|
||||
} else {
|
||||
flags.relay_network_whitelist = "".to_string();
|
||||
@@ -784,7 +780,9 @@ impl NetworkConfig {
|
||||
pub fn new_from_config(config: &TomlConfigLoader) -> Result<Self, anyhow::Error> {
|
||||
let default_config = TomlConfigLoader::default();
|
||||
|
||||
let mut result = Self::default();
|
||||
let mut result = Self {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
result.instance_id = Some(config.get_id().to_string());
|
||||
if config.get_hostname() != default_config.get_hostname() {
|
||||
@@ -819,7 +817,7 @@ impl NetworkConfig {
|
||||
|
||||
result.listener_urls = config
|
||||
.get_listeners()
|
||||
.unwrap_or_else(|| vec![])
|
||||
.unwrap_or_default()
|
||||
.iter()
|
||||
.map(|l| l.to_string())
|
||||
.collect();
|
||||
@@ -846,17 +844,16 @@ impl NetworkConfig {
|
||||
|
||||
let port_forwards = config.get_port_forwards();
|
||||
if !port_forwards.is_empty() {
|
||||
result.port_forwards = port_forwards.iter()
|
||||
.map(|f| {
|
||||
web::PortForwardConfig {
|
||||
proto: f.proto.clone(),
|
||||
bind_ip: f.bind_addr.ip().to_string(),
|
||||
bind_port: f.bind_addr.port() as u32,
|
||||
dst_ip: f.dst_addr.ip().to_string(),
|
||||
dst_port: f.dst_addr.port() as u32,
|
||||
}
|
||||
}).
|
||||
collect();
|
||||
result.port_forwards = port_forwards
|
||||
.iter()
|
||||
.map(|f| web::PortForwardConfig {
|
||||
proto: f.proto.clone(),
|
||||
bind_ip: f.bind_addr.ip().to_string(),
|
||||
bind_port: f.bind_addr.port() as u32,
|
||||
dst_ip: f.dst_addr.ip().to_string(),
|
||||
dst_port: f.dst_addr.port() as u32,
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
|
||||
if let Some(vpn_config) = config.get_vpn_portal_config() {
|
||||
|
||||
+3
-3
@@ -13,8 +13,8 @@ mod vpn_portal;
|
||||
|
||||
pub mod common;
|
||||
pub mod connector;
|
||||
pub mod launcher;
|
||||
pub mod instance_manager;
|
||||
pub mod launcher;
|
||||
pub mod peers;
|
||||
pub mod proto;
|
||||
pub mod tunnel;
|
||||
@@ -27,6 +27,6 @@ mod tests;
|
||||
pub const VERSION: &str = common::constants::EASYTIER_VERSION;
|
||||
rust_i18n::i18n!("locales", fallback = "en");
|
||||
|
||||
pub fn print_completions<G: Generator>(generator: G, cmd: &mut Command, bin_name:&str) {
|
||||
pub fn print_completions<G: Generator>(generator: G, cmd: &mut Command, bin_name: &str) {
|
||||
clap_complete::generate(generator, cmd, bin_name, &mut io::stdout());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,13 +97,13 @@ impl PeerCenterBase {
|
||||
&self,
|
||||
job_ctx: T,
|
||||
job_fn: impl Fn(
|
||||
Box<dyn PeerCenterRpc<Controller = BaseController> + Send>,
|
||||
Arc<PeridicJobCtx<T>>,
|
||||
) -> Fut
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
) -> () {
|
||||
Box<dyn PeerCenterRpc<Controller = BaseController> + Send>,
|
||||
Arc<PeridicJobCtx<T>>,
|
||||
) -> Fut
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
) {
|
||||
let my_peer_id = self.my_peer_id;
|
||||
let peer_mgr = self.peer_mgr.clone();
|
||||
let lock = self.lock.clone();
|
||||
@@ -126,7 +126,7 @@ impl PeerCenterBase {
|
||||
return;
|
||||
};
|
||||
|
||||
ctx.center_peer.store(center_peer.clone());
|
||||
ctx.center_peer.store(center_peer);
|
||||
tracing::trace!(?center_peer, "run periodic job");
|
||||
let _g = lock.lock().await;
|
||||
let stub = rpc_mgr
|
||||
@@ -310,7 +310,7 @@ impl PeerCenterInstance {
|
||||
.init_periodic_job(ctx, |client, ctx| async move {
|
||||
let my_node_id = ctx.my_peer_id;
|
||||
let peers = ctx.job_ctx.peer_mgr.list_peers().await;
|
||||
let peer_list = peers.direct_peers.keys().map(|k| *k).collect();
|
||||
let peer_list = peers.direct_peers.keys().copied().collect();
|
||||
let job_ctx = &ctx.job_ctx;
|
||||
|
||||
// only report when:
|
||||
@@ -370,7 +370,7 @@ impl PeerCenterInstance {
|
||||
.map
|
||||
.get(&src)
|
||||
.and_then(|src_peer_info| src_peer_info.direct_peers.get(&dst))
|
||||
.and_then(|info| Some(info.latency_ms))
|
||||
.map(|info| info.latency_ms)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -503,7 +503,7 @@ mod tests {
|
||||
let peer_center_b = PeerCenterInstance::new(peer_mgr_b.clone());
|
||||
let peer_center_c = PeerCenterInstance::new(peer_mgr_c.clone());
|
||||
|
||||
let peer_centers = vec![&peer_center_a, &peer_center_b, &peer_center_c];
|
||||
let peer_centers = [&peer_center_a, &peer_center_b, &peer_center_c];
|
||||
for pc in peer_centers.iter() {
|
||||
pc.init().await;
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ impl PeerCenterRpc for PeerCenterServer {
|
||||
direct_peers: Default::default(),
|
||||
})
|
||||
.direct_peers
|
||||
.insert(pair.dst, entry.info.clone());
|
||||
.insert(pair.dst, entry.info);
|
||||
}
|
||||
|
||||
Ok(GetGlobalPeerMapResponse {
|
||||
|
||||
@@ -27,6 +27,12 @@ pub struct AclFilter {
|
||||
acl_enabled: Arc<AtomicBool>,
|
||||
}
|
||||
|
||||
impl Default for AclFilter {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl AclFilter {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
@@ -75,8 +81,8 @@ impl AclFilter {
|
||||
let rules_stats = processor.get_rules_stats();
|
||||
|
||||
AclStats {
|
||||
global: global_stats.into_iter().map(|(k, v)| (k, v)).collect(),
|
||||
conn_track: conn_track.iter().map(|x| x.value().clone()).collect(),
|
||||
global: global_stats.into_iter().collect(),
|
||||
conn_track: conn_track.iter().map(|x| *x.value()).collect(),
|
||||
rules: rules_stats,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,21 +15,21 @@ pub struct AesGcmCipher {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum AesGcmEnum {
|
||||
AES128GCM(Aes128Gcm),
|
||||
AES256GCM(Aes256Gcm),
|
||||
AES128GCM(Box<Aes128Gcm>),
|
||||
AES256GCM(Box<Aes256Gcm>),
|
||||
}
|
||||
|
||||
impl AesGcmCipher {
|
||||
pub fn new_128(key: [u8; 16]) -> Self {
|
||||
let key: &Key<Aes128Gcm> = &key.into();
|
||||
Self {
|
||||
cipher: AesGcmEnum::AES128GCM(Aes128Gcm::new(key)),
|
||||
cipher: AesGcmEnum::AES128GCM(Box::new(Aes128Gcm::new(key))),
|
||||
}
|
||||
}
|
||||
pub fn new_256(key: [u8; 32]) -> Self {
|
||||
let key: &Key<Aes256Gcm> = &key.into();
|
||||
Self {
|
||||
cipher: AesGcmEnum::AES256GCM(Aes256Gcm::new(key)),
|
||||
cipher: AesGcmEnum::AES256GCM(Box::new(Aes256Gcm::new(key))),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,7 @@ impl Encryptor for AesGcmCipher {
|
||||
zc_packet
|
||||
.mut_inner()
|
||||
.truncate(old_len - AES_GCM_ENCRYPTION_RESERVED);
|
||||
return Ok(());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encrypt(&self, zc_packet: &mut ZCPacket) -> Result<(), Error> {
|
||||
@@ -104,7 +104,7 @@ impl Encryptor for AesGcmCipher {
|
||||
}
|
||||
};
|
||||
|
||||
return match rs {
|
||||
match rs {
|
||||
Ok(tag) => {
|
||||
tail.tag.copy_from_slice(tag.as_slice());
|
||||
|
||||
@@ -114,7 +114,7 @@ impl Encryptor for AesGcmCipher {
|
||||
Ok(())
|
||||
}
|
||||
Err(_) => Err(Error::EncryptionFailed),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,10 +137,10 @@ mod tests {
|
||||
packet.payload().len(),
|
||||
text.len() + AES_GCM_ENCRYPTION_RESERVED
|
||||
);
|
||||
assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), true);
|
||||
assert!(packet.peer_manager_header().unwrap().is_encrypted());
|
||||
|
||||
cipher.decrypt(&mut packet).unwrap();
|
||||
assert_eq!(packet.payload(), text);
|
||||
assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), false);
|
||||
assert!(!packet.peer_manager_header().unwrap().is_encrypted());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ impl Encryptor for NullCipher {
|
||||
fn decrypt(&self, zc_packet: &mut ZCPacket) -> Result<(), Error> {
|
||||
let pm_header = zc_packet.peer_manager_header().unwrap();
|
||||
if pm_header.is_encrypted() {
|
||||
return Err(Error::DecryptionFailed);
|
||||
Err(Error::DecryptionFailed)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -212,12 +212,12 @@ mod tests {
|
||||
// 加密
|
||||
cipher.encrypt(&mut packet).unwrap();
|
||||
assert!(packet.payload().len() > text.len() + OPENSSL_ENCRYPTION_RESERVED);
|
||||
assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), true);
|
||||
assert!(packet.peer_manager_header().unwrap().is_encrypted());
|
||||
|
||||
// 解密
|
||||
cipher.decrypt(&mut packet).unwrap();
|
||||
assert_eq!(packet.payload(), text);
|
||||
assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), false);
|
||||
assert!(!packet.peer_manager_header().unwrap().is_encrypted());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -231,11 +231,11 @@ mod tests {
|
||||
// 加密
|
||||
cipher.encrypt(&mut packet).unwrap();
|
||||
assert!(packet.payload().len() > text.len());
|
||||
assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), true);
|
||||
assert!(packet.peer_manager_header().unwrap().is_encrypted());
|
||||
|
||||
// 解密
|
||||
cipher.decrypt(&mut packet).unwrap();
|
||||
assert_eq!(packet.payload(), text);
|
||||
assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), false);
|
||||
assert!(!packet.peer_manager_header().unwrap().is_encrypted());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ impl Encryptor for AesGcmCipher {
|
||||
let text_and_tag_len = payload_len - AES_GCM_ENCRYPTION_RESERVED + 16;
|
||||
|
||||
let aes_tail = AesGcmTail::ref_from_suffix(zc_packet.payload()).unwrap();
|
||||
let nonce = aead::Nonce::assume_unique_for_key(aes_tail.nonce.clone());
|
||||
let nonce = aead::Nonce::assume_unique_for_key(aes_tail.nonce);
|
||||
|
||||
let rs = match &self.cipher {
|
||||
AesGcmEnum::AesGCM128(cipher, _) => cipher.open_in_place(
|
||||
@@ -79,7 +79,7 @@ impl Encryptor for AesGcmCipher {
|
||||
&mut zc_packet.mut_payload()[..text_and_tag_len],
|
||||
),
|
||||
};
|
||||
if let Err(_) = rs {
|
||||
if rs.is_err() {
|
||||
return Err(Error::DecryptionFailed);
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ impl Encryptor for AesGcmCipher {
|
||||
zc_packet
|
||||
.mut_inner()
|
||||
.truncate(old_len - AES_GCM_ENCRYPTION_RESERVED);
|
||||
return Ok(());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encrypt(&self, zc_packet: &mut ZCPacket) -> Result<(), Error> {
|
||||
@@ -101,7 +101,7 @@ impl Encryptor for AesGcmCipher {
|
||||
|
||||
let mut tail = AesGcmTail::default();
|
||||
rand::thread_rng().fill_bytes(&mut tail.nonce);
|
||||
let nonce = aead::Nonce::assume_unique_for_key(tail.nonce.clone());
|
||||
let nonce = aead::Nonce::assume_unique_for_key(tail.nonce);
|
||||
|
||||
let rs = match &self.cipher {
|
||||
AesGcmEnum::AesGCM128(cipher, _) => cipher.seal_in_place_separate_tag(
|
||||
@@ -115,7 +115,7 @@ impl Encryptor for AesGcmCipher {
|
||||
zc_packet.mut_payload(),
|
||||
),
|
||||
};
|
||||
return match rs {
|
||||
match rs {
|
||||
Ok(tag) => {
|
||||
let tag = tag.as_ref();
|
||||
if tag.len() != 16 {
|
||||
@@ -129,7 +129,7 @@ impl Encryptor for AesGcmCipher {
|
||||
Ok(())
|
||||
}
|
||||
Err(_) => Err(Error::EncryptionFailed),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,10 +152,10 @@ mod tests {
|
||||
packet.payload().len(),
|
||||
text.len() + AES_GCM_ENCRYPTION_RESERVED
|
||||
);
|
||||
assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), true);
|
||||
assert!(packet.peer_manager_header().unwrap().is_encrypted());
|
||||
|
||||
cipher.decrypt(&mut packet).unwrap();
|
||||
assert_eq!(packet.payload(), text);
|
||||
assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), false);
|
||||
assert!(!packet.peer_manager_header().unwrap().is_encrypted());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ impl Encryptor for RingChaCha20Cipher {
|
||||
let text_and_tag_len = payload_len - CHACHA20_POLY1305_ENCRYPTION_RESERVED + 16;
|
||||
|
||||
let chacha20_tail = ChaCha20Poly1305Tail::ref_from_suffix(zc_packet.payload()).unwrap();
|
||||
let nonce = Nonce::assume_unique_for_key(chacha20_tail.nonce.clone());
|
||||
let nonce = Nonce::assume_unique_for_key(chacha20_tail.nonce);
|
||||
|
||||
let rs = self.cipher.open_in_place(
|
||||
nonce,
|
||||
@@ -75,7 +75,7 @@ impl Encryptor for RingChaCha20Cipher {
|
||||
|
||||
let mut tail = ChaCha20Poly1305Tail::default();
|
||||
rand::thread_rng().fill_bytes(&mut tail.nonce);
|
||||
let nonce = Nonce::assume_unique_for_key(tail.nonce.clone());
|
||||
let nonce = Nonce::assume_unique_for_key(tail.nonce);
|
||||
|
||||
let rs =
|
||||
self.cipher
|
||||
@@ -116,10 +116,10 @@ mod tests {
|
||||
packet.payload().len(),
|
||||
text.len() + CHACHA20_POLY1305_ENCRYPTION_RESERVED
|
||||
);
|
||||
assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), true);
|
||||
assert!(packet.peer_manager_header().unwrap().is_encrypted());
|
||||
|
||||
cipher.decrypt(&mut packet).unwrap();
|
||||
assert_eq!(packet.payload(), text);
|
||||
assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), false);
|
||||
assert!(!packet.peer_manager_header().unwrap().is_encrypted());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,12 +75,12 @@ mod tests {
|
||||
|
||||
// 加密
|
||||
cipher.encrypt(&mut packet).unwrap();
|
||||
assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), true);
|
||||
assert!(packet.peer_manager_header().unwrap().is_encrypted());
|
||||
assert_ne!(packet.payload(), text); // 加密后数据应该不同
|
||||
|
||||
// 解密
|
||||
cipher.decrypt(&mut packet).unwrap();
|
||||
assert_eq!(packet.payload(), text);
|
||||
assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), false);
|
||||
assert!(!packet.peer_manager_header().unwrap().is_encrypted());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ impl ForeignNetworkClient {
|
||||
|
||||
pub fn get_next_hop(&self, peer_id: PeerId) -> Option<PeerId> {
|
||||
if self.peer_map.has_peer(peer_id) {
|
||||
return Some(peer_id.clone());
|
||||
return Some(peer_id);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
@@ -362,31 +362,32 @@ impl ForeignNetworkEntry {
|
||||
.get_gateway_peer_id(to_peer_id, NextHopPolicy::LeastHop)
|
||||
.await;
|
||||
|
||||
if gateway_peer_id.is_some() && peer_map.has_peer(gateway_peer_id.unwrap()) {
|
||||
if let Err(e) = peer_map
|
||||
.send_msg_directly(zc_packet, gateway_peer_id.unwrap())
|
||||
.await
|
||||
{
|
||||
tracing::error!(
|
||||
?e,
|
||||
"send packet to foreign peer inside peer map failed"
|
||||
match gateway_peer_id {
|
||||
Some(peer_id) if peer_map.has_peer(peer_id) => {
|
||||
if let Err(e) = peer_map.send_msg_directly(zc_packet, peer_id).await {
|
||||
tracing::error!(
|
||||
?e,
|
||||
"send packet to foreign peer inside peer map failed"
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let mut foreign_packet = ZCPacket::new_for_foreign_network(
|
||||
&network_name,
|
||||
to_peer_id,
|
||||
&zc_packet,
|
||||
);
|
||||
let via_peer = gateway_peer_id.unwrap_or(to_peer_id);
|
||||
foreign_packet.fill_peer_manager_hdr(
|
||||
my_node_id,
|
||||
via_peer,
|
||||
PacketType::ForeignNetworkPacket as u8,
|
||||
);
|
||||
if let Err(e) = pm_sender.send(foreign_packet).await {
|
||||
tracing::error!("send packet to peer with pm failed: {:?}", e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let mut foreign_packet = ZCPacket::new_for_foreign_network(
|
||||
&network_name,
|
||||
to_peer_id,
|
||||
&zc_packet,
|
||||
);
|
||||
foreign_packet.fill_peer_manager_hdr(
|
||||
my_node_id,
|
||||
gateway_peer_id.unwrap_or(to_peer_id),
|
||||
PacketType::ForeignNetworkPacket as u8,
|
||||
);
|
||||
if let Err(e) = pm_sender.send(foreign_packet).await {
|
||||
tracing::error!("send packet to peer with pm failed: {:?}", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -434,9 +435,10 @@ impl ForeignNetworkManagerData {
|
||||
let _ = v.remove(network_name);
|
||||
v.is_empty()
|
||||
});
|
||||
if let Some(_) = self
|
||||
if self
|
||||
.network_peer_maps
|
||||
.remove_if(network_name, |_, v| v.peer_map.is_empty())
|
||||
.is_some()
|
||||
{
|
||||
self.network_peer_last_update.remove(network_name);
|
||||
}
|
||||
@@ -446,7 +448,7 @@ impl ForeignNetworkManagerData {
|
||||
let Some(peer_map) = self
|
||||
.network_peer_maps
|
||||
.get(network_name)
|
||||
.and_then(|v| Some(v.peer_map.clone()))
|
||||
.map(|v| v.peer_map.clone())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
@@ -492,7 +494,7 @@ impl ForeignNetworkManagerData {
|
||||
|
||||
self.peer_network_map
|
||||
.entry(dst_peer_id)
|
||||
.or_insert_with(|| DashSet::new())
|
||||
.or_default()
|
||||
.insert(network_identity.network_name.clone());
|
||||
|
||||
self.network_peer_last_update
|
||||
@@ -553,7 +555,7 @@ impl ForeignNetworkManager {
|
||||
self.data
|
||||
.network_peer_maps
|
||||
.get(network_name)
|
||||
.and_then(|v| Some(v.my_peer_id))
|
||||
.map(|v| v.my_peer_id)
|
||||
}
|
||||
|
||||
pub async fn add_peer_conn(&self, peer_conn: PeerConn) -> Result<(), Error> {
|
||||
@@ -574,7 +576,7 @@ impl ForeignNetworkManager {
|
||||
&peer_conn.get_network_identity(),
|
||||
peer_conn.get_my_peer_id(),
|
||||
peer_conn.get_peer_id(),
|
||||
!ret.is_err(),
|
||||
ret.is_ok(),
|
||||
&self.global_ctx,
|
||||
&self.packet_sender_to_mgr,
|
||||
)
|
||||
@@ -608,22 +610,21 @@ impl ForeignNetworkManager {
|
||||
|
||||
if new_added {
|
||||
self.start_event_handler(&entry).await;
|
||||
} else {
|
||||
if let Some(peer) = entry.peer_map.get_peer_by_id(peer_conn.get_peer_id()) {
|
||||
let direct_conns_len = peer.get_directly_connections().len();
|
||||
let max_count = use_global_var!(MAX_DIRECT_CONNS_PER_PEER_IN_FOREIGN_NETWORK);
|
||||
if direct_conns_len >= max_count as usize {
|
||||
return Err(anyhow::anyhow!(
|
||||
"too many direct conns, cur: {}, max: {}",
|
||||
direct_conns_len,
|
||||
max_count
|
||||
)
|
||||
.into());
|
||||
}
|
||||
} else if let Some(peer) = entry.peer_map.get_peer_by_id(peer_conn.get_peer_id()) {
|
||||
let direct_conns_len = peer.get_directly_connections().len();
|
||||
let max_count = use_global_var!(MAX_DIRECT_CONNS_PER_PEER_IN_FOREIGN_NETWORK);
|
||||
if direct_conns_len >= max_count as usize {
|
||||
return Err(anyhow::anyhow!(
|
||||
"too many direct conns, cur: {}, max: {}",
|
||||
direct_conns_len,
|
||||
max_count
|
||||
)
|
||||
.into());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(entry.peer_map.add_new_peer_conn(peer_conn).await)
|
||||
entry.peer_map.add_new_peer_conn(peer_conn).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn start_event_handler(&self, entry: &ForeignNetworkEntry) {
|
||||
@@ -686,9 +687,11 @@ impl ForeignNetworkManager {
|
||||
peers: Default::default(),
|
||||
};
|
||||
for peer in item.peer_map.list_peers().await {
|
||||
let mut peer_info = PeerInfo::default();
|
||||
peer_info.peer_id = peer;
|
||||
peer_info.conns = item.peer_map.list_peer_conns(peer).await.unwrap_or(vec![]);
|
||||
let peer_info = PeerInfo {
|
||||
peer_id: peer,
|
||||
conns: item.peer_map.list_peer_conns(peer).await.unwrap_or(vec![]),
|
||||
..Default::default()
|
||||
};
|
||||
entry.peers.push(peer_info);
|
||||
}
|
||||
|
||||
@@ -701,7 +704,7 @@ impl ForeignNetworkManager {
|
||||
self.data
|
||||
.network_peer_last_update
|
||||
.get(network_name)
|
||||
.map(|v| v.clone())
|
||||
.map(|v| *v)
|
||||
}
|
||||
|
||||
pub async fn send_msg_to_peer(
|
||||
@@ -820,7 +823,7 @@ pub mod tests {
|
||||
let pm_center = create_mock_peer_manager_with_mock_stun(NatType::Unknown).await;
|
||||
tracing::debug!("pm_center: {:?}", pm_center.my_peer_id());
|
||||
let mut flag = pm_center.get_global_ctx().get_flags();
|
||||
flag.relay_network_whitelist = vec!["net1".to_string(), "net2*".to_string()].join(" ");
|
||||
flag.relay_network_whitelist = ["net1".to_string(), "net2*".to_string()].join(" ");
|
||||
pm_center.get_global_ctx().config.set_flags(flag);
|
||||
|
||||
let pma_net1 = create_mock_peer_manager_for_foreign_network(name.as_str()).await;
|
||||
@@ -1026,7 +1029,7 @@ pub mod tests {
|
||||
|
||||
drop(pm_center);
|
||||
wait_for_condition(
|
||||
|| async { pma_net1.list_routes().await.len() == 0 },
|
||||
|| async { pma_net1.list_routes().await.is_empty() },
|
||||
Duration::from_secs(5),
|
||||
)
|
||||
.await;
|
||||
@@ -1168,7 +1171,7 @@ pub mod tests {
|
||||
println!("drop pm_center1, id: {:?}", pm_center1.my_peer_id());
|
||||
drop(pm_center1);
|
||||
wait_for_condition(
|
||||
|| async { pma_net1.list_routes().await.len() == 0 },
|
||||
|| async { pma_net1.list_routes().await.is_empty() },
|
||||
Duration::from_secs(5),
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -60,14 +60,13 @@ impl<K: PartialOrd, T> Ord for MinScored<K, T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub type DijkstraResult<K, NodeId> = (HashMap<NodeId, K>, HashMap<NodeId, (NodeId, usize)>);
|
||||
|
||||
pub fn dijkstra_with_first_hop<G, F, K>(
|
||||
graph: G,
|
||||
start: G::NodeId,
|
||||
mut edge_cost: F,
|
||||
) -> (
|
||||
HashMap<G::NodeId, K>,
|
||||
HashMap<G::NodeId, (G::NodeId, usize)>,
|
||||
)
|
||||
) -> DijkstraResult<K, G::NodeId>
|
||||
where
|
||||
G: IntoEdges + Visitable,
|
||||
G::NodeId: Eq + Hash + Clone,
|
||||
@@ -79,43 +78,43 @@ where
|
||||
let mut first_hop = HashMap::new();
|
||||
let mut visit_next = BinaryHeap::new();
|
||||
let zero_score = K::default();
|
||||
scores.insert(start.clone(), zero_score);
|
||||
visit_next.push(MinScored(zero_score, start.clone()));
|
||||
first_hop.insert(start.clone(), (start.clone(), 0));
|
||||
scores.insert(start, zero_score);
|
||||
visit_next.push(MinScored(zero_score, start));
|
||||
first_hop.insert(start, (start, 0));
|
||||
|
||||
while let Some(MinScored(node_score, node)) = visit_next.pop() {
|
||||
if visited.is_visited(&node) {
|
||||
continue;
|
||||
}
|
||||
for edge in graph.edges(node.clone()) {
|
||||
for edge in graph.edges(node) {
|
||||
let next = edge.target();
|
||||
if visited.is_visited(&next) {
|
||||
continue;
|
||||
}
|
||||
let next_score = node_score + edge_cost(edge);
|
||||
match scores.entry(next.clone()) {
|
||||
match scores.entry(next) {
|
||||
Occupied(mut ent) => {
|
||||
if next_score < *ent.get() {
|
||||
*ent.get_mut() = next_score;
|
||||
visit_next.push(MinScored(next_score, next.clone()));
|
||||
visit_next.push(MinScored(next_score, next));
|
||||
// 继承前驱的 first_hop,或自己就是第一跳
|
||||
let hop = if node == start {
|
||||
(next.clone(), 0)
|
||||
(next, 0)
|
||||
} else {
|
||||
first_hop[&node].clone()
|
||||
first_hop[&node]
|
||||
};
|
||||
first_hop.insert(next.clone(), (hop.0, hop.1 + 1));
|
||||
first_hop.insert(next, (hop.0, hop.1 + 1));
|
||||
}
|
||||
}
|
||||
Vacant(ent) => {
|
||||
ent.insert(next_score);
|
||||
visit_next.push(MinScored(next_score, next.clone()));
|
||||
visit_next.push(MinScored(next_score, next));
|
||||
let hop = if node == start {
|
||||
(next.clone(), 0)
|
||||
(next, 0)
|
||||
} else {
|
||||
first_hop[&node].clone()
|
||||
first_hop[&node]
|
||||
};
|
||||
first_hop.insert(next.clone(), (hop.0, hop.1 + 1));
|
||||
first_hop.insert(next, (hop.0, hop.1 + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,9 +137,9 @@ mod tests {
|
||||
let c = graph.add_node("c");
|
||||
let d = graph.add_node("d");
|
||||
|
||||
graph.extend_with_edges(&[(a, b, 1)]);
|
||||
graph.extend_with_edges(&[(b, c, 1)]);
|
||||
graph.extend_with_edges(&[(c, d, 2)]);
|
||||
graph.extend_with_edges([(a, b, 1)]);
|
||||
graph.extend_with_edges([(b, c, 1)]);
|
||||
graph.extend_with_edges([(c, d, 2)]);
|
||||
|
||||
let (scores, first_hop) = dijkstra_with_first_hop(&graph, a, |edge| *edge.weight());
|
||||
|
||||
@@ -162,7 +161,7 @@ mod tests {
|
||||
let d = graph.add_node("d");
|
||||
let e = graph.add_node("e");
|
||||
|
||||
graph.extend_with_edges(&[(a, b, 1), (a, c, 2), (b, d, 1), (c, d, 3), (d, e, 1)]);
|
||||
graph.extend_with_edges([(a, b, 1), (a, c, 2), (b, d, 1), (c, d, 3), (d, e, 1)]);
|
||||
|
||||
let (scores, first_hop) = dijkstra_with_first_hop(&graph, a, |edge| *edge.weight());
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ impl Peer {
|
||||
}
|
||||
|
||||
// find a conn with the smallest latency
|
||||
let mut min_latency = std::u64::MAX;
|
||||
let mut min_latency = u64::MAX;
|
||||
for conn in self.conns.iter() {
|
||||
let latency = conn.value().get_stats().latency_us;
|
||||
if latency < min_latency {
|
||||
@@ -176,7 +176,7 @@ impl Peer {
|
||||
if !has_key {
|
||||
return Err(Error::NotFound);
|
||||
}
|
||||
self.close_event_sender.send(conn_id.clone()).await.unwrap();
|
||||
self.close_event_sender.send(*conn_id).await.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ mod tests {
|
||||
|
||||
// wait for remote peer conn close
|
||||
timeout(std::time::Duration::from_secs(5), async {
|
||||
while (&remote_peer).list_peer_conns().await.len() != 0 {
|
||||
while !remote_peer.list_peer_conns().await.is_empty() {
|
||||
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
|
||||
}
|
||||
})
|
||||
|
||||
@@ -102,7 +102,7 @@ pub struct PeerConn {
|
||||
|
||||
tunnel: Arc<Mutex<Box<dyn Any + Send + 'static>>>,
|
||||
sink: MpscTunnelSender,
|
||||
recv: Arc<Mutex<Option<Pin<Box<dyn ZCPacketStream>>>>>,
|
||||
recv: Mutex<Option<Pin<Box<dyn ZCPacketStream>>>>,
|
||||
tunnel_info: Option<TunnelInfo>,
|
||||
|
||||
tasks: JoinSet<Result<(), TunnelError>>,
|
||||
@@ -149,7 +149,7 @@ impl PeerConn {
|
||||
let conn_id = PeerConnId::new_v4();
|
||||
|
||||
PeerConn {
|
||||
conn_id: conn_id.clone(),
|
||||
conn_id,
|
||||
|
||||
my_peer_id,
|
||||
global_ctx,
|
||||
@@ -158,7 +158,7 @@ impl PeerConn {
|
||||
mpsc_tunnel.close()
|
||||
})))),
|
||||
sink,
|
||||
recv: Arc::new(Mutex::new(Some(recv))),
|
||||
recv: Mutex::new(Some(recv)),
|
||||
tunnel_info,
|
||||
|
||||
tasks: JoinSet::new(),
|
||||
@@ -238,7 +238,7 @@ impl PeerConn {
|
||||
));
|
||||
}
|
||||
|
||||
return Ok(rsp);
|
||||
Ok(rsp)
|
||||
}
|
||||
|
||||
async fn wait_handshake_loop(&mut self) -> Result<HandshakeRequest, Error> {
|
||||
@@ -424,10 +424,8 @@ impl PeerConn {
|
||||
if let Err(e) = ctrl_sender.send(zc_packet) {
|
||||
tracing::error!(?e, "peer conn send ctrl resp error");
|
||||
}
|
||||
} else {
|
||||
if sender.send(zc_packet).await.is_err() {
|
||||
break;
|
||||
}
|
||||
} else if sender.send(zc_packet).await.is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -650,7 +648,10 @@ mod tests {
|
||||
let throughput = c_peer.throughput.clone();
|
||||
let _t = ScopedTask::from(tokio::spawn(async move {
|
||||
// if not drop both, we mock some rx traffic for client peer to test pinger
|
||||
while !drop_both {
|
||||
if drop_both {
|
||||
return;
|
||||
}
|
||||
loop {
|
||||
tokio::time::sleep(Duration::from_millis(100)).await;
|
||||
throughput.record_rx_bytes(3);
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ impl PingIntervalController {
|
||||
}
|
||||
|
||||
self.last_send_logic_time = self.logic_time;
|
||||
return true;
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ impl PeerConnPinger {
|
||||
"pingpong controller send pingpong task, seq: {}, node_id: {}, controller: {:?}",
|
||||
req_seq,
|
||||
my_node_id,
|
||||
controller
|
||||
controller,
|
||||
);
|
||||
|
||||
let mut sink = sink.clone();
|
||||
|
||||
@@ -351,7 +351,8 @@ impl PeerManager {
|
||||
"network identity not match".to_string(),
|
||||
));
|
||||
}
|
||||
Ok(self.peers.add_new_peer_conn(peer_conn).await)
|
||||
self.peers.add_new_peer_conn(peer_conn).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn add_client_tunnel(
|
||||
@@ -377,10 +378,8 @@ impl PeerManager {
|
||||
pub fn has_directly_connected_conn(&self, peer_id: PeerId) -> bool {
|
||||
if let Some(peer) = self.peers.get_peer_by_id(peer_id) {
|
||||
peer.has_directly_connected_conn()
|
||||
} else if self.foreign_network_client.get_peer_map().has_peer(peer_id) {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
self.foreign_network_client.get_peer_map().has_peer(peer_id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,14 +440,14 @@ impl PeerManager {
|
||||
match addr {
|
||||
SocketAddr::V4(addr) => {
|
||||
if let Some(virtual_ipv4) = virtual_ipv4 {
|
||||
if virtual_ipv4.contains(&addr.ip()) {
|
||||
if virtual_ipv4.contains(addr.ip()) {
|
||||
anyhow::bail!("tunnel src host is from the virtual network (ignore this error please)");
|
||||
}
|
||||
}
|
||||
}
|
||||
SocketAddr::V6(addr) => {
|
||||
if let Some(virtual_ipv6) = virtual_ipv6 {
|
||||
if virtual_ipv6.contains(&addr.ip()) {
|
||||
if virtual_ipv6.contains(addr.ip()) {
|
||||
anyhow::bail!("tunnel src host is from the virtual network (ignore this error please)");
|
||||
}
|
||||
}
|
||||
@@ -489,7 +488,7 @@ impl PeerManager {
|
||||
rand::random::<PeerId>()
|
||||
}).value());
|
||||
}
|
||||
peer.set_peer_id(peer_id.clone().unwrap());
|
||||
peer.set_peer_id(peer_id.unwrap());
|
||||
|
||||
tracing::info!(
|
||||
?peer_id,
|
||||
@@ -742,10 +741,8 @@ impl PeerManager {
|
||||
|
||||
let mut processed = false;
|
||||
let mut zc_packet = Some(ret);
|
||||
let mut idx = 0;
|
||||
for pipeline in pipe_line.read().await.iter().rev() {
|
||||
for (idx, pipeline) in pipe_line.read().await.iter().rev().enumerate() {
|
||||
tracing::trace!(?zc_packet, ?idx, "try_process_packet_from_peer");
|
||||
idx += 1;
|
||||
zc_packet = pipeline
|
||||
.try_process_packet_from_peer(zc_packet.unwrap())
|
||||
.await;
|
||||
@@ -938,14 +935,17 @@ impl PeerManager {
|
||||
let entry = resp
|
||||
.foreign_networks
|
||||
.entry(info.key.as_ref().unwrap().peer_id)
|
||||
.or_insert_with(|| Default::default());
|
||||
.or_insert_with(Default::default);
|
||||
let Some(route_info) = info.value.as_ref() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let mut f = OneForeignNetwork::default();
|
||||
f.network_name = info.key.as_ref().unwrap().network_name.clone();
|
||||
f.peer_ids
|
||||
.extend(info.value.as_ref().unwrap().foreign_peer_ids.iter());
|
||||
f.last_updated = format!("{}", info.value.as_ref().unwrap().last_update.unwrap());
|
||||
f.version = info.value.as_ref().unwrap().version;
|
||||
let f = OneForeignNetwork {
|
||||
network_name: info.key.as_ref().unwrap().network_name.clone(),
|
||||
peer_ids: route_info.foreign_peer_ids.clone(),
|
||||
last_updated: format!("{}", route_info.last_update.unwrap()),
|
||||
version: route_info.version,
|
||||
};
|
||||
|
||||
entry.foreign_networks.push(f);
|
||||
}
|
||||
@@ -1033,14 +1033,8 @@ impl PeerManager {
|
||||
|| ipv4_addr.is_multicast()
|
||||
|| *ipv4_addr == ipv4_inet.last_address()
|
||||
{
|
||||
dst_peers.extend(
|
||||
self.peers
|
||||
.list_routes()
|
||||
.await
|
||||
.iter()
|
||||
.map(|x| x.key().clone()),
|
||||
);
|
||||
} else if let Some(peer_id) = self.peers.get_peer_id_by_ipv4(&ipv4_addr).await {
|
||||
dst_peers.extend(self.peers.list_routes().await.iter().map(|x| *x.key()));
|
||||
} else if let Some(peer_id) = self.peers.get_peer_id_by_ipv4(ipv4_addr).await {
|
||||
dst_peers.push(peer_id);
|
||||
} else {
|
||||
for exit_node in &self.exit_nodes {
|
||||
@@ -1075,14 +1069,8 @@ impl PeerManager {
|
||||
.unwrap_or(64);
|
||||
let ipv6_inet = cidr::Ipv6Inet::new(*ipv6_addr, network_length).unwrap();
|
||||
if ipv6_addr.is_multicast() || *ipv6_addr == ipv6_inet.last_address() {
|
||||
dst_peers.extend(
|
||||
self.peers
|
||||
.list_routes()
|
||||
.await
|
||||
.iter()
|
||||
.map(|x| x.key().clone()),
|
||||
);
|
||||
} else if let Some(peer_id) = self.peers.get_peer_id_by_ipv6(&ipv6_addr).await {
|
||||
dst_peers.extend(self.peers.list_routes().await.iter().map(|x| *x.key()));
|
||||
} else if let Some(peer_id) = self.peers.get_peer_id_by_ipv6(ipv6_addr).await {
|
||||
dst_peers.push(peer_id);
|
||||
} else if !ipv6_addr.is_unicast_link_local() {
|
||||
// NOTE: never route link local address to exit node.
|
||||
@@ -1168,14 +1156,13 @@ impl PeerManager {
|
||||
let mut errs: Vec<Error> = vec![];
|
||||
let mut msg = Some(msg);
|
||||
let total_dst_peers = dst_peers.len();
|
||||
for i in 0..total_dst_peers {
|
||||
for (i, peer_id) in dst_peers.iter().enumerate() {
|
||||
let mut msg = if i == total_dst_peers - 1 {
|
||||
msg.take().unwrap()
|
||||
} else {
|
||||
msg.clone().unwrap()
|
||||
};
|
||||
|
||||
let peer_id = &dst_peers[i];
|
||||
msg.mut_peer_manager_header()
|
||||
.unwrap()
|
||||
.to_peer_id
|
||||
@@ -1632,16 +1619,16 @@ mod tests {
|
||||
..Default::default()
|
||||
});
|
||||
tokio::time::sleep(Duration::from_secs(2)).await;
|
||||
wait_route_appear_with_cost(peer_mgr_a.clone(), peer_mgr_c.my_peer_id, Some(3))
|
||||
if wait_route_appear_with_cost(peer_mgr_a.clone(), peer_mgr_c.my_peer_id, Some(3))
|
||||
.await
|
||||
.expect(
|
||||
format!(
|
||||
"route not appear, a route table: {}, table: {:#?}",
|
||||
peer_mgr_a.get_route().dump().await,
|
||||
peer_mgr_a.get_route().list_routes().await
|
||||
)
|
||||
.as_str(),
|
||||
);
|
||||
.is_err()
|
||||
{
|
||||
panic!(
|
||||
"route not appear, a route table: {}, table: {:#?}",
|
||||
peer_mgr_a.get_route().dump().await,
|
||||
peer_mgr_a.get_route().list_routes().await
|
||||
)
|
||||
}
|
||||
|
||||
let ret = peer_mgr_a
|
||||
.get_route()
|
||||
@@ -1767,8 +1754,7 @@ mod tests {
|
||||
.get_foreign_network_client()
|
||||
.list_public_peers()
|
||||
.await
|
||||
.len()
|
||||
== 0
|
||||
.is_empty()
|
||||
},
|
||||
Duration::from_secs(10),
|
||||
)
|
||||
@@ -1810,8 +1796,7 @@ mod tests {
|
||||
.get_foreign_network_client()
|
||||
.list_public_peers()
|
||||
.await
|
||||
.len()
|
||||
== 0
|
||||
.is_empty()
|
||||
},
|
||||
Duration::from_secs(10),
|
||||
)
|
||||
|
||||
@@ -49,8 +49,8 @@ impl PeerMap {
|
||||
}
|
||||
|
||||
async fn add_new_peer(&self, peer: Peer) {
|
||||
let peer_id = peer.peer_node_id.clone();
|
||||
self.peer_map.insert(peer_id.clone(), Arc::new(peer));
|
||||
let peer_id = peer.peer_node_id;
|
||||
self.peer_map.insert(peer_id, Arc::new(peer));
|
||||
self.global_ctx
|
||||
.issue_event(GlobalCtxEvent::PeerAdded(peer_id));
|
||||
}
|
||||
@@ -75,7 +75,7 @@ impl PeerMap {
|
||||
let conn_id = close_notifier.get_conn_id();
|
||||
let conn_info = peer_conn.get_conn_info();
|
||||
self.alive_conns
|
||||
.insert((conn_info.peer_id, conn_id.clone()), conn_info.clone());
|
||||
.insert((conn_info.peer_id, conn_id), conn_info.clone());
|
||||
tokio::spawn(async move {
|
||||
if let Some(mut waiter) = close_notifier.get_waiter().await {
|
||||
let _ = waiter.recv().await;
|
||||
@@ -173,9 +173,7 @@ impl PeerMap {
|
||||
) -> Vec<PeerId> {
|
||||
let mut ret = Vec::new();
|
||||
for route in self.routes.read().await.iter() {
|
||||
let peers = route
|
||||
.list_peers_own_foreign_network(&network_identity)
|
||||
.await;
|
||||
let peers = route.list_peers_own_foreign_network(network_identity).await;
|
||||
ret.extend(peers);
|
||||
}
|
||||
ret
|
||||
@@ -195,7 +193,7 @@ impl PeerMap {
|
||||
};
|
||||
|
||||
self.send_msg_directly(msg, gateway_peer_id).await?;
|
||||
return Ok(());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn get_peer_id_by_ipv4(&self, ipv4: &Ipv4Addr) -> Option<PeerId> {
|
||||
@@ -263,7 +261,7 @@ impl PeerMap {
|
||||
let Some(peer) = self.get_peer_by_id(*peer_id) else {
|
||||
continue;
|
||||
};
|
||||
if peer.list_peer_conns().await.len() > 0 {
|
||||
if !peer.list_peer_conns().await.is_empty() {
|
||||
ret.push(*peer_id);
|
||||
}
|
||||
}
|
||||
@@ -274,7 +272,7 @@ impl PeerMap {
|
||||
if let Some(p) = self.get_peer_by_id(peer_id) {
|
||||
Some(p.list_peer_conns().await)
|
||||
} else {
|
||||
return None;
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,7 +289,7 @@ impl PeerMap {
|
||||
if let Some(p) = self.get_peer_by_id(peer_id) {
|
||||
p.close_peer_conn(conn_id).await
|
||||
} else {
|
||||
return Err(Error::NotFound);
|
||||
Err(Error::NotFound)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,7 +337,7 @@ impl PeerMap {
|
||||
}
|
||||
|
||||
pub async fn list_route_infos(&self) -> Vec<cli::Route> {
|
||||
for route in self.routes.read().await.iter() {
|
||||
if let Some(route) = self.routes.read().await.iter().next() {
|
||||
return route.list_routes().await;
|
||||
}
|
||||
vec![]
|
||||
@@ -361,7 +359,7 @@ impl PeerMap {
|
||||
pub fn get_alive_conns(&self) -> DashMap<(PeerId, PeerConnId), PeerConnInfo> {
|
||||
self.alive_conns
|
||||
.iter()
|
||||
.map(|v| (v.key().clone(), v.value().clone()))
|
||||
.map(|v| (*v.key(), v.value().clone()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ impl RoutePeerInfo {
|
||||
};
|
||||
|
||||
let need_update_periodically = if let Ok(Ok(d)) =
|
||||
SystemTime::try_from(new.last_update.unwrap()).map(|x| x.elapsed())
|
||||
SystemTime::try_from(new.last_update.unwrap_or_default()).map(|x| x.elapsed())
|
||||
{
|
||||
d > UPDATE_PEER_INFO_PERIOD
|
||||
} else {
|
||||
@@ -186,45 +186,41 @@ impl RoutePeerInfo {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<crate::proto::cli::Route> for RoutePeerInfo {
|
||||
fn into(self) -> crate::proto::cli::Route {
|
||||
let network_length = if self.network_length == 0 {
|
||||
impl From<RoutePeerInfo> for crate::proto::cli::Route {
|
||||
fn from(val: RoutePeerInfo) -> Self {
|
||||
let network_length = if val.network_length == 0 {
|
||||
24
|
||||
} else {
|
||||
self.network_length
|
||||
val.network_length
|
||||
};
|
||||
|
||||
crate::proto::cli::Route {
|
||||
peer_id: self.peer_id,
|
||||
ipv4_addr: if let Some(ipv4_addr) = self.ipv4_addr {
|
||||
Some(Ipv4Inet {
|
||||
address: Some(ipv4_addr.into()),
|
||||
network_length,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
},
|
||||
peer_id: val.peer_id,
|
||||
ipv4_addr: val.ipv4_addr.map(|ipv4_addr| Ipv4Inet {
|
||||
address: Some(ipv4_addr),
|
||||
network_length,
|
||||
}),
|
||||
next_hop_peer_id: 0, // next_hop_peer_id is calculated in RouteTable.
|
||||
cost: 0, // cost is calculated in RouteTable.
|
||||
path_latency: 0, // path_latency is calculated in RouteTable.
|
||||
proxy_cidrs: self.proxy_cidrs.clone(),
|
||||
hostname: self.hostname.unwrap_or_default(),
|
||||
proxy_cidrs: val.proxy_cidrs.clone(),
|
||||
hostname: val.hostname.unwrap_or_default(),
|
||||
stun_info: {
|
||||
let mut stun_info = StunInfo::default();
|
||||
if let Ok(udp_nat_type) = NatType::try_from(self.udp_stun_info as i32) {
|
||||
if let Ok(udp_nat_type) = NatType::try_from(val.udp_stun_info) {
|
||||
stun_info.set_udp_nat_type(udp_nat_type);
|
||||
}
|
||||
Some(stun_info)
|
||||
},
|
||||
inst_id: self.inst_id.map(|x| x.to_string()).unwrap_or_default(),
|
||||
version: self.easytier_version,
|
||||
feature_flag: self.feature_flag,
|
||||
inst_id: val.inst_id.map(|x| x.to_string()).unwrap_or_default(),
|
||||
version: val.easytier_version,
|
||||
feature_flag: val.feature_flag,
|
||||
|
||||
next_hop_peer_id_latency_first: None,
|
||||
cost_latency_first: None,
|
||||
path_latency_latency_first: None,
|
||||
|
||||
ipv6_addr: self.ipv6_addr.map(Into::into),
|
||||
ipv6_addr: val.ipv6_addr,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,10 +231,10 @@ struct RouteConnBitmap {
|
||||
bitmap: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Into<crate::proto::peer_rpc::RouteConnBitmap> for RouteConnBitmap {
|
||||
fn into(self) -> crate::proto::peer_rpc::RouteConnBitmap {
|
||||
impl From<RouteConnBitmap> for crate::proto::peer_rpc::RouteConnBitmap {
|
||||
fn from(val: RouteConnBitmap) -> Self {
|
||||
crate::proto::peer_rpc::RouteConnBitmap {
|
||||
peer_ids: self
|
||||
peer_ids: val
|
||||
.peer_ids
|
||||
.into_iter()
|
||||
.map(|x| PeerIdVersion {
|
||||
@@ -246,7 +242,7 @@ impl Into<crate::proto::peer_rpc::RouteConnBitmap> for RouteConnBitmap {
|
||||
version: x.1,
|
||||
})
|
||||
.collect(),
|
||||
bitmap: self.bitmap,
|
||||
bitmap: val.bitmap,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -318,7 +314,7 @@ impl SyncedRouteInfo {
|
||||
fn get_connected_peers<T: FromIterator<PeerId>>(&self, peer_id: PeerId) -> Option<T> {
|
||||
self.conn_map
|
||||
.get(&peer_id)
|
||||
.map(|x| x.0.clone().iter().map(|x| *x).collect())
|
||||
.map(|x| x.0.clone().iter().copied().collect())
|
||||
}
|
||||
|
||||
fn remove_peer(&self, peer_id: PeerId) {
|
||||
@@ -403,8 +399,8 @@ impl SyncedRouteInfo {
|
||||
my_peer_id: PeerId,
|
||||
my_peer_route_id: u64,
|
||||
dst_peer_id: PeerId,
|
||||
peer_infos: &Vec<RoutePeerInfo>,
|
||||
raw_peer_infos: &Vec<DynamicMessage>,
|
||||
peer_infos: &[RoutePeerInfo],
|
||||
raw_peer_infos: &[DynamicMessage],
|
||||
) -> Result<(), Error> {
|
||||
let mut need_inc_version = false;
|
||||
for (idx, route_info) in peer_infos.iter().enumerate() {
|
||||
@@ -476,7 +472,7 @@ impl SyncedRouteInfo {
|
||||
})
|
||||
.or_insert_with(|| {
|
||||
need_inc_version = true;
|
||||
(connceted_peers, version.clone().into())
|
||||
(connceted_peers, (*version).into())
|
||||
});
|
||||
}
|
||||
if need_inc_version {
|
||||
@@ -512,11 +508,8 @@ impl SyncedRouteInfo {
|
||||
my_peer_route_id: u64,
|
||||
global_ctx: &ArcGlobalCtx,
|
||||
) -> bool {
|
||||
let mut old = self
|
||||
.peer_infos
|
||||
.entry(my_peer_id)
|
||||
.or_insert(RoutePeerInfo::new());
|
||||
let new = old.update_self(my_peer_id, my_peer_route_id, &global_ctx);
|
||||
let mut old = self.peer_infos.entry(my_peer_id).or_default();
|
||||
let new = old.update_self(my_peer_id, my_peer_route_id, global_ctx);
|
||||
let new_version = new.version;
|
||||
let old_version = old.version;
|
||||
*old = new;
|
||||
@@ -616,8 +609,8 @@ impl SyncedRouteInfo {
|
||||
}
|
||||
|
||||
fn is_peer_directly_connected(&self, src_peer_id: PeerId, dst_peer_id: PeerId) -> bool {
|
||||
return self.is_peer_bidirectly_connected(src_peer_id, dst_peer_id)
|
||||
|| self.is_peer_bidirectly_connected(dst_peer_id, src_peer_id);
|
||||
self.is_peer_bidirectly_connected(src_peer_id, dst_peer_id)
|
||||
|| self.is_peer_bidirectly_connected(dst_peer_id, src_peer_id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -674,7 +667,7 @@ impl RouteTable {
|
||||
fn get_nat_type(&self, peer_id: PeerId) -> Option<NatType> {
|
||||
self.peer_infos
|
||||
.get(&peer_id)
|
||||
.map(|x| NatType::try_from(x.udp_stun_info as i32).unwrap_or_default())
|
||||
.map(|x| NatType::try_from(x.udp_stun_info).unwrap_or_default())
|
||||
}
|
||||
|
||||
// return graph and start node index (node of my peer id).
|
||||
@@ -710,9 +703,9 @@ impl RouteTable {
|
||||
for item in peer_id_to_node_index.iter() {
|
||||
let src_peer_id = item.key();
|
||||
let src_node_idx = item.value();
|
||||
let connected_peers = synced_info
|
||||
let connected_peers: BTreeSet<_> = synced_info
|
||||
.get_connected_peers(*src_peer_id)
|
||||
.unwrap_or(BTreeSet::new());
|
||||
.unwrap_or_default();
|
||||
|
||||
// if avoid relay, just set all outgoing edges to a large value: AVOID_RELAY_COST.
|
||||
let peer_avoid_relay_data = synced_info.get_avoid_relay_data(*src_peer_id);
|
||||
@@ -798,7 +791,7 @@ impl RouteTable {
|
||||
}
|
||||
|
||||
// Step 3: 第二次 Dijkstra - 在子图上找代价最小的路径
|
||||
self.gen_next_hop_map_with_least_cost(&subgraph, &start_node_idx.clone().unwrap(), version);
|
||||
self.gen_next_hop_map_with_least_cost(&subgraph, &start_node_idx.unwrap(), version);
|
||||
}
|
||||
|
||||
fn gen_next_hop_map_with_least_cost(
|
||||
@@ -813,7 +806,7 @@ impl RouteTable {
|
||||
let info = NextHopInfo {
|
||||
next_hop_peer_id: *graph.node_weight(*next_hop).unwrap(),
|
||||
path_latency: (*costs.get(dst).unwrap() % AVOID_RELAY_COST) as i32,
|
||||
path_len: *path_len as usize,
|
||||
path_len: { *path_len },
|
||||
version,
|
||||
};
|
||||
let dst_peer_id = *graph.node_weight(*dst).unwrap();
|
||||
@@ -841,7 +834,7 @@ impl RouteTable {
|
||||
|
||||
// build next hop map
|
||||
let (graph, start_node) =
|
||||
Self::build_peer_graph_from_synced_info(my_peer_id, &synced_info, cost_calc);
|
||||
Self::build_peer_graph_from_synced_info(my_peer_id, synced_info, cost_calc);
|
||||
|
||||
if graph.node_count() == 0 {
|
||||
tracing::warn!("no peer in graph, cannot build next hop map");
|
||||
@@ -1031,11 +1024,11 @@ impl SyncRouteSession {
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
fn update_dst_saved_peer_info_version(&self, infos: &Vec<RoutePeerInfo>) {
|
||||
fn update_dst_saved_peer_info_version(&self, infos: &[RoutePeerInfo]) {
|
||||
for info in infos.iter() {
|
||||
self.dst_saved_peer_info_versions
|
||||
.entry(info.peer_id)
|
||||
.or_insert_with(|| AtomicVersion::new())
|
||||
.or_insert_with(AtomicVersion::new)
|
||||
.set_if_larger(info.version);
|
||||
}
|
||||
}
|
||||
@@ -1044,7 +1037,7 @@ impl SyncRouteSession {
|
||||
for (peer_id, version) in conn_bitmap.peer_ids.iter() {
|
||||
self.dst_saved_conn_bitmap_version
|
||||
.entry(*peer_id)
|
||||
.or_insert_with(|| AtomicVersion::new())
|
||||
.or_insert_with(AtomicVersion::new)
|
||||
.set_if_larger(*version);
|
||||
}
|
||||
}
|
||||
@@ -1053,7 +1046,7 @@ impl SyncRouteSession {
|
||||
for item in foreign_network.infos.iter() {
|
||||
self.dst_saved_foreign_network_versions
|
||||
.entry(item.key.clone().unwrap())
|
||||
.or_insert_with(|| AtomicVersion::new())
|
||||
.or_insert_with(AtomicVersion::new)
|
||||
.set_if_larger(item.value.as_ref().unwrap().version);
|
||||
}
|
||||
}
|
||||
@@ -1249,13 +1242,10 @@ impl PeerRouteServiceImpl {
|
||||
.list_foreign_networks()
|
||||
.await;
|
||||
|
||||
let updated = self
|
||||
.synced_route_info
|
||||
.update_my_foreign_network(self.my_peer_id, foreign_networks);
|
||||
|
||||
// do not need update owner map because we always filter out my peer id.
|
||||
|
||||
updated
|
||||
self.synced_route_info
|
||||
.update_my_foreign_network(self.my_peer_id, foreign_networks)
|
||||
}
|
||||
|
||||
fn update_route_table(&self) {
|
||||
@@ -1317,7 +1307,7 @@ impl PeerRouteServiceImpl {
|
||||
};
|
||||
self.foreign_network_owner_map
|
||||
.entry(network_identity)
|
||||
.or_insert_with(|| Vec::new())
|
||||
.or_default()
|
||||
.push(entry.my_peer_id_for_this_network);
|
||||
|
||||
self.foreign_network_my_peer_id_map.insert(
|
||||
@@ -1350,8 +1340,7 @@ impl PeerRouteServiceImpl {
|
||||
.synced_route_info
|
||||
.conn_map
|
||||
.iter()
|
||||
.map(|x| x.value().clone().0.into_iter())
|
||||
.flatten()
|
||||
.flat_map(|x| x.value().clone().0.into_iter())
|
||||
.collect::<BTreeSet<_>>();
|
||||
|
||||
let all_peer_ids = self
|
||||
@@ -1364,7 +1353,7 @@ impl PeerRouteServiceImpl {
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut conn_bitmap = RouteConnBitmap::new();
|
||||
conn_bitmap.bitmap = vec![0; (all_peer_ids.len() * all_peer_ids.len() + 7) / 8];
|
||||
conn_bitmap.bitmap = vec![0; (all_peer_ids.len() * all_peer_ids.len()).div_ceil(8)];
|
||||
conn_bitmap.peer_ids = all_peer_ids;
|
||||
|
||||
let all_peer_ids = &conn_bitmap.peer_ids;
|
||||
@@ -1419,7 +1408,7 @@ impl PeerRouteServiceImpl {
|
||||
for (peer_id, local_version) in self.cached_local_conn_map.lock().unwrap().peer_ids.iter() {
|
||||
let peer_version = session
|
||||
.dst_saved_conn_bitmap_version
|
||||
.get(&peer_id)
|
||||
.get(peer_id)
|
||||
.map(|item| item.get());
|
||||
if peer_version.is_none() || peer_version.unwrap() < *local_version {
|
||||
need_update = true;
|
||||
@@ -1442,7 +1431,7 @@ impl PeerRouteServiceImpl {
|
||||
for item in self.synced_route_info.foreign_network.iter() {
|
||||
if session
|
||||
.dst_saved_foreign_network_versions
|
||||
.get(&item.key())
|
||||
.get(item.key())
|
||||
.map(|x| x.get() >= item.value().version)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
@@ -1485,9 +1474,9 @@ impl PeerRouteServiceImpl {
|
||||
Option<RouteConnBitmap>,
|
||||
Option<RouteForeignNetworkInfos>,
|
||||
) {
|
||||
let route_infos = self.build_route_info(&session);
|
||||
let conn_bitmap = self.build_conn_bitmap(&session);
|
||||
let foreign_network = self.build_foreign_network_info(&session);
|
||||
let route_infos = self.build_route_info(session);
|
||||
let conn_bitmap = self.build_conn_bitmap(session);
|
||||
let foreign_network = self.build_foreign_network_info(session);
|
||||
|
||||
(route_infos, conn_bitmap, foreign_network)
|
||||
}
|
||||
@@ -1661,19 +1650,19 @@ impl PeerRouteServiceImpl {
|
||||
session.update_dst_session_id(resp.session_id);
|
||||
|
||||
if let Some(peer_infos) = &peer_infos {
|
||||
session.update_dst_saved_peer_info_version(&peer_infos);
|
||||
session.update_dst_saved_peer_info_version(peer_infos);
|
||||
}
|
||||
|
||||
if let Some(conn_bitmap) = &conn_bitmap {
|
||||
session.update_dst_saved_conn_bitmap_version(&conn_bitmap);
|
||||
session.update_dst_saved_conn_bitmap_version(conn_bitmap);
|
||||
}
|
||||
|
||||
if let Some(foreign_network) = &foreign_network {
|
||||
session.update_dst_saved_foreign_network_version(&foreign_network);
|
||||
session.update_dst_saved_foreign_network_version(foreign_network);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
false
|
||||
}
|
||||
|
||||
fn update_peer_info_last_update(&self) {
|
||||
@@ -1767,11 +1756,10 @@ impl OspfRouteRpc for RouteSessionManager {
|
||||
|
||||
Ok(match ret {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
let mut resp = SyncRouteInfoResponse::default();
|
||||
resp.error = Some(e as i32);
|
||||
resp
|
||||
}
|
||||
Err(e) => SyncRouteInfoResponse {
|
||||
error: Some(e as i32),
|
||||
..Default::default()
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1828,12 +1816,9 @@ impl RouteSessionManager {
|
||||
|
||||
select! {
|
||||
_ = tokio::time::sleep(Duration::from_secs(1)) => {}
|
||||
ret = sync_now.recv() => match ret {
|
||||
Err(e) => {
|
||||
tracing::debug!(?e, "session_task sync_now recv failed, ospf route may exit");
|
||||
break;
|
||||
},
|
||||
_ => {}
|
||||
ret = sync_now.recv() => if let Err(e) = ret {
|
||||
tracing::debug!(?e, "session_task sync_now recv failed, ospf route may exit");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1903,7 +1888,7 @@ impl RouteSessionManager {
|
||||
};
|
||||
!session.dst_is_initiator.load(Ordering::Relaxed)
|
||||
})
|
||||
.map(|x| *x)
|
||||
.copied()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if initiator_candidates.is_empty() {
|
||||
@@ -1998,6 +1983,7 @@ impl RouteSessionManager {
|
||||
tracing::debug!(?ret, ?reason, "sync_now_broadcast.send");
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn do_sync_route_info(
|
||||
&self,
|
||||
from_peer_id: PeerId,
|
||||
@@ -2034,7 +2020,7 @@ impl RouteSessionManager {
|
||||
}
|
||||
|
||||
if let Some(conn_bitmap) = &conn_bitmap {
|
||||
service_impl.synced_route_info.update_conn_map(&conn_bitmap);
|
||||
service_impl.synced_route_info.update_conn_map(conn_bitmap);
|
||||
session.update_dst_saved_conn_bitmap_version(conn_bitmap);
|
||||
need_update_route_table = true;
|
||||
}
|
||||
@@ -2046,7 +2032,7 @@ impl RouteSessionManager {
|
||||
if let Some(foreign_network) = &foreign_network {
|
||||
service_impl
|
||||
.synced_route_info
|
||||
.update_foreign_network(&foreign_network);
|
||||
.update_foreign_network(foreign_network);
|
||||
session.update_dst_saved_foreign_network_version(foreign_network);
|
||||
}
|
||||
|
||||
@@ -2267,7 +2253,7 @@ impl Route for PeerRoute {
|
||||
route.cost_latency_first = next_hop_peer_latency_first.map(|x| x.path_len as i32);
|
||||
route.path_latency_latency_first = next_hop_peer_latency_first.map(|x| x.path_latency);
|
||||
|
||||
route.feature_flag = item.feature_flag.clone();
|
||||
route.feature_flag = item.feature_flag;
|
||||
|
||||
routes.push(route);
|
||||
}
|
||||
@@ -2455,7 +2441,7 @@ mod tests {
|
||||
let r_a = create_mock_route(p_a.clone()).await;
|
||||
let r_b = create_mock_route(p_b.clone()).await;
|
||||
|
||||
for r in vec![r_a.clone(), r_b.clone()].iter() {
|
||||
for r in [r_a.clone(), r_b.clone()].iter() {
|
||||
wait_for_condition(
|
||||
|| async {
|
||||
println!("route: {:?}", r.list_routes().await);
|
||||
@@ -2507,7 +2493,7 @@ mod tests {
|
||||
drop(p_b);
|
||||
|
||||
wait_for_condition(
|
||||
|| async { r_a.list_routes().await.len() == 0 },
|
||||
|| async { r_a.list_routes().await.is_empty() },
|
||||
Duration::from_secs(5),
|
||||
)
|
||||
.await;
|
||||
@@ -2531,7 +2517,7 @@ mod tests {
|
||||
let r_b = create_mock_route(p_b.clone()).await;
|
||||
let r_c = create_mock_route(p_c.clone()).await;
|
||||
|
||||
for r in vec![r_a.clone(), r_b.clone(), r_c.clone()].iter() {
|
||||
for r in [r_a.clone(), r_b.clone(), r_c.clone()].iter() {
|
||||
wait_for_condition(
|
||||
|| async { r.service_impl.synced_route_info.peer_infos.len() == 3 },
|
||||
Duration::from_secs(5),
|
||||
@@ -2563,10 +2549,10 @@ mod tests {
|
||||
connect_peer_manager(p_d.clone(), p_c.clone()).await;
|
||||
|
||||
// find the smallest peer_id, which should be a center node
|
||||
let mut all_route = vec![r_a.clone(), r_b.clone(), r_c.clone(), r_d.clone()];
|
||||
let mut all_route = [r_a.clone(), r_b.clone(), r_c.clone(), r_d.clone()];
|
||||
all_route.sort_by(|a, b| a.my_peer_id.cmp(&b.my_peer_id));
|
||||
let mut all_peer_mgr = vec![p_a.clone(), p_b.clone(), p_c.clone(), p_d.clone()];
|
||||
all_peer_mgr.sort_by(|a, b| a.my_peer_id().cmp(&b.my_peer_id()));
|
||||
let mut all_peer_mgr = [p_a.clone(), p_b.clone(), p_c.clone(), p_d.clone()];
|
||||
all_peer_mgr.sort_by_key(|a| a.my_peer_id());
|
||||
|
||||
wait_for_condition(
|
||||
|| async { all_route[0].service_impl.sessions.len() == 3 },
|
||||
@@ -2664,7 +2650,7 @@ mod tests {
|
||||
let r_b = create_mock_route(p_b.clone()).await;
|
||||
let r_c = create_mock_route(p_c.clone()).await;
|
||||
|
||||
for r in vec![r_a.clone(), r_b.clone(), r_c.clone()].iter() {
|
||||
for r in [r_a.clone(), r_b.clone(), r_c.clone()].iter() {
|
||||
wait_for_condition(
|
||||
|| async { r.service_impl.synced_route_info.peer_infos.len() == 3 },
|
||||
Duration::from_secs(5),
|
||||
@@ -2684,7 +2670,7 @@ mod tests {
|
||||
drop(r_c);
|
||||
drop(p_c);
|
||||
|
||||
for r in vec![r_a.clone(), r_b.clone()].iter() {
|
||||
for r in [r_a.clone(), r_b.clone()].iter() {
|
||||
wait_for_condition(
|
||||
|| async { r.list_routes().await.len() == 1 },
|
||||
Duration::from_secs(5),
|
||||
@@ -2717,7 +2703,7 @@ mod tests {
|
||||
.await
|
||||
.unwrap();
|
||||
wait_for_condition(
|
||||
|| async { r_a.list_routes().await.len() == 0 },
|
||||
|| async { r_a.list_routes().await.is_empty() },
|
||||
Duration::from_secs(5),
|
||||
)
|
||||
.await;
|
||||
@@ -2756,7 +2742,7 @@ mod tests {
|
||||
|
||||
// in normal mode, packet from p_c should directly forward to p_a
|
||||
wait_for_condition(
|
||||
|| async { r_d.get_next_hop(p_a.my_peer_id()).await != None },
|
||||
|| async { (r_d.get_next_hop(p_a.my_peer_id()).await).is_some() },
|
||||
Duration::from_secs(5),
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -4,7 +4,7 @@ use futures::{SinkExt as _, StreamExt};
|
||||
use tokio::task::JoinSet;
|
||||
|
||||
use crate::{
|
||||
common::{error::Error, PeerId, stats_manager::StatsManager},
|
||||
common::{error::Error, stats_manager::StatsManager, PeerId},
|
||||
proto::rpc_impl::{self, bidirect::BidirectRpcManager},
|
||||
tunnel::packet_def::ZCPacket,
|
||||
};
|
||||
@@ -47,7 +47,10 @@ impl PeerRpcManager {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_with_stats_manager(tspt: impl PeerRpcManagerTransport, stats_manager: Arc<StatsManager>) -> Self {
|
||||
pub fn new_with_stats_manager(
|
||||
tspt: impl PeerRpcManagerTransport,
|
||||
stats_manager: Arc<StatsManager>,
|
||||
) -> Self {
|
||||
Self {
|
||||
tspt: Arc::new(Box::new(tspt)),
|
||||
bidirect_rpc: BidirectRpcManager::new_with_stats_manager(stats_manager),
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
use std::{net::{Ipv4Addr, Ipv6Addr}, sync::Arc};
|
||||
use std::{
|
||||
net::{Ipv4Addr, Ipv6Addr},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use dashmap::DashMap;
|
||||
|
||||
@@ -10,18 +13,13 @@ use crate::{
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub enum NextHopPolicy {
|
||||
#[default]
|
||||
LeastHop,
|
||||
LeastCost,
|
||||
}
|
||||
|
||||
impl Default for NextHopPolicy {
|
||||
fn default() -> Self {
|
||||
NextHopPolicy::LeastHop
|
||||
}
|
||||
}
|
||||
|
||||
pub type ForeignNetworkRouteInfoMap =
|
||||
DashMap<ForeignNetworkRouteInfoKey, ForeignNetworkRouteInfoEntry>;
|
||||
|
||||
|
||||
@@ -40,17 +40,19 @@ impl PeerManagerRpcService {
|
||||
let peer_map = peer_manager.get_peer_map();
|
||||
let mut peer_infos = Vec::new();
|
||||
for peer in peers {
|
||||
let mut peer_info = PeerInfo::default();
|
||||
peer_info.peer_id = peer;
|
||||
peer_info.default_conn_id = peer_map
|
||||
.get_peer_default_conn_id(peer)
|
||||
.await
|
||||
.map(Into::into);
|
||||
peer_info.directly_connected_conns = peer_map
|
||||
.get_directly_connections_by_peer_id(peer)
|
||||
.into_iter()
|
||||
.map(Into::into)
|
||||
.collect();
|
||||
let mut peer_info = PeerInfo {
|
||||
peer_id: peer,
|
||||
default_conn_id: peer_map
|
||||
.get_peer_default_conn_id(peer)
|
||||
.await
|
||||
.map(Into::into),
|
||||
directly_connected_conns: peer_map
|
||||
.get_directly_connections_by_peer_id(peer)
|
||||
.into_iter()
|
||||
.map(Into::into)
|
||||
.collect(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
if let Some(conns) = peer_map.list_peer_conns(peer).await {
|
||||
peer_info.conns = conns;
|
||||
@@ -93,8 +95,9 @@ impl PeerManageRpc for PeerManagerRpcService {
|
||||
_: BaseController,
|
||||
_request: ListRouteRequest, // Accept request of type HelloRequest
|
||||
) -> Result<ListRouteResponse, rpc_types::error::Error> {
|
||||
let mut reply = ListRouteResponse::default();
|
||||
reply.routes = self.peer_manager.list_routes().await;
|
||||
let reply = ListRouteResponse {
|
||||
routes: self.peer_manager.list_routes().await,
|
||||
};
|
||||
Ok(reply)
|
||||
}
|
||||
|
||||
@@ -103,8 +106,9 @@ impl PeerManageRpc for PeerManagerRpcService {
|
||||
_: BaseController,
|
||||
_request: DumpRouteRequest, // Accept request of type HelloRequest
|
||||
) -> Result<DumpRouteResponse, rpc_types::error::Error> {
|
||||
let mut reply = DumpRouteResponse::default();
|
||||
reply.result = self.peer_manager.dump_route().await;
|
||||
let reply = DumpRouteResponse {
|
||||
result: self.peer_manager.dump_route().await,
|
||||
};
|
||||
Ok(reply)
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ pub async fn wait_route_appear_with_cost(
|
||||
}
|
||||
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
|
||||
}
|
||||
return Err(Error::NotFound);
|
||||
Err(Error::NotFound)
|
||||
}
|
||||
|
||||
pub async fn wait_route_appear(
|
||||
|
||||
@@ -90,7 +90,7 @@ impl PeerRoutePair {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_udp_nat_type(self: &Self) -> String {
|
||||
pub fn get_udp_nat_type(&self) -> String {
|
||||
use crate::proto::common::NatType;
|
||||
let mut ret = NatType::Unknown;
|
||||
if let Some(r) = &self.route.clone().unwrap_or_default().stun_info {
|
||||
|
||||
@@ -38,13 +38,13 @@ impl From<String> for Uuid {
|
||||
|
||||
impl fmt::Display for Uuid {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", uuid::Uuid::from(self.clone()))
|
||||
write!(f, "{}", uuid::Uuid::from(*self))
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Uuid {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", uuid::Uuid::from(self.clone()))
|
||||
write!(f, "{}", uuid::Uuid::from(*self))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,9 +62,9 @@ impl From<Ipv4Addr> for std::net::Ipv4Addr {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for Ipv4Addr {
|
||||
fn to_string(&self) -> String {
|
||||
std::net::Ipv4Addr::from(self.addr).to_string()
|
||||
impl Display for Ipv4Addr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", std::net::Ipv4Addr::from(self.addr))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,9 +93,9 @@ impl From<Ipv6Addr> for std::net::Ipv6Addr {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for Ipv6Addr {
|
||||
fn to_string(&self) -> String {
|
||||
std::net::Ipv6Addr::from(self.clone()).to_string()
|
||||
impl Display for Ipv6Addr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", std::net::Ipv6Addr::from(*self))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ impl From<Ipv4Inet> for cidr::Ipv4Inet {
|
||||
|
||||
impl fmt::Display for Ipv4Inet {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", cidr::Ipv4Inet::from(self.clone()))
|
||||
write!(f, "{}", cidr::Ipv4Inet::from(*self))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ impl From<Ipv6Inet> for cidr::Ipv6Inet {
|
||||
|
||||
impl fmt::Display for Ipv6Inet {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", cidr::Ipv6Inet::from(self.clone()))
|
||||
write!(f, "{}", cidr::Ipv6Inet::from(*self))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ impl From<IpInet> for cidr::IpInet {
|
||||
|
||||
impl Display for IpInet {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", cidr::IpInet::from(self.clone()))
|
||||
write!(f, "{}", cidr::IpInet::from(*self))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,11 +240,11 @@ impl From<std::net::SocketAddr> for SocketAddr {
|
||||
fn from(value: std::net::SocketAddr) -> Self {
|
||||
match value {
|
||||
std::net::SocketAddr::V4(v4) => SocketAddr {
|
||||
ip: Some(socket_addr::Ip::Ipv4(v4.ip().clone().into())),
|
||||
ip: Some(socket_addr::Ip::Ipv4((*v4.ip()).into())),
|
||||
port: v4.port() as u32,
|
||||
},
|
||||
std::net::SocketAddr::V6(v6) => SocketAddr {
|
||||
ip: Some(socket_addr::Ip::Ipv6(v6.ip().clone().into())),
|
||||
ip: Some(socket_addr::Ip::Ipv6((*v6.ip()).into())),
|
||||
port: v6.port() as u32,
|
||||
},
|
||||
}
|
||||
@@ -271,9 +271,9 @@ impl From<SocketAddr> for std::net::SocketAddr {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for SocketAddr {
|
||||
fn to_string(&self) -> String {
|
||||
std::net::SocketAddr::from(self.clone()).to_string()
|
||||
impl Display for SocketAddr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", std::net::SocketAddr::from(*self))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,14 +302,14 @@ impl TryFrom<CompressorAlgo> for CompressionAlgoPb {
|
||||
|
||||
impl fmt::Debug for Ipv4Addr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let std_ipv4_addr = std::net::Ipv4Addr::from(self.clone());
|
||||
let std_ipv4_addr = std::net::Ipv4Addr::from(*self);
|
||||
write!(f, "{}", std_ipv4_addr)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Ipv6Addr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let std_ipv6_addr = std::net::Ipv6Addr::from(self.clone());
|
||||
let std_ipv6_addr = std::net::Ipv6Addr::from(*self);
|
||||
write!(f, "{}", std_ipv6_addr)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#![allow(clippy::module_inception)]
|
||||
|
||||
use prost::DecodeError;
|
||||
|
||||
use super::rpc_types;
|
||||
|
||||
@@ -24,6 +24,12 @@ pub struct BidirectRpcManager {
|
||||
tasks: Mutex<Option<JoinSet<()>>>,
|
||||
}
|
||||
|
||||
impl Default for BidirectRpcManager {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl BidirectRpcManager {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
@@ -42,7 +48,10 @@ impl BidirectRpcManager {
|
||||
pub fn new_with_stats_manager(stats_manager: Arc<StatsManager>) -> Self {
|
||||
Self {
|
||||
rpc_client: Client::new_with_stats_manager(stats_manager.clone()),
|
||||
rpc_server: Server::new_with_registry_and_stats_manager(Arc::new(ServiceRegistry::new()), stats_manager),
|
||||
rpc_server: Server::new_with_registry_and_stats_manager(
|
||||
Arc::new(ServiceRegistry::new()),
|
||||
stats_manager,
|
||||
),
|
||||
|
||||
rx_timeout: None,
|
||||
error: Arc::new(Mutex::new(None)),
|
||||
@@ -176,7 +185,7 @@ impl BidirectRpcManager {
|
||||
return;
|
||||
};
|
||||
tasks.abort_all();
|
||||
while let Some(_) = tasks.join_next().await {}
|
||||
while tasks.join_next().await.is_some() {}
|
||||
}
|
||||
|
||||
pub fn take_error(&self) -> Option<Error> {
|
||||
@@ -187,7 +196,7 @@ impl BidirectRpcManager {
|
||||
let Some(mut tasks) = self.tasks.lock().unwrap().take() else {
|
||||
return;
|
||||
};
|
||||
while let Some(_) = tasks.join_next().await {
|
||||
while tasks.join_next().await.is_some() {
|
||||
// when any task is done, abort all tasks
|
||||
tasks.abort_all();
|
||||
}
|
||||
|
||||
@@ -18,7 +18,9 @@ use crate::defer;
|
||||
use crate::proto::common::{
|
||||
CompressionAlgoPb, RpcCompressionInfo, RpcDescriptor, RpcPacket, RpcRequest, RpcResponse,
|
||||
};
|
||||
use crate::proto::rpc_impl::packet::{build_rpc_packet, compress_packet, decompress_packet};
|
||||
use crate::proto::rpc_impl::packet::{
|
||||
build_rpc_packet, compress_packet, decompress_packet, BuildRpcPacketArgs,
|
||||
};
|
||||
use crate::proto::rpc_types::controller::Controller;
|
||||
use crate::proto::rpc_types::descriptor::MethodDescriptor;
|
||||
use crate::proto::rpc_types::{
|
||||
@@ -53,6 +55,15 @@ struct InflightRequest {
|
||||
start_time: std::time::Instant,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for InflightRequest {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("InflightRequest")
|
||||
.field("sender", &self.sender)
|
||||
.field("start_time", &self.start_time)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct PeerInfo {
|
||||
pub peer_id: PeerId,
|
||||
@@ -72,6 +83,12 @@ pub struct Client {
|
||||
stats_manager: Option<Arc<StatsManager>>,
|
||||
}
|
||||
|
||||
impl Default for Client {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Client {
|
||||
pub fn new() -> Self {
|
||||
let (ring_a, ring_b) = create_ring_tunnel_pair();
|
||||
@@ -86,15 +103,9 @@ impl Client {
|
||||
}
|
||||
|
||||
pub fn new_with_stats_manager(stats_manager: Arc<StatsManager>) -> Self {
|
||||
let (ring_a, ring_b) = create_ring_tunnel_pair();
|
||||
Self {
|
||||
mpsc: Mutex::new(MpscTunnel::new(ring_a, None)),
|
||||
transport: Mutex::new(MpscTunnel::new(ring_b, None)),
|
||||
inflight_requests: Arc::new(DashMap::new()),
|
||||
peer_info: Arc::new(DashMap::new()),
|
||||
tasks: Mutex::new(JoinSet::new()),
|
||||
stats_manager: Some(stats_manager),
|
||||
}
|
||||
let mut ret = Self::new();
|
||||
ret.stats_manager = Some(stats_manager);
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn get_transport_sink(&self) -> MpscTunnelSender {
|
||||
@@ -151,7 +162,11 @@ impl Client {
|
||||
};
|
||||
|
||||
let Some(mut inflight_request) = inflight_requests.get_mut(&key) else {
|
||||
tracing::warn!(?key, "No inflight request found for key");
|
||||
tracing::warn!(
|
||||
?key,
|
||||
?inflight_requests,
|
||||
"No inflight request found for key"
|
||||
);
|
||||
continue;
|
||||
};
|
||||
|
||||
@@ -276,19 +291,19 @@ impl Client {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let packets = build_rpc_packet(
|
||||
self.from_peer_id,
|
||||
self.to_peer_id,
|
||||
let packets = build_rpc_packet(BuildRpcPacketArgs {
|
||||
from_peer: self.from_peer_id,
|
||||
to_peer: self.to_peer_id,
|
||||
rpc_desc,
|
||||
transaction_id,
|
||||
true,
|
||||
&buf,
|
||||
ctrl.trace_id(),
|
||||
RpcCompressionInfo {
|
||||
is_req: true,
|
||||
content: &buf,
|
||||
trace_id: ctrl.trace_id(),
|
||||
compression_info: RpcCompressionInfo {
|
||||
algo: c_algo.into(),
|
||||
accepted_algo: CompressionAlgoPb::Zstd.into(),
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
let timeout_dur = std::time::Duration::from_millis(ctrl.timeout_ms() as u64);
|
||||
let mut rpc_packet = timeout(timeout_dur, self.do_rpc(packets, &mut rx)).await??;
|
||||
@@ -298,7 +313,7 @@ impl Client {
|
||||
self.to_peer_id,
|
||||
PeerInfo {
|
||||
peer_id: self.to_peer_id,
|
||||
compression_info: compression_info.clone(),
|
||||
compression_info,
|
||||
last_active: Some(std::time::Instant::now()),
|
||||
},
|
||||
);
|
||||
|
||||
@@ -21,7 +21,7 @@ pub async fn compress_packet(
|
||||
let algo = accepted_compression_algo
|
||||
.try_into()
|
||||
.unwrap_or(CompressorAlgo::None);
|
||||
let compressed = compressor.compress_raw(&content, algo).await?;
|
||||
let compressed = compressor.compress_raw(content, algo).await?;
|
||||
if compressed.len() >= content.len() {
|
||||
Ok((content.to_vec(), CompressionAlgoPb::None))
|
||||
} else {
|
||||
@@ -35,7 +35,7 @@ pub async fn decompress_packet(
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
let compressor = DefaultCompressor::new();
|
||||
let algo = compression_algo.try_into()?;
|
||||
let decompressed = compressor.decompress_raw(&content, algo).await?;
|
||||
let decompressed = compressor.decompress_raw(content, algo).await?;
|
||||
Ok(decompressed)
|
||||
}
|
||||
|
||||
@@ -45,6 +45,12 @@ pub struct PacketMerger {
|
||||
last_updated: std::time::Instant,
|
||||
}
|
||||
|
||||
impl Default for PacketMerger {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl PacketMerger {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
@@ -133,55 +139,57 @@ impl PacketMerger {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_rpc_packet(
|
||||
from_peer: PeerId,
|
||||
to_peer: PeerId,
|
||||
rpc_desc: RpcDescriptor,
|
||||
transaction_id: RpcTransactId,
|
||||
is_req: bool,
|
||||
content: &Vec<u8>,
|
||||
trace_id: i32,
|
||||
compression_info: RpcCompressionInfo,
|
||||
) -> Vec<ZCPacket> {
|
||||
pub struct BuildRpcPacketArgs<'a> {
|
||||
pub from_peer: PeerId,
|
||||
pub to_peer: PeerId,
|
||||
pub rpc_desc: RpcDescriptor,
|
||||
pub transaction_id: RpcTransactId,
|
||||
pub is_req: bool,
|
||||
pub content: &'a [u8],
|
||||
pub trace_id: i32,
|
||||
pub compression_info: RpcCompressionInfo,
|
||||
}
|
||||
|
||||
pub fn build_rpc_packet(args: BuildRpcPacketArgs<'_>) -> Vec<ZCPacket> {
|
||||
let mut ret = Vec::new();
|
||||
let content_mtu = RPC_PACKET_CONTENT_MTU;
|
||||
let total_pieces = (content.len() + content_mtu - 1) / content_mtu;
|
||||
let total_pieces = args.content.len().div_ceil(content_mtu);
|
||||
let mut cur_offset = 0;
|
||||
while cur_offset < content.len() || content.len() == 0 {
|
||||
while cur_offset < args.content.len() || args.content.is_empty() {
|
||||
let mut cur_len = content_mtu;
|
||||
if cur_offset + cur_len > content.len() {
|
||||
cur_len = content.len() - cur_offset;
|
||||
if cur_offset + cur_len > args.content.len() {
|
||||
cur_len = args.content.len() - cur_offset;
|
||||
}
|
||||
|
||||
let mut cur_content = Vec::new();
|
||||
cur_content.extend_from_slice(&content[cur_offset..cur_offset + cur_len]);
|
||||
cur_content.extend_from_slice(&args.content[cur_offset..cur_offset + cur_len]);
|
||||
|
||||
let cur_packet = RpcPacket {
|
||||
from_peer,
|
||||
to_peer,
|
||||
from_peer: args.from_peer,
|
||||
to_peer: args.to_peer,
|
||||
descriptor: if cur_offset == 0
|
||||
|| compression_info.algo == CompressionAlgoPb::None as i32
|
||||
|| args.compression_info.algo == CompressionAlgoPb::None as i32
|
||||
{
|
||||
// old version must have descriptor on every piece
|
||||
Some(rpc_desc.clone())
|
||||
Some(args.rpc_desc.clone())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
is_request: is_req,
|
||||
is_request: args.is_req,
|
||||
total_pieces: total_pieces as u32,
|
||||
piece_idx: (cur_offset / content_mtu) as u32,
|
||||
transaction_id,
|
||||
piece_idx: (cur_offset / RPC_PACKET_CONTENT_MTU) as u32,
|
||||
transaction_id: args.transaction_id,
|
||||
body: cur_content,
|
||||
trace_id,
|
||||
trace_id: args.trace_id,
|
||||
compression_info: if cur_offset == 0 {
|
||||
Some(compression_info.clone())
|
||||
Some(args.compression_info)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
};
|
||||
cur_offset += cur_len;
|
||||
|
||||
let packet_type = if is_req {
|
||||
let packet_type = if args.is_req {
|
||||
PacketType::RpcReq
|
||||
} else {
|
||||
PacketType::RpcResp
|
||||
@@ -190,10 +198,10 @@ pub fn build_rpc_packet(
|
||||
let mut buf = Vec::new();
|
||||
cur_packet.encode(&mut buf).unwrap();
|
||||
let mut zc_packet = ZCPacket::new_with_payload(&buf);
|
||||
zc_packet.fill_peer_manager_hdr(from_peer, to_peer, packet_type as u8);
|
||||
zc_packet.fill_peer_manager_hdr(args.from_peer, args.to_peer, packet_type as u8);
|
||||
ret.push(zc_packet);
|
||||
|
||||
if content.len() == 0 {
|
||||
if args.content.is_empty() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ use crate::{
|
||||
self, CompressionAlgoPb, RpcCompressionInfo, RpcPacket, RpcRequest, RpcResponse,
|
||||
TunnelInfo,
|
||||
},
|
||||
rpc_impl::packet::BuildRpcPacketArgs,
|
||||
rpc_types::{controller::Controller, error::Result},
|
||||
},
|
||||
tunnel::{
|
||||
@@ -53,6 +54,12 @@ pub struct Server {
|
||||
stats_manager: Option<Arc<StatsManager>>,
|
||||
}
|
||||
|
||||
impl Default for Server {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Server {
|
||||
pub fn new() -> Self {
|
||||
Server::new_with_registry(Arc::new(ServiceRegistry::new()))
|
||||
@@ -139,10 +146,7 @@ impl Server {
|
||||
|
||||
tracing::trace!(?key, ?packet, "Received request packet");
|
||||
|
||||
let ret = packet_merges
|
||||
.entry(key.clone())
|
||||
.or_insert_with(PacketMerger::new)
|
||||
.feed(packet);
|
||||
let ret = packet_merges.entry(key.clone()).or_default().feed(packet);
|
||||
|
||||
match ret {
|
||||
Ok(Some(packet)) => {
|
||||
@@ -238,7 +242,7 @@ impl Server {
|
||||
let mut resp_msg = RpcResponse::default();
|
||||
let now = std::time::Instant::now();
|
||||
|
||||
let compression_info = packet.compression_info.clone();
|
||||
let compression_info = packet.compression_info;
|
||||
let resp_bytes = Self::handle_rpc_request(packet, reg, tunnel_info).await;
|
||||
|
||||
match &resp_bytes {
|
||||
@@ -290,19 +294,19 @@ impl Server {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let packets = build_rpc_packet(
|
||||
to_peer,
|
||||
from_peer,
|
||||
desc,
|
||||
let packets = build_rpc_packet(BuildRpcPacketArgs {
|
||||
from_peer: to_peer,
|
||||
to_peer: from_peer,
|
||||
rpc_desc: desc,
|
||||
transaction_id,
|
||||
false,
|
||||
&compressed_resp,
|
||||
is_req: false,
|
||||
content: &compressed_resp,
|
||||
trace_id,
|
||||
RpcCompressionInfo {
|
||||
compression_info: RpcCompressionInfo {
|
||||
algo: algo.into(),
|
||||
accepted_algo: CompressionAlgoPb::Zstd.into(),
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
for packet in packets {
|
||||
if let Err(err) = sender.send(packet).await {
|
||||
|
||||
@@ -52,6 +52,12 @@ pub struct ServiceRegistry {
|
||||
table: DashMap<ServiceKey, ServiceEntry>,
|
||||
}
|
||||
|
||||
impl Default for ServiceRegistry {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl ServiceRegistry {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
|
||||
@@ -17,7 +17,6 @@ pub trait Handler: Clone + Send + Sync + 'static {
|
||||
type Descriptor: descriptor::ServiceDescriptor + Default;
|
||||
|
||||
type Controller: super::controller::Controller;
|
||||
///
|
||||
|
||||
/// Perform a raw call to the specified service and method.
|
||||
async fn call(
|
||||
|
||||
@@ -233,8 +233,10 @@ async fn rpc_tunnel_stuck_test() {
|
||||
let out =
|
||||
client.scoped_client::<GreetingClientFactory<RpcController>>(1, 1, "test".to_string());
|
||||
tasks.spawn(async move {
|
||||
let mut ctrl = RpcController::default();
|
||||
ctrl.timeout_ms = 1000;
|
||||
let ctrl = RpcController {
|
||||
timeout_ms: 1000,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let input = SayHelloRequest {
|
||||
name: "world".to_string(),
|
||||
@@ -263,8 +265,10 @@ async fn rpc_tunnel_stuck_test() {
|
||||
|
||||
let out =
|
||||
client.scoped_client::<GreetingClientFactory<RpcController>>(1, 1, "test".to_string());
|
||||
let mut ctrl = RpcController::default();
|
||||
ctrl.timeout_ms = 1000;
|
||||
let ctrl = RpcController {
|
||||
timeout_ms: 1000,
|
||||
..Default::default()
|
||||
};
|
||||
let input = SayHelloRequest {
|
||||
name: "fuck world".to_string(),
|
||||
};
|
||||
|
||||
@@ -154,7 +154,6 @@ async fn wait_proxy_route_appear(
|
||||
let now = std::time::Instant::now();
|
||||
loop {
|
||||
for r in mgr.list_routes().await.iter() {
|
||||
let r = r;
|
||||
if r.proxy_cidrs.contains(&proxy_cidr.to_owned()) {
|
||||
assert_eq!(r.peer_id, dst_peer_id);
|
||||
assert_eq!(r.ipv4_addr, Some(ipv4.parse().unwrap()));
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#![allow(clippy::too_many_arguments)]
|
||||
|
||||
use core::panic;
|
||||
use std::{
|
||||
sync::{atomic::AtomicU32, Arc},
|
||||
@@ -214,13 +216,13 @@ pub async fn drop_insts(insts: Vec<Instance>) {
|
||||
debug_assert_eq!(pm.strong_count(), 0, "PeerManager should be dropped");
|
||||
});
|
||||
}
|
||||
while let Some(_) = set.join_next().await {}
|
||||
while set.join_next().await.is_some() {}
|
||||
}
|
||||
|
||||
async fn ping_test(from_netns: &str, target_ip: &str, payload_size: Option<usize>) -> bool {
|
||||
let _g = NetNS::new(Some(ROOT_NETNS_NAME.to_owned())).guard();
|
||||
let code = tokio::process::Command::new("ip")
|
||||
.args(&[
|
||||
.args([
|
||||
"netns",
|
||||
"exec",
|
||||
from_netns,
|
||||
@@ -244,7 +246,7 @@ async fn ping_test(from_netns: &str, target_ip: &str, payload_size: Option<usize
|
||||
async fn ping6_test(from_netns: &str, target_ip: &str, payload_size: Option<usize>) -> bool {
|
||||
let _g = NetNS::new(Some(ROOT_NETNS_NAME.to_owned())).guard();
|
||||
let code = tokio::process::Command::new("ip")
|
||||
.args(&[
|
||||
.args([
|
||||
"netns",
|
||||
"exec",
|
||||
from_netns,
|
||||
@@ -364,7 +366,7 @@ async fn subnet_proxy_test_udp(target_ip: &str) {
|
||||
let udp_connector =
|
||||
UdpTunnelConnector::new(format!("udp://{}:22233", target_ip).parse().unwrap());
|
||||
|
||||
let mut buf = vec![0; 1 * 1024];
|
||||
let mut buf = vec![0; 1024];
|
||||
rand::thread_rng().fill(&mut buf[..]);
|
||||
|
||||
_tunnel_pingpong_netns(
|
||||
@@ -397,7 +399,7 @@ async fn subnet_proxy_test_udp(target_ip: &str) {
|
||||
let udp_listener = UdpTunnelListener::new("udp://0.0.0.0:22235".parse().unwrap());
|
||||
let udp_connector = UdpTunnelConnector::new("udp://10.144.144.3:22235".parse().unwrap());
|
||||
|
||||
let mut buf = vec![0; 1 * 1024];
|
||||
let mut buf = vec![0; 1024];
|
||||
rand::thread_rng().fill(&mut buf[..]);
|
||||
|
||||
_tunnel_pingpong_netns(
|
||||
@@ -690,8 +692,7 @@ pub async fn proxy_three_node_disconnect_test(#[values("tcp", "wg")] proto: &str
|
||||
.list_routes()
|
||||
.await
|
||||
.iter()
|
||||
.find(|r| r.peer_id == inst4.peer_id())
|
||||
.is_some()
|
||||
.any(|r| r.peer_id == inst4.peer_id())
|
||||
},
|
||||
Duration::from_secs(8),
|
||||
)
|
||||
@@ -706,14 +707,13 @@ pub async fn proxy_three_node_disconnect_test(#[values("tcp", "wg")] proto: &str
|
||||
}));
|
||||
wait_for_condition(
|
||||
|| async {
|
||||
let ret = insts[2]
|
||||
let ret = !insts[2]
|
||||
.get_peer_manager()
|
||||
.get_peer_map()
|
||||
.list_peers_with_conn()
|
||||
.await
|
||||
.iter()
|
||||
.find(|r| **r == inst4.peer_id())
|
||||
.is_none();
|
||||
.any(|r| *r == inst4.peer_id());
|
||||
|
||||
ret
|
||||
},
|
||||
@@ -726,13 +726,12 @@ pub async fn proxy_three_node_disconnect_test(#[values("tcp", "wg")] proto: &str
|
||||
|
||||
wait_for_condition(
|
||||
|| async {
|
||||
insts[0]
|
||||
!insts[0]
|
||||
.get_peer_manager()
|
||||
.list_routes()
|
||||
.await
|
||||
.iter()
|
||||
.find(|r| r.peer_id == inst4.peer_id())
|
||||
.is_none()
|
||||
.any(|r| r.peer_id == inst4.peer_id())
|
||||
},
|
||||
Duration::from_secs(7),
|
||||
)
|
||||
@@ -788,9 +787,8 @@ pub async fn udp_broadcast_test() {
|
||||
// socket.connect(("10.144.144.255", 22111)).await.unwrap();
|
||||
let call: Vec<u8> = vec![1; 1024];
|
||||
println!("Sending call, {} bytes", call.len());
|
||||
match socket.send_to(&call, "10.144.144.255:22111").await {
|
||||
Err(e) => panic!("Error sending call: {:?}", e),
|
||||
_ => {}
|
||||
if let Err(e) = socket.send_to(&call, "10.144.144.255:22111").await {
|
||||
panic!("Error sending call: {:?}", e)
|
||||
}
|
||||
|
||||
tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
|
||||
@@ -1163,7 +1161,7 @@ pub async fn manual_reconnector(#[values(true, false)] is_foreign: bool) {
|
||||
|
||||
let conns = peer_map.list_peer_conns(center_inst_peer_id).await.unwrap();
|
||||
|
||||
assert!(conns.len() >= 1);
|
||||
assert!(!conns.is_empty());
|
||||
|
||||
wait_for_condition(
|
||||
|| async { ping_test("net_b", "10.144.145.2", None).await },
|
||||
@@ -1405,39 +1403,47 @@ pub async fn acl_rule_test_inbound(
|
||||
let mut acl = Acl::default();
|
||||
let mut acl_v1 = AclV1::default();
|
||||
|
||||
let mut chain = Chain::default();
|
||||
chain.name = "test_inbound".to_string();
|
||||
chain.chain_type = ChainType::Inbound as i32;
|
||||
chain.enabled = true;
|
||||
let mut chain = Chain {
|
||||
name: "test_inbound".to_string(),
|
||||
chain_type: ChainType::Inbound as i32,
|
||||
enabled: true,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// 禁止 8080
|
||||
let mut deny_rule = Rule::default();
|
||||
deny_rule.name = "deny_8080".to_string();
|
||||
deny_rule.priority = 200;
|
||||
deny_rule.enabled = true;
|
||||
deny_rule.action = Action::Drop as i32;
|
||||
deny_rule.protocol = Protocol::Any as i32;
|
||||
deny_rule.ports = vec!["8080".to_string()];
|
||||
let deny_rule = Rule {
|
||||
name: "deny_8080".to_string(),
|
||||
priority: 200,
|
||||
enabled: true,
|
||||
action: Action::Drop as i32,
|
||||
protocol: Protocol::Any as i32,
|
||||
ports: vec!["8080".to_string()],
|
||||
..Default::default()
|
||||
};
|
||||
chain.rules.push(deny_rule);
|
||||
|
||||
// 允许其他
|
||||
let mut allow_rule = Rule::default();
|
||||
allow_rule.name = "allow_all".to_string();
|
||||
allow_rule.priority = 100;
|
||||
allow_rule.enabled = true;
|
||||
allow_rule.action = Action::Allow as i32;
|
||||
allow_rule.protocol = Protocol::Any as i32;
|
||||
allow_rule.stateful = true;
|
||||
let allow_rule = Rule {
|
||||
name: "allow_all".to_string(),
|
||||
priority: 100,
|
||||
enabled: true,
|
||||
action: Action::Allow as i32,
|
||||
protocol: Protocol::Any as i32,
|
||||
stateful: true,
|
||||
..Default::default()
|
||||
};
|
||||
chain.rules.push(allow_rule);
|
||||
|
||||
// 禁止 src ip 为 10.144.144.2 的流量
|
||||
let mut deny_rule = Rule::default();
|
||||
deny_rule.name = "deny_10.144.144.2".to_string();
|
||||
deny_rule.priority = 200;
|
||||
deny_rule.enabled = true;
|
||||
deny_rule.action = Action::Drop as i32;
|
||||
deny_rule.protocol = Protocol::Any as i32;
|
||||
deny_rule.source_ips = vec!["10.144.144.2/32".to_string()];
|
||||
let deny_rule = Rule {
|
||||
name: "deny_10.144.144.2".to_string(),
|
||||
priority: 200,
|
||||
enabled: true,
|
||||
action: Action::Drop as i32,
|
||||
protocol: Protocol::Any as i32,
|
||||
source_ips: vec!["10.144.144.2/32".to_string()],
|
||||
..Default::default()
|
||||
};
|
||||
chain.rules.push(deny_rule);
|
||||
|
||||
acl_v1.chains.push(chain);
|
||||
@@ -1626,42 +1632,50 @@ pub async fn acl_rule_test_subnet_proxy(
|
||||
let mut acl = Acl::default();
|
||||
let mut acl_v1 = AclV1::default();
|
||||
|
||||
let mut chain = Chain::default();
|
||||
chain.name = "test_subnet_proxy_inbound".to_string();
|
||||
chain.chain_type = ChainType::Forward as i32;
|
||||
chain.enabled = true;
|
||||
let mut chain = Chain {
|
||||
name: "test_subnet_proxy_inbound".to_string(),
|
||||
chain_type: ChainType::Forward as i32,
|
||||
enabled: true,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// 禁止访问子网代理中的 8080 端口
|
||||
let mut deny_rule = Rule::default();
|
||||
deny_rule.name = "deny_subnet_8080".to_string();
|
||||
deny_rule.priority = 200;
|
||||
deny_rule.enabled = true;
|
||||
deny_rule.action = Action::Drop as i32;
|
||||
deny_rule.protocol = Protocol::Any as i32;
|
||||
deny_rule.ports = vec!["8080".to_string()];
|
||||
deny_rule.destination_ips = vec!["10.1.2.0/24".to_string()];
|
||||
let deny_rule = Rule {
|
||||
name: "deny_subnet_8080".to_string(),
|
||||
priority: 200,
|
||||
enabled: true,
|
||||
action: Action::Drop as i32,
|
||||
protocol: Protocol::Any as i32,
|
||||
ports: vec!["8080".to_string()],
|
||||
destination_ips: vec!["10.1.2.0/24".to_string()],
|
||||
..Default::default()
|
||||
};
|
||||
chain.rules.push(deny_rule);
|
||||
|
||||
// 禁止来自 inst1 (10.144.144.1) 访问子网代理中的 8081 端口
|
||||
let mut deny_src_rule = Rule::default();
|
||||
deny_src_rule.name = "deny_inst1_to_subnet_8081".to_string();
|
||||
deny_src_rule.priority = 200;
|
||||
deny_src_rule.enabled = true;
|
||||
deny_src_rule.action = Action::Drop as i32;
|
||||
deny_src_rule.protocol = Protocol::Any as i32;
|
||||
deny_src_rule.ports = vec!["8081".to_string()];
|
||||
deny_src_rule.source_ips = vec!["10.144.144.1/32".to_string()];
|
||||
deny_src_rule.destination_ips = vec!["10.1.2.0/24".to_string()];
|
||||
let deny_src_rule = Rule {
|
||||
name: "deny_inst1_to_subnet_8081".to_string(),
|
||||
priority: 200,
|
||||
enabled: true,
|
||||
action: Action::Drop as i32,
|
||||
protocol: Protocol::Any as i32,
|
||||
ports: vec!["8081".to_string()],
|
||||
source_ips: vec!["10.144.144.1/32".to_string()],
|
||||
destination_ips: vec!["10.1.2.0/24".to_string()],
|
||||
..Default::default()
|
||||
};
|
||||
chain.rules.push(deny_src_rule);
|
||||
|
||||
// 允许其他流量
|
||||
let mut allow_rule = Rule::default();
|
||||
allow_rule.name = "allow_all".to_string();
|
||||
allow_rule.priority = 100;
|
||||
allow_rule.enabled = true;
|
||||
allow_rule.action = Action::Allow as i32;
|
||||
allow_rule.protocol = Protocol::Any as i32;
|
||||
allow_rule.stateful = true;
|
||||
let allow_rule = Rule {
|
||||
name: "allow_all".to_string(),
|
||||
priority: 100,
|
||||
enabled: true,
|
||||
action: Action::Allow as i32,
|
||||
protocol: Protocol::Any as i32,
|
||||
stateful: true,
|
||||
..Default::default()
|
||||
};
|
||||
chain.rules.push(allow_rule);
|
||||
|
||||
acl_v1.chains.push(chain);
|
||||
|
||||
@@ -145,8 +145,7 @@ where
|
||||
return Poll::Ready(None);
|
||||
}
|
||||
|
||||
while let Some(packet) =
|
||||
Self::extract_one_packet(self_mut.buf, *self_mut.max_packet_size)
|
||||
if let Some(packet) = Self::extract_one_packet(self_mut.buf, *self_mut.max_packet_size)
|
||||
{
|
||||
if let Err(TunnelError::InvalidPacket(msg)) = packet.as_ref() {
|
||||
self_mut
|
||||
@@ -157,7 +156,7 @@ where
|
||||
}
|
||||
|
||||
reserve_buf(
|
||||
&mut self_mut.buf,
|
||||
self_mut.buf,
|
||||
*self_mut.max_packet_size,
|
||||
*self_mut.max_packet_size * 2,
|
||||
);
|
||||
@@ -186,12 +185,12 @@ where
|
||||
}
|
||||
|
||||
pub trait ZCPacketToBytes {
|
||||
fn into_bytes(&self, zc_packet: ZCPacket) -> Result<Bytes, TunnelError>;
|
||||
fn zcpacket_into_bytes(&self, zc_packet: ZCPacket) -> Result<Bytes, TunnelError>;
|
||||
}
|
||||
|
||||
pub struct TcpZCPacketToBytes;
|
||||
impl ZCPacketToBytes for TcpZCPacketToBytes {
|
||||
fn into_bytes(&self, item: ZCPacket) -> Result<Bytes, TunnelError> {
|
||||
fn zcpacket_into_bytes(&self, item: ZCPacket) -> Result<Bytes, TunnelError> {
|
||||
let mut item = item.convert_type(ZCPacketType::TCP);
|
||||
|
||||
let tcp_len = PEER_MANAGER_HEADER_SIZE + item.payload_len();
|
||||
@@ -280,7 +279,9 @@ where
|
||||
|
||||
fn start_send(self: Pin<&mut Self>, item: ZCPacket) -> Result<(), Self::Error> {
|
||||
let pinned = self.project();
|
||||
pinned.sending_bufs.push(pinned.converter.into_bytes(item)?);
|
||||
pinned
|
||||
.sending_bufs
|
||||
.push(pinned.converter.zcpacket_into_bytes(item)?);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -461,14 +462,13 @@ pub mod tests {
|
||||
continue;
|
||||
};
|
||||
tracing::debug!(?msg, "recv a msg, try echo back");
|
||||
if let Err(_) = send.send(msg).await {
|
||||
if send.send(msg).await.is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let Some(ret) = recv.next().await else {
|
||||
assert!(false, "recv error");
|
||||
return;
|
||||
panic!("recv error");
|
||||
};
|
||||
|
||||
if ret.is_err() {
|
||||
@@ -597,7 +597,7 @@ pub mod tests {
|
||||
let elapsed_sec = now.elapsed().as_secs();
|
||||
if elapsed_sec > 0 {
|
||||
bps_clone.store(
|
||||
count as u64 / now.elapsed().as_secs() as u64,
|
||||
count as u64 / now.elapsed().as_secs(),
|
||||
std::sync::atomic::Ordering::Relaxed,
|
||||
);
|
||||
}
|
||||
@@ -621,7 +621,7 @@ pub mod tests {
|
||||
while now.elapsed().as_secs() < 10 {
|
||||
// send.feed(item)
|
||||
let item = ZCPacket::new_with_payload(send_buf.as_ref());
|
||||
let _ = send.feed(item).await.unwrap();
|
||||
send.feed(item).await.unwrap();
|
||||
}
|
||||
|
||||
send.close().await.unwrap();
|
||||
@@ -649,7 +649,7 @@ pub mod tests {
|
||||
.init();
|
||||
}
|
||||
|
||||
pub async fn wait_for_condition<F, FRet>(mut condition: F, timeout: std::time::Duration) -> ()
|
||||
pub async fn wait_for_condition<F, FRet>(mut condition: F, timeout: std::time::Duration)
|
||||
where
|
||||
F: FnMut() -> FRet + Send,
|
||||
FRet: Future<Output = bool>,
|
||||
|
||||
@@ -227,7 +227,7 @@ impl TunnelFilter for PacketRecorderTunnelFilter {
|
||||
fn after_received(&self, data: StreamItem) -> Option<StreamItem> {
|
||||
match data {
|
||||
Ok(v) => {
|
||||
self.sent.lock().unwrap().push(v.clone().into());
|
||||
self.sent.lock().unwrap().push(v.clone());
|
||||
Some(Ok(v))
|
||||
}
|
||||
Err(e) => Some(Err(e)),
|
||||
@@ -242,6 +242,12 @@ impl TunnelFilter for PacketRecorderTunnelFilter {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for PacketRecorderTunnelFilter {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl PacketRecorderTunnelFilter {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
@@ -278,6 +284,12 @@ impl TunnelFilter for StatsRecorderTunnelFilter {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for StatsRecorderTunnelFilter {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl StatsRecorderTunnelFilter {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
|
||||
@@ -90,9 +90,11 @@ impl<T> ZCPacketStream for T where T: Stream<Item = StreamItem> + Send {}
|
||||
pub trait ZCPacketSink: Sink<SinkItem, Error = SinkError> + Send {}
|
||||
impl<T> ZCPacketSink for T where T: Sink<SinkItem, Error = SinkError> + Send {}
|
||||
|
||||
pub type SplitTunnel = (Pin<Box<dyn ZCPacketStream>>, Pin<Box<dyn ZCPacketSink>>);
|
||||
|
||||
#[auto_impl::auto_impl(Box, Arc)]
|
||||
pub trait Tunnel: Send {
|
||||
fn split(&self) -> (Pin<Box<dyn ZCPacketStream>>, Pin<Box<dyn ZCPacketSink>>);
|
||||
fn split(&self) -> SplitTunnel;
|
||||
fn info(&self) -> Option<TunnelInfo>;
|
||||
}
|
||||
|
||||
@@ -189,7 +191,7 @@ where
|
||||
return Err(TunnelError::InvalidProtocol(url.scheme().to_string()));
|
||||
}
|
||||
|
||||
Ok(T::from_url(url.clone(), ip_version).await?)
|
||||
T::from_url(url.clone(), ip_version).await
|
||||
}
|
||||
|
||||
fn default_port(scheme: &str) -> Option<u16> {
|
||||
@@ -269,7 +271,7 @@ impl TunnelUrl {
|
||||
if s.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(String::from_utf8(percent_encoding::percent_decode_str(&s).collect()).unwrap())
|
||||
Some(String::from_utf8(percent_encoding::percent_decode_str(s).collect()).unwrap())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -86,12 +86,9 @@ impl<T: Tunnel> MpscTunnel<T> {
|
||||
sink.feed(initial_item).await?;
|
||||
|
||||
while let Ok(item) = rx.try_recv() {
|
||||
match sink.feed(item).await {
|
||||
Err(e) => {
|
||||
tracing::error!(?e, "feed error");
|
||||
return Err(e);
|
||||
}
|
||||
Ok(_) => {}
|
||||
if let Err(e) = sink.feed(item).await {
|
||||
tracing::error!(?e, "feed error");
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -423,7 +423,7 @@ impl ZCPacket {
|
||||
let total_len = payload_off + payload.len();
|
||||
ret.inner.reserve(total_len);
|
||||
unsafe { ret.inner.set_len(total_len) };
|
||||
ret.mut_payload()[..payload.len()].copy_from_slice(&payload);
|
||||
ret.mut_payload()[..payload.len()].copy_from_slice(payload);
|
||||
ret
|
||||
}
|
||||
|
||||
@@ -440,7 +440,7 @@ impl ZCPacket {
|
||||
dst_peer_id: u32,
|
||||
foreign_zc_packet: &ZCPacket,
|
||||
) -> Self {
|
||||
let foreign_network_hdr = ForeignNetworkPacketHeader::new(dst_peer_id, &network_name);
|
||||
let foreign_network_hdr = ForeignNetworkPacketHeader::new(dst_peer_id, network_name);
|
||||
let total_payload_len =
|
||||
foreign_network_hdr.get_header_len() + foreign_zc_packet.tunnel_payload().len();
|
||||
|
||||
@@ -639,7 +639,7 @@ impl ZCPacket {
|
||||
return Self::new_from_buf(buf, target_packet_type);
|
||||
}
|
||||
|
||||
return Self::new_from_buf(self.inner.split_off(new_offset), target_packet_type);
|
||||
Self::new_from_buf(self.inner.split_off(new_offset), target_packet_type)
|
||||
}
|
||||
|
||||
pub fn into_bytes(self) -> Bytes {
|
||||
@@ -656,7 +656,7 @@ impl ZCPacket {
|
||||
|
||||
pub fn is_lossy(&self) -> bool {
|
||||
self.peer_manager_header()
|
||||
.and_then(|hdr| Some(hdr.packet_type == PacketType::Data as u8))
|
||||
.map(|hdr| hdr.packet_type == PacketType::Data as u8)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
|
||||
@@ -90,8 +90,8 @@ impl AsyncUdpSocket for NoGroAsyncUdpSocket {
|
||||
pub fn make_server_endpoint(bind_addr: SocketAddr) -> Result<(Endpoint, Vec<u8>), Box<dyn Error>> {
|
||||
let (server_config, server_cert) = configure_server()?;
|
||||
let socket = std::net::UdpSocket::bind(bind_addr)?;
|
||||
let runtime = quinn::default_runtime()
|
||||
.ok_or_else(|| std::io::Error::new(std::io::ErrorKind::Other, "no async runtime found"))?;
|
||||
let runtime =
|
||||
quinn::default_runtime().ok_or_else(|| std::io::Error::other("no async runtime found"))?;
|
||||
let mut endpoint_config = EndpointConfig::default();
|
||||
endpoint_config.max_udp_payload_size(1200)?;
|
||||
let socket = NoGroAsyncUdpSocket {
|
||||
@@ -110,7 +110,7 @@ pub fn make_server_endpoint(bind_addr: SocketAddr) -> Result<(Endpoint, Vec<u8>)
|
||||
pub fn configure_server() -> Result<(ServerConfig, Vec<u8>), Box<dyn Error>> {
|
||||
let (certs, key) = get_insecure_tls_cert();
|
||||
|
||||
let mut server_config = ServerConfig::with_single_cert(certs.clone(), key.into())?;
|
||||
let mut server_config = ServerConfig::with_single_cert(certs.clone(), key)?;
|
||||
let transport_config = Arc::get_mut(&mut server_config.transport).unwrap();
|
||||
transport_config.max_concurrent_uni_streams(10_u8.into());
|
||||
transport_config.max_concurrent_bidi_streams(10_u8.into());
|
||||
@@ -123,8 +123,6 @@ pub fn configure_server() -> Result<(ServerConfig, Vec<u8>), Box<dyn Error>> {
|
||||
#[allow(unused)]
|
||||
pub const ALPN_QUIC_HTTP: &[&[u8]] = &[b"hq-29"];
|
||||
|
||||
/// Runs a QUIC server bound to given address.
|
||||
|
||||
struct ConnWrapper {
|
||||
conn: Connection,
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user