clawft_kernel/licence/links.rs
1//! What the licence exchange needs from a mesh (ADR-106 phase 3, service
2//! mode): a way to receive the three control topics, the peers to sync with,
3//! which of them may be sent floods, a send, and peer-join events.
4//!
5//! Two implementations:
6//!
7//! - [`MeshRuntime`], the kernel's own mesh (collapsed mode): the control
8//! topics arrive as runtime control sinks, and the licensed predicate is the
9//! admitted class of the route.
10//! - [`super::ServiceLicenceLinks`], the machine mesh service (service mode):
11//! the control topics arrive as service-stamped deliveries, sends go out
12//! through the service link, and the peer view is the service's.
13//!
14//! An exchange is started over exactly one of them, so a node never takes the
15//! same record from two paths.
16
17use std::sync::Arc;
18
19use async_trait::async_trait;
20
21use crate::error::KernelResult;
22use crate::ipc::KernelMessage;
23use crate::mesh_discovery::MeshPeerEvent;
24use crate::mesh_runtime::{MeshRuntime, PeerControlSink};
25
26/// The mesh a [`super::LicenceExchange`] floods and syncs over.
27#[async_trait]
28pub trait LicenceLinks: Send + Sync + 'static {
29 /// Receive `topic` with `sink` (first registration wins).
30 fn set_control_sink(&self, topic: &str, sink: Arc<dyn PeerControlSink>);
31
32 /// Peers to ask for a catch-up sync (the answering side checks admission).
33 fn peer_ids(&self) -> Vec<String>;
34
35 /// True when `peer` may be sent bindings and grants: verified by
36 /// admission and of class `node`.
37 fn peer_licensed(&self, peer: &str) -> bool;
38
39 /// Send `msg` to `peer`.
40 async fn route_to_remote(&self, peer: &str, msg: KernelMessage) -> KernelResult<()>;
41
42 /// Peer-join events, for the sync on connect (`None`: this mesh has none
43 /// and only the periodic sync runs).
44 fn subscribe_peer_events(&self) -> Option<tokio::sync::broadcast::Receiver<MeshPeerEvent>>;
45}
46
47#[async_trait]
48impl LicenceLinks for MeshRuntime {
49 fn set_control_sink(&self, topic: &str, sink: Arc<dyn PeerControlSink>) {
50 MeshRuntime::set_control_sink(self, topic, sink);
51 }
52
53 fn peer_ids(&self) -> Vec<String> {
54 MeshRuntime::peer_ids(self)
55 }
56
57 fn peer_licensed(&self, peer: &str) -> bool {
58 MeshRuntime::peer_licensed(self, peer)
59 }
60
61 async fn route_to_remote(&self, peer: &str, msg: KernelMessage) -> KernelResult<()> {
62 MeshRuntime::route_to_remote(self, peer, msg).await
63 }
64
65 fn subscribe_peer_events(&self) -> Option<tokio::sync::broadcast::Receiver<MeshPeerEvent>> {
66 Some(MeshRuntime::subscribe_peer_events(self))
67 }
68}