Files
wehub-resource-sync 19dc5d82a0
Rust / build (push) Failing after 1s
Rust / docker (push) Failing after 0s
chore: import upstream snapshot with attribution
2026-07-13 12:29:44 +08:00

102 lines
3.6 KiB
Rust

use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main};
use rustnet_monitor::network::parser::{ParsedPacket, TcpFlags, TcpHeaderInfo};
use rustnet_monitor::network::tracker::ConnectionTracker;
use rustnet_monitor::network::types::*;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::time::SystemTime;
/// Build a synthetic TCP data packet for one of `n_connections` flows.
///
/// Flows are distinguished by client port so the workload exercises the
/// tracker's key hashing and DashMap sharding the same way live traffic does.
fn make_packet(flow: u16, seq: u32) -> ParsedPacket {
let local_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 100)), 10000 + flow);
let remote_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(93, 184, 216, 34)), 443);
ParsedPacket {
protocol: Protocol::Tcp,
local_addr,
remote_addr,
tcp_header: Some(TcpHeaderInfo {
seq,
ack: seq.wrapping_add(1),
window: 65535,
flags: TcpFlags {
syn: false,
ack: true,
fin: false,
rst: false,
psh: true,
urg: false,
},
payload_len: 1400,
}),
protocol_state: ProtocolState::Tcp(TcpState::Established),
is_outgoing: true,
packet_len: 1400,
dpi_result: None,
process_name: None,
process_id: None,
}
}
/// Interleaved packet stream: `flows` connections sending `packets_per_flow`
/// packets round-robin, mimicking concurrent flows rather than one flow at a
/// time.
fn make_workload(flows: u16, packets_per_flow: u32) -> Vec<ParsedPacket> {
let mut packets = Vec::with_capacity(flows as usize * packets_per_flow as usize);
for round in 0..packets_per_flow {
for flow in 0..flows {
packets.push(make_packet(flow, round * 1460));
}
}
packets
}
/// The canonical per-packet ingest cost: parse results folded into a fresh
/// tracker (mix of connection creation and in-place merge). This is the
/// before/after number for connection-key, timestamp, and limit-check work
/// on the packet path.
fn bench_tracker_ingest(c: &mut Criterion) {
let now = SystemTime::now();
let mut group = c.benchmark_group("tracker_ingest");
for (flows, per_flow) in [(100u16, 100u32), (1000, 50)] {
let packets = make_workload(flows, per_flow);
group.throughput(Throughput::Elements(packets.len() as u64));
group.bench_with_input(
BenchmarkId::new("fresh_tracker", format!("{flows}x{per_flow}")),
&packets,
|b, packets| {
b.iter(|| {
let tracker = ConnectionTracker::new();
for p in packets {
tracker.ingest_at(p, now);
}
tracker
});
},
);
}
group.finish();
// Steady state: every packet updates an existing connection (no creation).
let mut group = c.benchmark_group("tracker_ingest_steady");
let packets = make_workload(1000, 1);
let tracker = ConnectionTracker::new();
for p in &packets {
tracker.ingest_at(p, now);
}
group.throughput(Throughput::Elements(packets.len() as u64));
group.bench_function("existing_connections_1000", |b| {
b.iter(|| {
for p in &packets {
tracker.ingest_at(p, now);
}
});
});
group.finish();
}
criterion_group!(benches, bench_tracker_ingest);
criterion_main!(benches);