account_registration: GC the per-IP rate-limit table on the tick (an entry per distinct registering IP was never dropped)
This commit is contained in:
parent
e28efb03e6
commit
7563daf3a3
2 changed files with 22 additions and 0 deletions
|
|
@ -23,6 +23,7 @@ use std::collections::HashMap;
|
|||
|
||||
use crate::command::{CmdResult, Command};
|
||||
use crate::http::{json_str, urlencode};
|
||||
use crate::module::Module;
|
||||
use crate::server::{now, Server};
|
||||
use crate::Uid;
|
||||
|
||||
|
|
@ -30,6 +31,26 @@ use crate::Uid;
|
|||
#[derive(Default)]
|
||||
struct RateState(HashMap<String, Vec<u64>>);
|
||||
|
||||
/// Ticks the rate-limit table: prunes each IP's timestamps to the window and drops
|
||||
/// IPs with none left, so the map can't accumulate one entry per distinct IP that
|
||||
/// ever issued a REGISTER over the process lifetime.
|
||||
pub struct AcctRegGc;
|
||||
impl Module for AcctRegGc {
|
||||
fn name(&self) -> &'static str {
|
||||
"account_registration"
|
||||
}
|
||||
fn on_tick(&mut self, s: &mut Server) {
|
||||
let window = s.conf_num("acctregister_ratetime", 3600u64);
|
||||
let n = now();
|
||||
if let Some(st) = s.ext.get_mut::<RateState>() {
|
||||
st.0.retain(|_, hist| {
|
||||
hist.retain(|&t| n.saturating_sub(t) < window);
|
||||
!hist.is_empty()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn enabled(s: &Server) -> bool {
|
||||
s.conf_bool("account_registration", false) && s.conf("acctregister_registerurl").is_some()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ pub fn default_modules() -> Vec<Box<dyn Module>> {
|
|||
Box::new(operprefix::OperPrefix),
|
||||
Box::new(permchannels::PermChannels::default()),
|
||||
Box::new(chathistory::ChatHistoryGc),
|
||||
Box::new(account_registration::AcctRegGc),
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue