node: Add connection limits
The limits are roughly modeled after the Bitcoin network.
This commit is contained in:
parent
5bdc2ad1fb
commit
786ce40f95
|
|
@ -43,6 +43,10 @@ $ rad config
|
||||||
"fillRate": 1.0,
|
"fillRate": 1.0,
|
||||||
"capacity": 64
|
"capacity": 64
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"connection": {
|
||||||
|
"inbound": 128,
|
||||||
|
"outbound": 16
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"policy": "block",
|
"policy": "block",
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,10 @@ mod routes {
|
||||||
"fillRate": 1.0,
|
"fillRate": 1.0,
|
||||||
"capacity": 64
|
"capacity": 64
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"connection": {
|
||||||
|
"inbound": 128,
|
||||||
|
"outbound": 16
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"policy": "block",
|
"policy": "block",
|
||||||
|
|
|
||||||
|
|
@ -1059,10 +1059,15 @@ where
|
||||||
|
|
||||||
/// Inbound connection attempt.
|
/// Inbound connection attempt.
|
||||||
pub fn accepted(&mut self, addr: Address) -> bool {
|
pub fn accepted(&mut self, addr: Address) -> bool {
|
||||||
// Always accept trusted connections.
|
// Always accept trusted connections, even if we already reached
|
||||||
|
// our inbound connection limit.
|
||||||
if addr.is_trusted() {
|
if addr.is_trusted() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// Check for inbound connection limit.
|
||||||
|
if self.sessions.inbound().count() >= self.config.limits.connection.inbound {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
let host: HostName = addr.into();
|
let host: HostName = addr.into();
|
||||||
|
|
||||||
if self
|
if self
|
||||||
|
|
@ -1912,6 +1917,10 @@ where
|
||||||
error!(target: "service", "Attempted connection to self");
|
error!(target: "service", "Attempted connection to self");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if self.sessions.outbound().count() >= self.config.limits.connection.outbound {
|
||||||
|
error!(target: "service", "Outbound connection limit reached when attempting {nid} ({addr})");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
let persistent = self.config.is_persistent(&nid);
|
let persistent = self.config.is_persistent(&nid);
|
||||||
let time = self.time();
|
let time = self.time();
|
||||||
|
|
||||||
|
|
@ -2345,6 +2354,16 @@ impl Sessions {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Iterator over connected inbound peers.
|
||||||
|
pub fn inbound(&self) -> impl Iterator<Item = (&NodeId, &Session)> + Clone {
|
||||||
|
self.connected().filter(|(_, s)| s.link.is_inbound())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Iterator over outbound peers.
|
||||||
|
pub fn outbound(&self) -> impl Iterator<Item = (&NodeId, &Session)> + Clone {
|
||||||
|
self.connected().filter(|(_, s)| s.link.is_outbound())
|
||||||
|
}
|
||||||
|
|
||||||
/// Iterator over mutable fully connected peers.
|
/// Iterator over mutable fully connected peers.
|
||||||
pub fn connected_mut(&mut self) -> impl Iterator<Item = (&NodeId, &mut Session)> {
|
pub fn connected_mut(&mut self) -> impl Iterator<Item = (&NodeId, &mut Session)> {
|
||||||
self.0.iter_mut().filter(move |(_, s)| s.is_connected())
|
self.0.iter_mut().filter(move |(_, s)| s.is_connected())
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,9 @@ pub struct Limits {
|
||||||
/// Rate limitter settings.
|
/// Rate limitter settings.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub rate: RateLimits,
|
pub rate: RateLimits,
|
||||||
|
/// Connection limits.
|
||||||
|
#[serde(default)]
|
||||||
|
pub connection: ConnectionLimits,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Limits {
|
impl Default for Limits {
|
||||||
|
|
@ -104,6 +107,27 @@ impl Default for Limits {
|
||||||
fetch_concurrency: 1,
|
fetch_concurrency: 1,
|
||||||
max_open_files: 4096,
|
max_open_files: 4096,
|
||||||
rate: RateLimits::default(),
|
rate: RateLimits::default(),
|
||||||
|
connection: ConnectionLimits::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Connection limits.
|
||||||
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ConnectionLimits {
|
||||||
|
/// Max inbound connections.
|
||||||
|
pub inbound: usize,
|
||||||
|
/// Max outbound connections. Note that this is higher than the *target* number
|
||||||
|
/// in [`TARGET_OUTBOUND_PEERS`].
|
||||||
|
pub outbound: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ConnectionLimits {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
inbound: 128,
|
||||||
|
outbound: 16,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue