iroh_dns_server/http/
rate_limiting.rs1use std::{sync::Arc, time::Duration};
2
3use governor::{clock::QuantaInstant, middleware::NoOpMiddleware};
4use serde::{Deserialize, Serialize};
5use tower_governor::{
6 GovernorLayer,
7 governor::GovernorConfigBuilder,
8 key_extractor::{PeerIpKeyExtractor, SmartIpKeyExtractor},
9};
10
11#[derive(Debug, Deserialize, Default, Serialize, Clone)]
13#[serde(rename_all = "lowercase")]
14#[non_exhaustive]
15pub enum RateLimitConfig {
16 Disabled,
18 #[default]
24 Simple,
25 Smart,
33}
34
35impl Default for &RateLimitConfig {
36 fn default() -> Self {
37 &RateLimitConfig::Simple
38 }
39}
40
41pub(super) fn create<RespBody>(
45 rate_limit_config: &RateLimitConfig,
46) -> Option<GovernorLayer<PeerIpKeyExtractor, NoOpMiddleware<QuantaInstant>, RespBody>> {
47 let use_smart_extractor = match rate_limit_config {
48 RateLimitConfig::Disabled => {
49 tracing::info!("Rate limiting disabled");
50 return None;
51 }
52 RateLimitConfig::Simple => false,
53 RateLimitConfig::Smart => true,
54 };
55
56 tracing::info!("Rate limiting enabled ({rate_limit_config:?})");
57
58 let mut governor_conf_builder = GovernorConfigBuilder::default();
62 governor_conf_builder.per_second(4);
64 governor_conf_builder.burst_size(2);
65
66 if use_smart_extractor {
67 governor_conf_builder.key_extractor(SmartIpKeyExtractor);
68 }
69
70 let governor_conf = governor_conf_builder
71 .finish()
72 .expect("failed to build rate-limiting governor");
73
74 let governor_conf = Arc::new(governor_conf);
75
76 let gc_interval = Duration::from_secs(60);
78 let governor_limiter = governor_conf.limiter().clone();
79 std::thread::spawn(move || {
80 loop {
81 std::thread::sleep(gc_interval);
82 tracing::debug!("rate limiting storage size: {}", governor_limiter.len());
83 governor_limiter.retain_recent();
84 }
85 });
86
87 Some(GovernorLayer::new(governor_conf))
88}