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();
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}..");
return false;
}
@ -1132,9 +1135,13 @@ where
warn!(target: "service", "Session not found for {remote}");
return Ok(());
};
let limit = match peer.link {
Link::Outbound => &self.config.limits.rate.outbound,
Link::Inbound => &self.config.limits.rate.inbound,
};
if self
.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);
return Ok(());

View File

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

View File

@ -57,6 +57,9 @@ pub struct Limits {
pub routing_max_age: LocalDuration,
/// Maximum number of concurrent fetches per per connection.
pub fetch_concurrency: usize,
/// Rate limitter settings.
#[serde(default)]
pub rate: RateLimits,
}
impl Default for Limits {
@ -65,6 +68,38 @@ impl Default for Limits {
routing_max_size: 1000,
routing_max_age: LocalDuration::from_mins(7 * 24 * 60),
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,
},
}
}
}