chore: update scanner/ddos trainers, benchmarks, and tests

Expand DDoS feature vector to 14 dimensions (cookie_ratio, referer_ratio,
accept_language_ratio, suspicious_path_ratio). Add heuristic auto-labeling
to DDoS trainer. Update benchmarks and tests to match new feature vectors.

Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
This commit is contained in:
2026-03-10 23:38:21 +00:00
parent 905fd78299
commit 5daed3ecb0
5 changed files with 599 additions and 160 deletions

40
benches/ddos_bench.rs Normal file
View File

@@ -0,0 +1,40 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use sunbeam_proxy::ensemble::ddos::ddos_ensemble_predict;
use sunbeam_proxy::ensemble::gen::ddos_weights;
use sunbeam_proxy::ensemble::mlp::mlp_predict_32;
use sunbeam_proxy::ensemble::tree::tree_predict;
fn bench_ensemble_ddos_full(c: &mut Criterion) {
let raw: [f32; 14] = [5.0, 10.0, 2.0, 0.1, 50.0, 0.5, 3.0, 0.3, 500.0, 2.0, 0.8, 0.7, 0.9, 0.1];
c.bench_function("ensemble::ddos full predict", |b| {
b.iter(|| ddos_ensemble_predict(black_box(&raw)))
});
}
fn bench_ensemble_ddos_tree_only(c: &mut Criterion) {
let input: [f32; 14] = [0.5; 14];
c.bench_function("ensemble::ddos tree_only", |b| {
b.iter(|| tree_predict(black_box(&ddos_weights::TREE_NODES), black_box(&input)))
});
}
fn bench_ensemble_ddos_mlp_only(c: &mut Criterion) {
let input: [f32; 14] = [0.5; 14];
c.bench_function("ensemble::ddos mlp_only", |b| {
b.iter(|| mlp_predict_32::<14>(
black_box(&ddos_weights::W1),
black_box(&ddos_weights::B1),
black_box(&ddos_weights::W2),
black_box(ddos_weights::B2),
black_box(&input),
))
});
}
criterion_group!(
benches,
bench_ensemble_ddos_full,
bench_ensemble_ddos_tree_only,
bench_ensemble_ddos_mlp_only,
);
criterion_main!(benches);

View File

@@ -1,5 +1,9 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use sunbeam_proxy::config::RouteConfig;
use sunbeam_proxy::ensemble::gen::scanner_weights;
use sunbeam_proxy::ensemble::mlp::mlp_predict_32;
use sunbeam_proxy::ensemble::scanner::scanner_ensemble_predict;
use sunbeam_proxy::ensemble::tree::tree_predict;
use sunbeam_proxy::scanner::detector::ScannerDetector;
use sunbeam_proxy::scanner::features::{
self, fx_hash_bytes, ScannerNormParams, NUM_SCANNER_FEATURES, NUM_SCANNER_WEIGHTS,
@@ -250,6 +254,34 @@ fn bench_extract_features(c: &mut Criterion) {
});
}
fn bench_ensemble_scanner_full(c: &mut Criterion) {
// Raw features simulating a scanner probe
let raw: [f32; 12] = [0.8, 3.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.25, 0.0, 0.0, 0.0, 1.0];
c.bench_function("ensemble::scanner full predict", |b| {
b.iter(|| scanner_ensemble_predict(black_box(&raw)))
});
}
fn bench_ensemble_scanner_tree_only(c: &mut Criterion) {
let input: [f32; 12] = [0.8, 0.3, 1.0, 0.0, 0.0, 0.0, 0.0, 0.25, 0.0, 0.0, 0.0, 1.0];
c.bench_function("ensemble::scanner tree_only", |b| {
b.iter(|| tree_predict(black_box(&scanner_weights::TREE_NODES), black_box(&input)))
});
}
fn bench_ensemble_scanner_mlp_only(c: &mut Criterion) {
let input: [f32; 12] = [0.5; 12];
c.bench_function("ensemble::scanner mlp_only", |b| {
b.iter(|| mlp_predict_32::<12>(
black_box(&scanner_weights::W1),
black_box(&scanner_weights::B1),
black_box(&scanner_weights::W2),
black_box(scanner_weights::B2),
black_box(&input),
))
});
}
criterion_group!(
benches,
bench_check_normal_browser,
@@ -260,5 +292,8 @@ criterion_group!(
bench_check_deep_path,
bench_check_api_legitimate,
bench_extract_features,
bench_ensemble_scanner_full,
bench_ensemble_scanner_tree_only,
bench_ensemble_scanner_mlp_only,
);
criterion_main!(benches);