Spam filter performance and accuracy improvements (part 2)

This commit is contained in:
mdecimus
2025-11-30 18:28:27 +01:00
parent 05ef5a7c10
commit 53a04ce069
59 changed files with 961 additions and 1004 deletions

View File

@@ -51,21 +51,13 @@ pub struct SpamFilterConfig {
pub pyzor: Option<PyzorConfig>,
pub classifier: Option<ClassifierConfig>,
pub scores: SpamFilterScoreConfig,
pub headers: SpamFilterHeaderConfig,
}
#[derive(Debug, Clone)]
pub struct SpamFilterHeaderConfig {
pub status: Option<String>,
pub result: Option<String>,
pub llm: Option<String>,
}
#[derive(Debug, Clone, Default)]
pub struct SpamFilterScoreConfig {
pub reject_threshold: f64,
pub discard_threshold: f64,
pub spam_threshold: f64,
pub reject_threshold: f32,
pub discard_threshold: f32,
pub spam_threshold: f32,
}
#[derive(Debug, Clone, Default)]
@@ -80,7 +72,7 @@ pub struct DnsBlConfig {
#[derive(Debug, Clone, Default)]
pub struct SpamFilterLists {
pub file_extensions: GlobMap<FileExtension>,
pub scores: GlobMap<SpamFilterAction<f64>>,
pub scores: GlobMap<SpamFilterAction<f32>>,
}
#[derive(Debug, Clone)]
@@ -88,6 +80,7 @@ pub enum SpamFilterAction<T> {
Allow(T),
Discard,
Reject,
Disabled,
}
#[derive(Debug, Clone, Default)]
@@ -97,8 +90,8 @@ pub struct ClassifierConfig {
pub alpha: f32,
pub auto_learn_reply_ham: bool,
pub auto_learn_card_is_ham: bool,
pub score_spam: f64,
pub score_ham: f64,
pub score_spam: f32,
pub score_ham: f32,
}
#[derive(Debug, Clone)]
@@ -185,7 +178,6 @@ impl SpamFilterConfig {
pyzor: PyzorConfig::parse(config).await,
classifier: ClassifierConfig::parse(config),
scores: SpamFilterScoreConfig::parse(config),
headers: SpamFilterHeaderConfig::parse(config),
grey_list_expiry: config
.property::<Option<Duration>>("spam-filter.grey-list.duration")
.unwrap_or_default()
@@ -316,31 +308,6 @@ impl DnsBlServer {
}
}
impl SpamFilterHeaderConfig {
pub fn parse(config: &mut Config) -> Self {
let mut header = SpamFilterHeaderConfig::default();
for (typ, var) in [
("status", &mut header.status),
("result", &mut header.result),
("llm", &mut header.llm),
] {
if config
.property_or_default(("spam-filter.header", typ, "enable"), "true")
.unwrap_or(true)
&& let Some(value) = config.value(("spam-filter.header", typ, "name"))
{
let value = value.trim();
if !value.is_empty() {
*var = value.to_string().into();
}
}
}
header
}
}
impl SpamFilterLists {
pub fn parse(config: &mut Config) -> Self {
let mut lists = SpamFilterLists {
@@ -571,16 +538,6 @@ impl Location {
}
}
impl Default for SpamFilterHeaderConfig {
fn default() -> Self {
SpamFilterHeaderConfig {
status: "X-Spam-Status".to_string().into(),
result: "X-Spam-Result".to_string().into(),
llm: "X-Spam-LLM".to_string().into(),
}
}
}
pub const V_SPAM_REMOTE_IP: u32 = 100;
pub const V_SPAM_REMOTE_IP_PTR: u32 = 101;
pub const V_SPAM_EHLO_DOMAIN: u32 = 102;
@@ -809,3 +766,12 @@ impl CacheItemWeight for IpResolver {
(std::mem::size_of::<IpResolver>() + self.ip_string.len() + self.reverse.len()) as u64
}
}
impl<T> SpamFilterAction<T> {
pub fn as_score(&self) -> Option<&T> {
match self {
SpamFilterAction::Allow(value) => Some(value),
_ => None,
}
}
}

View File

@@ -4,12 +4,16 @@
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
use self::tokenizer::TokenMap;
use compact_str::CompactString;
use regex::Regex;
use std::{
borrow::Cow,
fmt::{Display, Formatter},
net::{IpAddr, Ipv4Addr, Ipv6Addr},
time::Duration,
};
use utils::config::{Rate, utils::ParseValue};
pub const V_RECIPIENT: u32 = 0;
pub const V_RECIPIENT_DOMAIN: u32 = 1;
@@ -81,12 +85,6 @@ pub const VARIABLES_MAP: &[(&str, u32)] = &[
("queue_age", V_QUEUE_AGE),
];
use compact_str::CompactString;
use regex::Regex;
use utils::config::{Rate, utils::ParseValue};
use self::tokenizer::TokenMap;
pub mod eval;
pub mod functions;
pub mod if_block;