Skip to main content

karyon_p2p/
access_control.rs

1use karyon_net::Endpoint;
2
3use crate::{peer::ConnDirection, protocol::ProtocolID, PeerID};
4
5/// A peer that has completed the handshake but has not joined the pool yet.
6pub struct PeerCandidate<'a> {
7    pub peer_id: &'a PeerID,
8    pub remote_endpoint: &'a Endpoint,
9    /// Protocols supported by both sides.
10    pub negotiated_protocols: &'a [ProtocolID],
11}
12
13/// The party being evaluated.
14pub enum Subject<'a> {
15    /// Before the handshake. Only the transport address is known.
16    Endpoint(&'a Endpoint),
17    /// After the handshake. The peer identity is known.
18    Peer(&'a PeerCandidate<'a>),
19}
20
21/// The purpose of the connection.
22#[derive(Clone, Debug)]
23pub enum Action {
24    /// A peer connection.
25    Connect(ConnDirection),
26    /// A discovery lookup query.
27    Lookup(ConnDirection),
28    /// A liveness check. No data is exchanged.
29    Probe(ConnDirection),
30}
31
32/// Policy that decides which peers this node talks to, and for what.
33///
34/// Synchronous by design: it runs on the accept loop, so a blocking
35/// policy would stall every other inbound connection. Keep its state
36/// in memory.
37pub trait AccessControl: Send + Sync {
38    /// Returns false to drop the connection.
39    ///
40    /// A `Subject::Endpoint` is evaluated before the handshake, when
41    /// only the address is known. A `Subject::Peer` is evaluated after
42    /// the handshake, when the identity is available.
43    fn allow(&self, subject: &Subject, action: Action) -> bool;
44}
45
46/// Default policy. Allows everything.
47pub struct AllowAll;
48
49impl AccessControl for AllowAll {
50    fn allow(&self, _subject: &Subject, _action: Action) -> bool {
51        true
52    }
53}