use crate::correlation::{CampaignUpdate, FingerprintIndex};
use std::net::IpAddr;
pub type DetectorResult<T> = Result<T, DetectorError>;
#[derive(Debug, Clone)]
pub enum DetectorError {
IndexUnavailable(String),
DetectionFailed(String),
RateLimited,
}
impl std::fmt::Display for DetectorError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
DetectorError::IndexUnavailable(msg) => write!(f, "Index unavailable: {}", msg),
DetectorError::DetectionFailed(msg) => write!(f, "Detection failed: {}", msg),
DetectorError::RateLimited => write!(f, "Detection rate limited"),
}
}
}
impl std::error::Error for DetectorError {}
pub trait Detector: Send + Sync {
fn name(&self) -> &'static str;
fn analyze(&self, index: &FingerprintIndex) -> DetectorResult<Vec<CampaignUpdate>>;
fn should_trigger(&self, ip: &IpAddr, index: &FingerprintIndex) -> bool;
fn scan_interval_ms(&self) -> u64 {
5000 }
}
pub mod attack_sequence;
pub mod auth_token;
pub mod behavioral_similarity;
pub mod common;
pub mod graph;
pub mod ja4_rotation;
pub mod network_proximity;
pub mod shared_fingerprint;
pub mod timing_correlation;
pub use attack_sequence::{AttackPayload, AttackSequenceConfig, AttackSequenceDetector};
pub use auth_token::{AuthTokenConfig, AuthTokenDetector, TokenFingerprint};
pub use behavioral_similarity::{BehaviorPattern, BehavioralConfig, BehavioralSimilarityDetector};
pub use common::TimeWindowedIndex;
pub use graph::{GraphConfig, GraphDetector};
pub use ja4_rotation::{Ja4RotationDetector, Ja4RotationStats, RotationConfig};
pub use network_proximity::{NetworkProximityConfig, NetworkProximityDetector};
pub use shared_fingerprint::SharedFingerprintDetector;
pub use timing_correlation::{TimingConfig, TimingCorrelationDetector};