Skip to main content

cloudillo_core/rate_limit/
config.rs

1//! Rate Limiting Configuration
2//!
3//! Configuration structs for hierarchical rate limiting with dual-tier
4//! (short-term burst + long-term sustained) limits.
5
6use std::num::NonZeroU32;
7use std::time::Duration;
8
9/// Dual-tier rate limit configuration for a single address level
10#[derive(Clone, Debug)]
11pub struct RateLimitTierConfig {
12	// Short-term: burst protection (per-second)
13	/// Requests per second
14	pub short_term_rps: NonZeroU32,
15	/// Burst capacity for short-term
16	pub short_term_burst: NonZeroU32,
17
18	// Long-term: sustained abuse protection (per-hour)
19	/// Requests per hour
20	pub long_term_rph: NonZeroU32,
21	/// Burst capacity for long-term
22	pub long_term_burst: NonZeroU32,
23}
24
25impl RateLimitTierConfig {
26	pub fn new(short_rps: u32, short_burst: u32, long_rph: u32, long_burst: u32) -> Self {
27		Self {
28			short_term_rps: NonZeroU32::new(short_rps).unwrap_or(NonZeroU32::MIN),
29			short_term_burst: NonZeroU32::new(short_burst).unwrap_or(NonZeroU32::MIN),
30			long_term_rph: NonZeroU32::new(long_rph).unwrap_or(NonZeroU32::MIN),
31			long_term_burst: NonZeroU32::new(long_burst).unwrap_or(NonZeroU32::MIN),
32		}
33	}
34}
35
36/// Configuration for an endpoint category with all address levels
37#[derive(Clone, Debug)]
38pub struct EndpointCategoryConfig {
39	/// Category name (e.g., "auth", "federation", "general")
40	pub name: &'static str,
41	/// IPv4 individual (/32) limits
42	pub ipv4_individual: RateLimitTierConfig,
43	/// IPv4 network (/24) limits
44	pub ipv4_network: RateLimitTierConfig,
45	/// IPv6 subnet (/64) limits
46	pub ipv6_subnet: RateLimitTierConfig,
47	/// IPv6 provider (/48) limits
48	pub ipv6_provider: RateLimitTierConfig,
49}
50
51/// Main rate limit configuration
52#[derive(Clone, Debug)]
53pub struct RateLimitConfig {
54	/// Auth endpoints (login, register, password reset)
55	pub auth: EndpointCategoryConfig,
56	/// Federation endpoints (inbox)
57	pub federation: EndpointCategoryConfig,
58	/// General public endpoints (profile, refs)
59	pub general: EndpointCategoryConfig,
60	/// WebSocket endpoints
61	pub websocket: EndpointCategoryConfig,
62	/// Maximum number of IPs to track (memory limit)
63	pub max_tracked_ips: usize,
64	/// How long to retain entries after last access
65	pub entry_ttl: Duration,
66}
67
68impl Default for RateLimitConfig {
69	fn default() -> Self {
70		Self {
71			auth: EndpointCategoryConfig {
72				name: "auth",
73				// Auth: strict limits to prevent credential stuffing
74				ipv4_individual: RateLimitTierConfig::new(20, 50, 100, 200),
75				ipv4_network: RateLimitTierConfig::new(50, 100, 300, 500),
76				ipv6_subnet: RateLimitTierConfig::new(20, 50, 100, 200),
77				ipv6_provider: RateLimitTierConfig::new(50, 100, 300, 500),
78			},
79			federation: EndpointCategoryConfig {
80				name: "federation",
81				// Federation: moderate limits for inter-instance communication
82				ipv4_individual: RateLimitTierConfig::new(100, 200, 1000, 100),
83				ipv4_network: RateLimitTierConfig::new(500, 750, 5000, 500),
84				ipv6_subnet: RateLimitTierConfig::new(100, 200, 1000, 100),
85				ipv6_provider: RateLimitTierConfig::new(500, 750, 5000, 500),
86			},
87			general: EndpointCategoryConfig {
88				name: "general",
89				// General: relaxed limits for normal browsing
90				ipv4_individual: RateLimitTierConfig::new(300, 500, 5000, 500),
91				ipv4_network: RateLimitTierConfig::new(600, 1000, 50000, 5000),
92				ipv6_subnet: RateLimitTierConfig::new(300, 500, 5000, 500),
93				ipv6_provider: RateLimitTierConfig::new(600, 1000, 50000, 5000),
94			},
95			websocket: EndpointCategoryConfig {
96				name: "websocket",
97				// WebSocket: relaxed limits for collaborative scenarios (connections are long-lived)
98				ipv4_individual: RateLimitTierConfig::new(100, 200, 1000, 500),
99				ipv4_network: RateLimitTierConfig::new(100, 200, 1000, 500),
100				ipv6_subnet: RateLimitTierConfig::new(100, 200, 1000, 500),
101				ipv6_provider: RateLimitTierConfig::new(100, 200, 1000, 500),
102			},
103			max_tracked_ips: 100_000,
104			entry_ttl: Duration::from_secs(3600), // 1 hour
105		}
106	}
107}
108
109/// Proof-of-Work counter configuration
110#[derive(Clone, Debug)]
111pub struct PowConfig {
112	/// Maximum counter value (caps PoW difficulty)
113	pub max_counter: u32,
114	/// Counter decay: decrease by 1 every N seconds of no violations
115	pub decay_interval_secs: u64,
116	/// LRU cache size for individual IPs
117	pub max_individual_entries: usize,
118	/// LRU cache size for networks
119	pub max_network_entries: usize,
120}
121
122impl Default for PowConfig {
123	fn default() -> Self {
124		Self {
125			max_counter: 10,           // Max "AAAAAAAAAA" required
126			decay_interval_secs: 3600, // 1 hour decay
127			max_individual_entries: 50_000,
128			max_network_entries: 10_000,
129		}
130	}
131}
132
133// vim: ts=4