sdlan-lib-rs/src/tcp/identity_cache.rs

71 lines
2.0 KiB
Rust

use std::{collections::{HashMap, HashSet}, sync::{OnceLock}, time::{SystemTime, UNIX_EPOCH}};
use dashmap::{DashMap};
use tracing::debug;
type IdentityID = u32;
type Port = u16;
type Proto = u8;
#[derive(Debug)]
pub struct RuleInfo {
pub proto: Proto,
pub port: Port,
}
static RULE_CACHE: OnceLock<DashMap<IdentityID, (u64, HashMap<Port, HashSet<Proto>>)>> = OnceLock::new();
// static RULE_CACHE: OnceLock<DashMap<IdentityID, HashMap<Port, HashMap<Proto, AtomicU64>>>> = OnceLock::new();
pub fn set_identity_cache(identity: IdentityID, infos: Vec<RuleInfo>) {
debug!("setting identity cache for identity={}, infos: {:?}", identity, infos);
let cache = RULE_CACHE.get().expect("should set first");
let mut temp = HashMap::new();
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs();
for info in &infos {
let mut protomap = HashSet::new();
protomap.insert(info.proto);
temp.insert(info.port, protomap);
}
cache.remove(&identity);
cache.insert(identity, (now, temp));
}
// result.1 is should renew
pub fn is_identity_ok(identity: IdentityID, proto: Proto, port: Port) -> (Option<bool>, bool) {
let cache = RULE_CACHE.get().expect("should set first");
let mut should_renew = false;
let result: Option<bool>;
match cache.get(&identity) {
Some(data) => {
let tm = data.0;
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs();
if tm + 10 < now {
should_renew = true;
}
if let Some(proto_info) = data.1.get(&port) {
if let Some(_has) = proto_info.get(&proto) {
result = Some(true);
// return Some(true);
} else {
result = Some(false);
}
} else {
result = Some(false);
}
}
None => {
result = None;
}
}
return (result, should_renew);
}