Radish alpha
h
rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5
Radicle Heartwood Protocol & Stack
Radicle
Git
protocol/service: Use block list for connections
Adrian Duke committed 2 months ago
commit 1fa14ef529f20e08c29af12d0b11f26a7ca3a5fe
parent 94e0a51
2 files changed +22 -0
modified CHANGELOG.md
@@ -11,6 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## 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`,
  `tags`, `notes`, `rad`, and `cobs`. The restriction is lifted, and the only
  references filtered out are `refs/tmp/heads` – used by `radicle-remote-helper`
modified crates/radicle-protocol/src/service.rs
@@ -230,6 +230,8 @@ pub enum ConnectError {
        "attempted connection to {nid}, via {addr} but addresses of this kind are not supported"
    )]
    UnsupportedAddress { nid: NodeId, addr: Address },
+
    #[error("attempted connection with blocked peer {nid}")]
+
    Blocked { nid: NodeId },
}

/// A store for all node data.
@@ -1219,6 +1221,16 @@ where
    }

    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:?})");
        self.emitter.emit(Event::PeerConnected { nid: remote });

@@ -2164,6 +2176,9 @@ where
        if nid == self.node_id() {
            return Err(ConnectError::SelfConnection);
        }
+
        if let Ok(true) = self.policies.is_blocked(&nid) {
+
            return Err(ConnectError::Blocked { nid });
+
        }
        if !self.is_supported_address(&addr) {
            return Err(ConnectError::UnsupportedAddress { nid, addr });
        }
@@ -2397,6 +2412,7 @@ where
                    .filter(|entry| !entry.address.banned)
                    .filter(|entry| !entry.penalty.is_connect_threshold_reached())
                    .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| &entry.node != self.nid())
                    .filter(|entry| self.is_supported_address(&entry.address.addr))
@@ -2564,6 +2580,9 @@ where

        for (nid, session) in self.sessions.iter_mut() {
            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 {
                    // 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.