mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-09-02 17:15:43 +00:00
fix: eliminate unsafe code in packet construction and stats counters
Replace all UnsafeCell-based counters with safe alternatives: - New ShardedCounter: per-thread TLS accumulation (thread_local crate) with periodic publish to static AtomicU64. Zero atomic RMW on hot path. - ACL RuleStatsTracker: remove unsafe Arc<RuleStats> raw pointer mutation, use two ShardedCounter fields. - ZCPacket: replace set_len on uninitialized BytesMut with write_bytes + copy_nonoverlapping before set_len. - StatsManager UnsafeCounter/MetricData: remove UnsafeCell and unsafe impl Send/Sync, wrap ShardedCounter. last_updated uses AtomicU64 epoch millis. - Throughput: replace UnsafeCell with AtomicU64. - secure_datagram: fix grace-window test timestamp.
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
|
||||
use easytier::common::acl_processor::{AclProcessor, PacketInfo};
|
||||
use easytier::proto::acl::*;
|
||||
use std::net::{IpAddr, Ipv4Addr};
|
||||
|
||||
fn make_acl_config() -> Acl {
|
||||
let mut acl_config = Acl::default();
|
||||
let mut acl_v1 = AclV1::default();
|
||||
|
||||
let mut chain = Chain {
|
||||
name: "bench_inbound".to_string(),
|
||||
chain_type: ChainType::Inbound as i32,
|
||||
enabled: true,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
chain.rules.push(Rule {
|
||||
name: "allow_all".to_string(),
|
||||
priority: 100,
|
||||
enabled: true,
|
||||
action: Action::Allow as i32,
|
||||
protocol: Protocol::Any as i32,
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
acl_v1.chains.push(chain);
|
||||
acl_config.acl_v1 = Some(acl_v1);
|
||||
acl_config
|
||||
}
|
||||
|
||||
fn make_packet_info() -> PacketInfo {
|
||||
PacketInfo {
|
||||
src_ip: IpAddr::V4(Ipv4Addr::new(192, 168, 1, 100)),
|
||||
dst_ip: IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)),
|
||||
src_port: Some(12345),
|
||||
dst_port: Some(80),
|
||||
protocol: Protocol::Tcp,
|
||||
packet_size: 1024,
|
||||
src_groups: Arc::new(vec![]),
|
||||
dst_groups: Arc::new(vec![]),
|
||||
}
|
||||
}
|
||||
|
||||
fn bench_cache_hit_single(c: &mut Criterion) {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let processor = rt.block_on(async { AclProcessor::new(make_acl_config()) });
|
||||
let packet_info = make_packet_info();
|
||||
|
||||
// Prime the cache
|
||||
let _ = processor.process_packet(&packet_info, ChainType::Inbound);
|
||||
|
||||
c.bench_function("acl_cache_hit_1t", |b| {
|
||||
b.iter(|| {
|
||||
std::hint::black_box(processor.process_packet(&packet_info, ChainType::Inbound));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn bench_cache_hit_multi(c: &mut Criterion) {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let mut group = c.benchmark_group("acl_cache_hit_multi");
|
||||
for threads in [2, 4, 8] {
|
||||
let processor = Arc::new(rt.block_on(async { AclProcessor::new(make_acl_config()) }));
|
||||
let packet_info = Arc::new(make_packet_info());
|
||||
|
||||
// Prime the cache
|
||||
let _ = processor.process_packet(&packet_info, ChainType::Inbound);
|
||||
|
||||
group.bench_with_input(
|
||||
BenchmarkId::from_parameter(threads),
|
||||
&threads,
|
||||
|b, &threads| {
|
||||
b.iter_custom(|iters| {
|
||||
use std::sync::Barrier;
|
||||
use std::thread;
|
||||
|
||||
let barrier = Arc::new(Barrier::new(threads + 1));
|
||||
let per_thread = (iters / threads as u64) as usize;
|
||||
let mut handles = Vec::with_capacity(threads);
|
||||
|
||||
for _ in 0..threads {
|
||||
let processor = Arc::clone(&processor);
|
||||
let packet_info = Arc::clone(&packet_info);
|
||||
let barrier = Arc::clone(&barrier);
|
||||
handles.push(thread::spawn(move || {
|
||||
barrier.wait();
|
||||
for _ in 0..per_thread {
|
||||
std::hint::black_box(
|
||||
processor.process_packet(&packet_info, ChainType::Inbound),
|
||||
);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
barrier.wait();
|
||||
for handle in handles {
|
||||
handle.join().unwrap();
|
||||
}
|
||||
start.elapsed()
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
group.finish();
|
||||
}
|
||||
|
||||
fn bench_unique_rule_match(c: &mut Criterion) {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let processor = rt.block_on(async { AclProcessor::new(make_acl_config()) });
|
||||
|
||||
c.bench_function("acl_unique_rule_match_1t", |b| {
|
||||
let mut i = 0usize;
|
||||
b.iter(|| {
|
||||
let mut packet_info = make_packet_info();
|
||||
packet_info.src_port = Some((1024 + (i % 60_000)) as u16);
|
||||
packet_info.src_ip = IpAddr::V4(Ipv4Addr::new(
|
||||
10,
|
||||
((i >> 16) & 0xff) as u8,
|
||||
((i >> 8) & 0xff) as u8,
|
||||
(i & 0xff) as u8,
|
||||
));
|
||||
std::hint::black_box(processor.process_packet(&packet_info, ChainType::Inbound));
|
||||
i = i.wrapping_add(1);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(
|
||||
benches,
|
||||
bench_cache_hit_single,
|
||||
bench_cache_hit_multi,
|
||||
bench_unique_rule_match
|
||||
);
|
||||
criterion_main!(benches);
|
||||
@@ -0,0 +1,51 @@
|
||||
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
|
||||
use easytier::tunnel::packet_def::{ZCPacket, ZCPacketType};
|
||||
|
||||
fn bench_new_with_payload(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("zc_new_with_payload");
|
||||
for size in [64usize, 1500] {
|
||||
let payload = vec![0xabu8; size];
|
||||
group.bench_with_input(BenchmarkId::from_parameter(size), &payload, |b, payload| {
|
||||
b.iter(|| {
|
||||
std::hint::black_box(ZCPacket::new_with_payload(std::hint::black_box(payload)));
|
||||
});
|
||||
});
|
||||
}
|
||||
group.finish();
|
||||
}
|
||||
|
||||
fn bench_new_for_foreign_network(c: &mut Criterion) {
|
||||
let payload = vec![0xabu8; 64];
|
||||
let foreign_packet = ZCPacket::new_with_payload(&payload);
|
||||
let network_name = "bench-network".to_string();
|
||||
|
||||
c.bench_function("zc_new_for_foreign_network_64b", |b| {
|
||||
b.iter(|| {
|
||||
std::hint::black_box(ZCPacket::new_for_foreign_network(
|
||||
std::hint::black_box(&network_name),
|
||||
42,
|
||||
std::hint::black_box(&foreign_packet),
|
||||
));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn bench_convert_type(c: &mut Criterion) {
|
||||
let payload = vec![0xabu8; 64];
|
||||
let packet = ZCPacket::new_with_payload(&payload);
|
||||
|
||||
c.bench_function("zc_convert_type_tcp_64b", |b| {
|
||||
b.iter(|| {
|
||||
let p = std::hint::black_box(packet.clone());
|
||||
std::hint::black_box(p.convert_type(ZCPacketType::TCP));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(
|
||||
benches,
|
||||
bench_new_with_payload,
|
||||
bench_new_for_foreign_network,
|
||||
bench_convert_type
|
||||
);
|
||||
criterion_main!(benches);
|
||||
Reference in New Issue
Block a user