node: Allow rate-limitting to be configurable

This commit is contained in:
Alexis Sellier 2023-09-16 21:24:29 +02:00 committed by cloudhead
parent af724eeb0d
commit a7cd7b25f5
No known key found for this signature in database
3 changed files with 48 additions and 12 deletions

View File

@ -738,7 +738,10 @@ where
} }
let host: HostName = addr.into(); let host: HostName = addr.into();
if self.limiter.limit(host.clone(), &Link::Inbound, self.clock) { if self
.limiter
.limit(host.clone(), &self.config.limits.rate.inbound, self.clock)
{
trace!(target: "service", "Rate limitting inbound connection from {host}.."); trace!(target: "service", "Rate limitting inbound connection from {host}..");
return false; return false;
} }
@ -1132,9 +1135,13 @@ where
warn!(target: "service", "Session not found for {remote}"); warn!(target: "service", "Session not found for {remote}");
return Ok(()); return Ok(());
}; };
let limit = match peer.link {
Link::Outbound => &self.config.limits.rate.outbound,
Link::Inbound => &self.config.limits.rate.inbound,
};
if self if self
.limiter .limiter
.limit(peer.addr.clone().into(), &peer.link, self.clock) .limit(peer.addr.clone().into(), limit, self.clock)
{ {
trace!(target: "service", "Rate limiting message from {remote} ({})", peer.addr); trace!(target: "service", "Rate limiting message from {remote} ({})", peer.addr);
return Ok(()); return Ok(());

View File

@ -1,7 +1,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use localtime::LocalTime; use localtime::LocalTime;
use radicle::node::HostName; use radicle::node::{config, HostName};
/// Peer rate limitter. /// Peer rate limitter.
/// ///
@ -38,19 +38,13 @@ pub trait AsTokens {
fn rate(&self) -> f64; fn rate(&self) -> f64;
} }
impl AsTokens for crate::Link { impl AsTokens for config::RateLimit {
fn rate(&self) -> f64 { fn rate(&self) -> f64 {
match self { self.fill_rate
Self::Inbound => 0.1,
Self::Outbound => 1.0,
}
} }
fn capacity(&self) -> usize { fn capacity(&self) -> usize {
match self { self.capacity
Self::Inbound => 16,
Self::Outbound => 64,
}
} }
} }

View File

@ -57,6 +57,9 @@ pub struct Limits {
pub routing_max_age: LocalDuration, pub routing_max_age: LocalDuration,
/// Maximum number of concurrent fetches per per connection. /// Maximum number of concurrent fetches per per connection.
pub fetch_concurrency: usize, pub fetch_concurrency: usize,
/// Rate limitter settings.
#[serde(default)]
pub rate: RateLimits,
} }
impl Default for Limits { impl Default for Limits {
@ -65,6 +68,38 @@ impl Default for Limits {
routing_max_size: 1000, routing_max_size: 1000,
routing_max_age: LocalDuration::from_mins(7 * 24 * 60), routing_max_age: LocalDuration::from_mins(7 * 24 * 60),
fetch_concurrency: 1, fetch_concurrency: 1,
rate: RateLimits::default(),
}
}
}
/// Rate limts for a single connection.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RateLimit {
pub fill_rate: f64,
pub capacity: usize,
}
/// Rate limits for inbound and outbound connections.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RateLimits {
pub inbound: RateLimit,
pub outbound: RateLimit,
}
impl Default for RateLimits {
fn default() -> Self {
Self {
inbound: RateLimit {
fill_rate: 0.1,
capacity: 16,
},
outbound: RateLimit {
fill_rate: 1.0,
capacity: 64,
},
} }
} }
} }