protocol/service: Use block list for connections
The service learns to consult the policies database to check if a `NodeId` is blocked. When a node is blocked the service will prevent any inbound or outbound connection. In the case of an inbound connection, a disconnect must be submitted to the reactor. In the case of an outbound connection, nodes are filtered out from any connection lists, and prevented from submitting a connect to the reactor.
This commit is contained in:
parent
94e0a5128d
commit
1fa14ef529
|
|
@ -11,6 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## New Features
|
## New Features
|
||||||
|
|
||||||
|
- The block policy for `NodeId`'s is used for limiting the namespaces fetched
|
||||||
|
from other nodes. It is now also extended to block connections to the blocked
|
||||||
|
`NodeId`.
|
||||||
- The set of references returned by `references_of` were restricted to `heads`,
|
- The set of references returned by `references_of` were restricted to `heads`,
|
||||||
`tags`, `notes`, `rad`, and `cobs`. The restriction is lifted, and the only
|
`tags`, `notes`, `rad`, and `cobs`. The restriction is lifted, and the only
|
||||||
references filtered out are `refs/tmp/heads` – used by `radicle-remote-helper`
|
references filtered out are `refs/tmp/heads` – used by `radicle-remote-helper`
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,8 @@ pub enum ConnectError {
|
||||||
"attempted connection to {nid}, via {addr} but addresses of this kind are not supported"
|
"attempted connection to {nid}, via {addr} but addresses of this kind are not supported"
|
||||||
)]
|
)]
|
||||||
UnsupportedAddress { nid: NodeId, addr: Address },
|
UnsupportedAddress { nid: NodeId, addr: Address },
|
||||||
|
#[error("attempted connection with blocked peer {nid}")]
|
||||||
|
Blocked { nid: NodeId },
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A store for all node data.
|
/// A store for all node data.
|
||||||
|
|
@ -1219,6 +1221,16 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn connected(&mut self, remote: NodeId, addr: Address, link: Link) {
|
pub fn connected(&mut self, remote: NodeId, addr: Address, link: Link) {
|
||||||
|
if let Ok(true) = self.policies.is_blocked(&remote) {
|
||||||
|
self.emitter.emit(Event::PeerDisconnected {
|
||||||
|
nid: remote,
|
||||||
|
reason: format!("{remote} is blocked"),
|
||||||
|
});
|
||||||
|
info!(target: "service", "Disconnecting blocked inbound peer {remote}");
|
||||||
|
self.outbox.disconnect(remote, DisconnectReason::Policy);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
info!(target: "service", "Connected to {remote} ({addr}) ({link:?})");
|
info!(target: "service", "Connected to {remote} ({addr}) ({link:?})");
|
||||||
self.emitter.emit(Event::PeerConnected { nid: remote });
|
self.emitter.emit(Event::PeerConnected { nid: remote });
|
||||||
|
|
||||||
|
|
@ -2164,6 +2176,9 @@ where
|
||||||
if nid == self.node_id() {
|
if nid == self.node_id() {
|
||||||
return Err(ConnectError::SelfConnection);
|
return Err(ConnectError::SelfConnection);
|
||||||
}
|
}
|
||||||
|
if let Ok(true) = self.policies.is_blocked(&nid) {
|
||||||
|
return Err(ConnectError::Blocked { nid });
|
||||||
|
}
|
||||||
if !self.is_supported_address(&addr) {
|
if !self.is_supported_address(&addr) {
|
||||||
return Err(ConnectError::UnsupportedAddress { nid, addr });
|
return Err(ConnectError::UnsupportedAddress { nid, addr });
|
||||||
}
|
}
|
||||||
|
|
@ -2397,6 +2412,7 @@ where
|
||||||
.filter(|entry| !entry.address.banned)
|
.filter(|entry| !entry.address.banned)
|
||||||
.filter(|entry| !entry.penalty.is_connect_threshold_reached())
|
.filter(|entry| !entry.penalty.is_connect_threshold_reached())
|
||||||
.filter(|entry| !self.sessions.contains_key(&entry.node))
|
.filter(|entry| !self.sessions.contains_key(&entry.node))
|
||||||
|
.filter(|entry| !self.policies.is_blocked(&entry.node).unwrap_or(false))
|
||||||
.filter(|entry| !self.config.external_addresses.contains(&entry.address.addr))
|
.filter(|entry| !self.config.external_addresses.contains(&entry.address.addr))
|
||||||
.filter(|entry| &entry.node != self.nid())
|
.filter(|entry| &entry.node != self.nid())
|
||||||
.filter(|entry| self.is_supported_address(&entry.address.addr))
|
.filter(|entry| self.is_supported_address(&entry.address.addr))
|
||||||
|
|
@ -2564,6 +2580,9 @@ where
|
||||||
|
|
||||||
for (nid, session) in self.sessions.iter_mut() {
|
for (nid, session) in self.sessions.iter_mut() {
|
||||||
if self.config.is_persistent(nid) {
|
if self.config.is_persistent(nid) {
|
||||||
|
if self.policies.is_blocked(nid).unwrap_or(false) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if let session::State::Disconnected { retry_at, .. } = &mut session.state {
|
if let session::State::Disconnected { retry_at, .. } = &mut session.state {
|
||||||
// TODO: Try to reconnect only if the peer was attempted. A disconnect without
|
// TODO: Try to reconnect only if the peer was attempted. A disconnect without
|
||||||
// even a successful attempt means that we're unlikely to be able to reconnect.
|
// even a successful attempt means that we're unlikely to be able to reconnect.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue