mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-08-31 16:29:05 +00:00
fix packet split on udp tunnel and avoid tcp proxy access rpc portal (#2107)
* distinct control / data when forward packets * fix rpc split for udp tunnel * feat(easytier-web): pass public ip in validate token webhook * protect rpc port from subnet proxy
This commit is contained in:
@@ -55,8 +55,8 @@ use super::{
|
||||
relay_peer_map::RelayPeerMap,
|
||||
route_trait::NextHopPolicy,
|
||||
traffic_metrics::{
|
||||
InstanceLabelKind, LogicalTrafficMetrics, TrafficMetricRecorder,
|
||||
route_peer_info_instance_id,
|
||||
InstanceLabelKind, LogicalTrafficMetrics, TrafficKind, TrafficMetricRecorder,
|
||||
route_peer_info_instance_id, traffic_kind,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -419,12 +419,19 @@ impl ForeignNetworkEntry {
|
||||
|
||||
let label_set =
|
||||
LabelSet::new().with_label_type(LabelType::NetworkName(network_name.clone()));
|
||||
let forward_bytes = self
|
||||
let forward_data_bytes = self
|
||||
.stats_mgr
|
||||
.get_counter(MetricName::TrafficBytesForwarded, label_set.clone());
|
||||
let forward_packets = self
|
||||
let forward_data_packets = self
|
||||
.stats_mgr
|
||||
.get_counter(MetricName::TrafficPacketsForwarded, label_set.clone());
|
||||
let forward_control_bytes = self
|
||||
.stats_mgr
|
||||
.get_counter(MetricName::TrafficControlBytesForwarded, label_set.clone());
|
||||
let forward_control_packets = self.stats_mgr.get_counter(
|
||||
MetricName::TrafficControlPacketsForwarded,
|
||||
label_set.clone(),
|
||||
);
|
||||
let rx_bytes = self
|
||||
.stats_mgr
|
||||
.get_counter(MetricName::TrafficBytesSelfRx, label_set.clone());
|
||||
@@ -502,8 +509,16 @@ impl ForeignNetworkEntry {
|
||||
}
|
||||
}
|
||||
|
||||
forward_bytes.add(buf_len as u64);
|
||||
forward_packets.inc();
|
||||
match traffic_kind(packet_type) {
|
||||
TrafficKind::Data => {
|
||||
forward_data_bytes.add(buf_len as u64);
|
||||
forward_data_packets.inc();
|
||||
}
|
||||
TrafficKind::Control => {
|
||||
forward_control_bytes.add(buf_len as u64);
|
||||
forward_control_packets.inc();
|
||||
}
|
||||
}
|
||||
|
||||
let gateway_peer_id = peer_map
|
||||
.get_gateway_peer_id(to_peer_id, NextHopPolicy::LeastHop)
|
||||
@@ -1293,6 +1308,11 @@ pub mod tests {
|
||||
MetricName::TrafficBytesForwarded,
|
||||
network_labels.clone(),
|
||||
);
|
||||
let forwarded_packets_before = metric_value(
|
||||
&pm_center,
|
||||
MetricName::TrafficPacketsForwarded,
|
||||
network_labels.clone(),
|
||||
);
|
||||
let rx_bytes_before = metric_value(
|
||||
&pm_center,
|
||||
MetricName::TrafficBytesRx,
|
||||
@@ -1320,6 +1340,7 @@ pub mod tests {
|
||||
pmb_net1.my_peer_id(),
|
||||
PacketType::Data as u8,
|
||||
);
|
||||
let transit_pkt_len = transit_pkt.buf_len() as u64;
|
||||
pma_net1
|
||||
.get_foreign_network_client()
|
||||
.send_msg(transit_pkt, center_peer_id)
|
||||
@@ -1334,7 +1355,12 @@ pub mod tests {
|
||||
&pm_center,
|
||||
MetricName::TrafficBytesForwarded,
|
||||
network_labels.clone(),
|
||||
) > forwarded_bytes_before
|
||||
) >= forwarded_bytes_before + transit_pkt_len
|
||||
&& metric_value(
|
||||
&pm_center,
|
||||
MetricName::TrafficPacketsForwarded,
|
||||
network_labels.clone(),
|
||||
) > forwarded_packets_before
|
||||
}
|
||||
},
|
||||
Duration::from_secs(5),
|
||||
@@ -1371,6 +1397,70 @@ pub mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn foreign_network_transit_control_forwarding_records_control_forwarded_metrics() {
|
||||
let pm_center = create_mock_peer_manager_with_mock_stun(NatType::Unknown).await;
|
||||
let pma_net1 = create_mock_peer_manager_for_foreign_network("net1").await;
|
||||
let pmb_net1 = create_mock_peer_manager_for_foreign_network("net1").await;
|
||||
|
||||
connect_peer_manager(pma_net1.clone(), pm_center.clone()).await;
|
||||
connect_peer_manager(pmb_net1.clone(), pm_center.clone()).await;
|
||||
wait_route_appear(pma_net1.clone(), pmb_net1.clone())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let center_peer_id = pm_center
|
||||
.get_foreign_network_manager()
|
||||
.get_network_peer_id("net1")
|
||||
.unwrap();
|
||||
let network_labels =
|
||||
LabelSet::new().with_label_type(LabelType::NetworkName("net1".to_string()));
|
||||
let forwarded_bytes_before = metric_value(
|
||||
&pm_center,
|
||||
MetricName::TrafficControlBytesForwarded,
|
||||
network_labels.clone(),
|
||||
);
|
||||
let forwarded_packets_before = metric_value(
|
||||
&pm_center,
|
||||
MetricName::TrafficControlPacketsForwarded,
|
||||
network_labels.clone(),
|
||||
);
|
||||
|
||||
let mut transit_pkt = ZCPacket::new_with_payload(b"foreign-control-transit");
|
||||
transit_pkt.fill_peer_manager_hdr(
|
||||
pma_net1.my_peer_id(),
|
||||
pmb_net1.my_peer_id(),
|
||||
PacketType::RpcReq as u8,
|
||||
);
|
||||
let transit_pkt_len = transit_pkt.buf_len() as u64;
|
||||
pma_net1
|
||||
.get_foreign_network_client()
|
||||
.send_msg(transit_pkt, center_peer_id)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
wait_for_condition(
|
||||
|| {
|
||||
let pm_center = pm_center.clone();
|
||||
let network_labels = network_labels.clone();
|
||||
async move {
|
||||
metric_value(
|
||||
&pm_center,
|
||||
MetricName::TrafficControlBytesForwarded,
|
||||
network_labels.clone(),
|
||||
) >= forwarded_bytes_before + transit_pkt_len
|
||||
&& metric_value(
|
||||
&pm_center,
|
||||
MetricName::TrafficControlPacketsForwarded,
|
||||
network_labels.clone(),
|
||||
) > forwarded_packets_before
|
||||
}
|
||||
},
|
||||
Duration::from_secs(5),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn foreign_network_encapsulated_forwarding_records_tx_metrics() {
|
||||
set_global_var!(OSPF_UPDATE_MY_GLOBAL_FOREIGN_NETWORK_INTERVAL_SEC, 1);
|
||||
|
||||
@@ -37,8 +37,8 @@ use crate::{
|
||||
recv_packet_from_chan,
|
||||
route_trait::{ForeignNetworkRouteInfoMap, MockRoute, NextHopPolicy, RouteInterface},
|
||||
traffic_metrics::{
|
||||
InstanceLabelKind, LogicalTrafficMetrics, TrafficMetricRecorder,
|
||||
route_peer_info_instance_id,
|
||||
InstanceLabelKind, LogicalTrafficMetrics, TrafficKind, TrafficMetricRecorder,
|
||||
route_peer_info_instance_id, traffic_kind,
|
||||
},
|
||||
},
|
||||
proto::{
|
||||
@@ -888,10 +888,16 @@ impl PeerManager {
|
||||
stats_mgr.get_counter(MetricName::TrafficBytesSelfRx, label_set.clone());
|
||||
let self_rx_packets =
|
||||
stats_mgr.get_counter(MetricName::TrafficPacketsSelfRx, label_set.clone());
|
||||
let forward_tx_bytes =
|
||||
let forward_data_tx_bytes =
|
||||
stats_mgr.get_counter(MetricName::TrafficBytesForwarded, label_set.clone());
|
||||
let forward_tx_packets =
|
||||
let forward_data_tx_packets =
|
||||
stats_mgr.get_counter(MetricName::TrafficPacketsForwarded, label_set.clone());
|
||||
let forward_control_tx_bytes =
|
||||
stats_mgr.get_counter(MetricName::TrafficControlBytesForwarded, label_set.clone());
|
||||
let forward_control_tx_packets = stats_mgr.get_counter(
|
||||
MetricName::TrafficControlPacketsForwarded,
|
||||
label_set.clone(),
|
||||
);
|
||||
|
||||
let compress_tx_bytes_before = self.self_tx_counters.compress_tx_bytes_before.clone();
|
||||
let compress_tx_bytes_after = self.self_tx_counters.compress_tx_bytes_after.clone();
|
||||
@@ -966,8 +972,16 @@ impl PeerManager {
|
||||
self_tx_bytes.add(ret.buf_len() as u64);
|
||||
self_tx_packets.inc();
|
||||
} else {
|
||||
forward_tx_bytes.add(buf_len as u64);
|
||||
forward_tx_packets.inc();
|
||||
match traffic_kind(packet_type) {
|
||||
TrafficKind::Data => {
|
||||
forward_data_tx_bytes.add(buf_len as u64);
|
||||
forward_data_tx_packets.inc();
|
||||
}
|
||||
TrafficKind::Control => {
|
||||
forward_control_tx_bytes.add(buf_len as u64);
|
||||
forward_control_tx_packets.inc();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tracing::trace!(?to_peer_id, ?my_peer_id, "need forward");
|
||||
@@ -2053,6 +2067,12 @@ mod tests {
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
fn network_labels(peer_mgr: &PeerManager) -> LabelSet {
|
||||
LabelSet::new().with_label_type(LabelType::NetworkName(
|
||||
peer_mgr.get_global_ctx().get_network_name(),
|
||||
))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recent_traffic_fanout_policy_only_marks_single_peer() {
|
||||
assert!(PeerManager::should_mark_recent_traffic_for_fanout(0));
|
||||
@@ -2439,6 +2459,136 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn send_msg_internal_records_data_forwarded_metrics_for_transit_peer() {
|
||||
let peer_mgr_a = create_mock_peer_manager_with_mock_stun(NatType::Unknown).await;
|
||||
let peer_mgr_b = create_mock_peer_manager_with_mock_stun(NatType::Unknown).await;
|
||||
let peer_mgr_c = create_mock_peer_manager_with_mock_stun(NatType::Unknown).await;
|
||||
|
||||
connect_peer_manager(peer_mgr_a.clone(), peer_mgr_b.clone()).await;
|
||||
connect_peer_manager(peer_mgr_b.clone(), peer_mgr_c.clone()).await;
|
||||
wait_route_appear(peer_mgr_a.clone(), peer_mgr_c.clone())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let b_network_labels = network_labels(&peer_mgr_b);
|
||||
let forwarded_bytes_before = metric_value(
|
||||
&peer_mgr_b,
|
||||
MetricName::TrafficBytesForwarded,
|
||||
&b_network_labels,
|
||||
);
|
||||
let forwarded_packets_before = metric_value(
|
||||
&peer_mgr_b,
|
||||
MetricName::TrafficPacketsForwarded,
|
||||
&b_network_labels,
|
||||
);
|
||||
|
||||
let mut pkt = ZCPacket::new_with_payload(b"forward-data");
|
||||
pkt.fill_peer_manager_hdr(
|
||||
peer_mgr_a.my_peer_id(),
|
||||
peer_mgr_c.my_peer_id(),
|
||||
PacketType::Data as u8,
|
||||
);
|
||||
let pkt_len = pkt.buf_len() as u64;
|
||||
|
||||
PeerManager::send_msg_internal(
|
||||
&peer_mgr_a.peers,
|
||||
&peer_mgr_a.foreign_network_client,
|
||||
&peer_mgr_a.relay_peer_map,
|
||||
Some(&peer_mgr_a.traffic_metrics),
|
||||
pkt,
|
||||
peer_mgr_c.my_peer_id(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
wait_for_condition(
|
||||
|| {
|
||||
let peer_mgr_b = peer_mgr_b.clone();
|
||||
let b_network_labels = b_network_labels.clone();
|
||||
async move {
|
||||
metric_value(
|
||||
&peer_mgr_b,
|
||||
MetricName::TrafficBytesForwarded,
|
||||
&b_network_labels,
|
||||
) >= forwarded_bytes_before + pkt_len
|
||||
&& metric_value(
|
||||
&peer_mgr_b,
|
||||
MetricName::TrafficPacketsForwarded,
|
||||
&b_network_labels,
|
||||
) > forwarded_packets_before
|
||||
}
|
||||
},
|
||||
Duration::from_secs(5),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn send_msg_internal_records_control_forwarded_metrics_for_transit_peer() {
|
||||
let peer_mgr_a = create_mock_peer_manager_with_mock_stun(NatType::Unknown).await;
|
||||
let peer_mgr_b = create_mock_peer_manager_with_mock_stun(NatType::Unknown).await;
|
||||
let peer_mgr_c = create_mock_peer_manager_with_mock_stun(NatType::Unknown).await;
|
||||
|
||||
connect_peer_manager(peer_mgr_a.clone(), peer_mgr_b.clone()).await;
|
||||
connect_peer_manager(peer_mgr_b.clone(), peer_mgr_c.clone()).await;
|
||||
wait_route_appear(peer_mgr_a.clone(), peer_mgr_c.clone())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let b_network_labels = network_labels(&peer_mgr_b);
|
||||
let forwarded_bytes_before = metric_value(
|
||||
&peer_mgr_b,
|
||||
MetricName::TrafficControlBytesForwarded,
|
||||
&b_network_labels,
|
||||
);
|
||||
let forwarded_packets_before = metric_value(
|
||||
&peer_mgr_b,
|
||||
MetricName::TrafficControlPacketsForwarded,
|
||||
&b_network_labels,
|
||||
);
|
||||
|
||||
let mut pkt = ZCPacket::new_with_payload(b"forward-control");
|
||||
pkt.fill_peer_manager_hdr(
|
||||
peer_mgr_a.my_peer_id(),
|
||||
peer_mgr_c.my_peer_id(),
|
||||
PacketType::RpcReq as u8,
|
||||
);
|
||||
let pkt_len = pkt.buf_len() as u64;
|
||||
|
||||
PeerManager::send_msg_internal(
|
||||
&peer_mgr_a.peers,
|
||||
&peer_mgr_a.foreign_network_client,
|
||||
&peer_mgr_a.relay_peer_map,
|
||||
Some(&peer_mgr_a.traffic_metrics),
|
||||
pkt,
|
||||
peer_mgr_c.my_peer_id(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
wait_for_condition(
|
||||
|| {
|
||||
let peer_mgr_b = peer_mgr_b.clone();
|
||||
let b_network_labels = b_network_labels.clone();
|
||||
async move {
|
||||
metric_value(
|
||||
&peer_mgr_b,
|
||||
MetricName::TrafficControlBytesForwarded,
|
||||
&b_network_labels,
|
||||
) >= forwarded_bytes_before + pkt_len
|
||||
&& metric_value(
|
||||
&peer_mgr_b,
|
||||
MetricName::TrafficControlPacketsForwarded,
|
||||
&b_network_labels,
|
||||
) > forwarded_packets_before
|
||||
}
|
||||
},
|
||||
Duration::from_secs(5),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn recent_traffic_tolerates_future_timestamps() {
|
||||
let peer_mgr_a = create_lazy_peer_manager().await;
|
||||
|
||||
@@ -220,12 +220,27 @@ impl LogicalTrafficMetrics {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum TrafficKind {
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub(crate) enum TrafficKind {
|
||||
Data,
|
||||
Control,
|
||||
}
|
||||
|
||||
pub(crate) fn traffic_kind(packet_type: u8) -> TrafficKind {
|
||||
if packet_type == PacketType::Data as u8
|
||||
|| packet_type == PacketType::KcpSrc as u8
|
||||
|| packet_type == PacketType::KcpDst as u8
|
||||
|| packet_type == PacketType::QuicSrc as u8
|
||||
|| packet_type == PacketType::QuicDst as u8
|
||||
|| packet_type == PacketType::DataWithKcpSrcModified as u8
|
||||
|| packet_type == PacketType::DataWithQuicSrcModified as u8
|
||||
{
|
||||
TrafficKind::Data
|
||||
} else {
|
||||
TrafficKind::Control
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct TrafficMetricGroup {
|
||||
data: Arc<LogicalTrafficMetrics>,
|
||||
@@ -282,7 +297,7 @@ impl TrafficMetricRecorder {
|
||||
return;
|
||||
}
|
||||
self.tx_metrics
|
||||
.select(Self::traffic_kind(packet_type))
|
||||
.select(traffic_kind(packet_type))
|
||||
.record_with_resolver(peer_id, bytes, || self.resolve_instance_id(peer_id))
|
||||
.await;
|
||||
}
|
||||
@@ -292,7 +307,7 @@ impl TrafficMetricRecorder {
|
||||
return;
|
||||
}
|
||||
self.rx_metrics
|
||||
.select(Self::traffic_kind(packet_type))
|
||||
.select(traffic_kind(packet_type))
|
||||
.record_with_resolver(peer_id, bytes, || self.resolve_instance_id(peer_id))
|
||||
.await;
|
||||
}
|
||||
@@ -314,21 +329,6 @@ impl TrafficMetricRecorder {
|
||||
fn resolve_instance_id(&self, peer_id: PeerId) -> BoxFuture<'static, Option<String>> {
|
||||
(self.resolve_instance_id)(peer_id)
|
||||
}
|
||||
|
||||
fn traffic_kind(packet_type: u8) -> TrafficKind {
|
||||
if packet_type == PacketType::Data as u8
|
||||
|| packet_type == PacketType::KcpSrc as u8
|
||||
|| packet_type == PacketType::KcpDst as u8
|
||||
|| packet_type == PacketType::QuicSrc as u8
|
||||
|| packet_type == PacketType::QuicDst as u8
|
||||
|| packet_type == PacketType::DataWithKcpSrcModified as u8
|
||||
|| packet_type == PacketType::DataWithQuicSrcModified as u8
|
||||
{
|
||||
TrafficKind::Data
|
||||
} else {
|
||||
TrafficKind::Control
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn route_peer_info_instance_id(route_peer_info: &RoutePeerInfo) -> Option<String> {
|
||||
|
||||
Reference in New Issue
Block a user