use std::num::NonZeroU32;
use std::time::Duration;
#[derive(Clone, Debug)]
pub struct RateLimitTierConfig {
pub short_term_rps: NonZeroU32,
pub short_term_burst: NonZeroU32,
pub long_term_rph: NonZeroU32,
pub long_term_burst: NonZeroU32,
}
impl RateLimitTierConfig {
pub fn new(short_rps: u32, short_burst: u32, long_rph: u32, long_burst: u32) -> Self {
Self {
short_term_rps: NonZeroU32::new(short_rps).unwrap_or(NonZeroU32::MIN),
short_term_burst: NonZeroU32::new(short_burst).unwrap_or(NonZeroU32::MIN),
long_term_rph: NonZeroU32::new(long_rph).unwrap_or(NonZeroU32::MIN),
long_term_burst: NonZeroU32::new(long_burst).unwrap_or(NonZeroU32::MIN),
}
}
}
#[derive(Clone, Debug)]
pub struct EndpointCategoryConfig {
pub name: &'static str,
pub ipv4_individual: RateLimitTierConfig,
pub ipv4_network: RateLimitTierConfig,
pub ipv6_subnet: RateLimitTierConfig,
pub ipv6_provider: RateLimitTierConfig,
}
#[derive(Clone, Debug)]
pub struct RateLimitConfig {
pub auth: EndpointCategoryConfig,
pub dav: EndpointCategoryConfig,
pub federation: EndpointCategoryConfig,
pub general: EndpointCategoryConfig,
pub websocket: EndpointCategoryConfig,
pub max_tracked_ips: usize,
pub entry_ttl: Duration,
}
impl Default for RateLimitConfig {
fn default() -> Self {
Self {
auth: EndpointCategoryConfig {
name: "auth",
ipv4_individual: RateLimitTierConfig::new(5, 10, 60, 60),
ipv4_network: RateLimitTierConfig::new(15, 30, 200, 200),
ipv6_subnet: RateLimitTierConfig::new(5, 10, 60, 60),
ipv6_provider: RateLimitTierConfig::new(15, 30, 200, 200),
},
dav: EndpointCategoryConfig {
name: "dav",
ipv4_individual: RateLimitTierConfig::new(30, 60, 2000, 500),
ipv4_network: RateLimitTierConfig::new(60, 120, 5000, 1000),
ipv6_subnet: RateLimitTierConfig::new(30, 60, 2000, 500),
ipv6_provider: RateLimitTierConfig::new(60, 120, 5000, 1000),
},
federation: EndpointCategoryConfig {
name: "federation",
ipv4_individual: RateLimitTierConfig::new(100, 200, 1000, 100),
ipv4_network: RateLimitTierConfig::new(500, 750, 5000, 500),
ipv6_subnet: RateLimitTierConfig::new(100, 200, 1000, 100),
ipv6_provider: RateLimitTierConfig::new(500, 750, 5000, 500),
},
general: EndpointCategoryConfig {
name: "general",
ipv4_individual: RateLimitTierConfig::new(300, 500, 5000, 500),
ipv4_network: RateLimitTierConfig::new(600, 1000, 50000, 5000),
ipv6_subnet: RateLimitTierConfig::new(300, 500, 5000, 500),
ipv6_provider: RateLimitTierConfig::new(600, 1000, 50000, 5000),
},
websocket: EndpointCategoryConfig {
name: "websocket",
ipv4_individual: RateLimitTierConfig::new(100, 200, 1000, 500),
ipv4_network: RateLimitTierConfig::new(100, 200, 1000, 500),
ipv6_subnet: RateLimitTierConfig::new(100, 200, 1000, 500),
ipv6_provider: RateLimitTierConfig::new(100, 200, 1000, 500),
},
max_tracked_ips: 100_000,
entry_ttl: Duration::from_hours(1),
}
}
}
#[derive(Clone, Debug)]
pub struct PowConfig {
pub max_counter: u32,
pub decay_interval_secs: u64,
pub max_individual_entries: usize,
pub max_network_entries: usize,
}
impl Default for PowConfig {
fn default() -> Self {
Self {
max_counter: 10, decay_interval_secs: 3600, max_individual_entries: 50_000,
max_network_entries: 10_000,
}
}
}