mirror of
https://github.com/telemt/telemt.git
synced 2026-10-11 03:45:58 +03:00
81 lines
2.7 KiB
Rust
81 lines
2.7 KiB
Rust
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
|
use std::path::Path;
|
|
use std::time::Duration;
|
|
|
|
use super::*;
|
|
use crate::synlimit_control::model::{
|
|
SynLimitNamespace, SynLimitRule, SynLimitTargets, synlimit_namespace,
|
|
};
|
|
|
|
fn rule(ip: IpAddr, hitcount: u32) -> SynLimitRule {
|
|
SynLimitRule {
|
|
ip: Some(ip),
|
|
port: 24443,
|
|
generic_seconds: 60,
|
|
generic_hitcount: hitcount,
|
|
generic_burst: 24,
|
|
ios_seconds: 1,
|
|
ios_hitcount: 12,
|
|
ios_burst: 24,
|
|
hashlimit_expire_ms: 60_000,
|
|
hashlimit_size: 32_768,
|
|
}
|
|
}
|
|
|
|
fn targets(low_family: &str) -> SynLimitTargets {
|
|
let (v4_rate, v6_rate) = match low_family {
|
|
"v4" => (2, 100),
|
|
"v6" => (100, 2),
|
|
_ => panic!("TELEMT_PF_LOW_FAMILY must be v4 or v6"),
|
|
};
|
|
SynLimitTargets {
|
|
pf_v4: vec![rule(IpAddr::V4(Ipv4Addr::new(198, 18, 1, 1)), v4_rate)],
|
|
pf_v6: vec![rule(
|
|
IpAddr::V6("fd00:18:1::1".parse::<Ipv6Addr>().unwrap()),
|
|
v6_rate,
|
|
)],
|
|
..Default::default()
|
|
}
|
|
}
|
|
|
|
fn write_metadata(path: &str, namespace: &SynLimitNamespace) {
|
|
std::fs::write(path, format!("anchor={}\n", namespace.pf_anchor)).unwrap();
|
|
}
|
|
|
|
async fn wait_for_file(path: &Path) {
|
|
tokio::time::timeout(Duration::from_secs(30), async {
|
|
while !path.exists() {
|
|
tokio::time::sleep(Duration::from_millis(20)).await;
|
|
}
|
|
})
|
|
.await
|
|
.expect("PF runtime-test release barrier timed out");
|
|
}
|
|
|
|
#[tokio::test]
|
|
#[ignore = "requires native FreeBSD PF and VNET test harness"]
|
|
async fn production_pf_runtime_role() {
|
|
let role = std::env::var("TELEMT_PF_ROLE").expect("TELEMT_PF_ROLE is required");
|
|
let low_family = std::env::var("TELEMT_PF_LOW_FAMILY").unwrap_or_else(|_| "v4".to_string());
|
|
let targets = targets(&low_family);
|
|
let namespace = synlimit_namespace(&targets).expect("PF namespace missing");
|
|
let metadata = std::env::var("TELEMT_PF_META").expect("TELEMT_PF_META is required");
|
|
match role.as_str() {
|
|
"render" => {
|
|
let script_path = std::env::var("TELEMT_PF_SCRIPT").unwrap();
|
|
std::fs::write(script_path, pf_synlimit_script(&targets)).unwrap();
|
|
write_metadata(&metadata, &namespace);
|
|
}
|
|
"apply-wait" => {
|
|
apply_synlimit_rules(&targets, &namespace).await.unwrap();
|
|
write_metadata(&metadata, &namespace);
|
|
let barrier = std::env::var("TELEMT_PF_BARRIER").unwrap();
|
|
let release = std::env::var("TELEMT_PF_RELEASE").unwrap();
|
|
std::fs::write(&barrier, b"ready").unwrap();
|
|
wait_for_file(Path::new(&release)).await;
|
|
assert!(clear_rules(&namespace).await.unwrap());
|
|
}
|
|
_ => panic!("TELEMT_PF_ROLE must be render or apply-wait"),
|
|
}
|
|
}
|