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}