Skip to main content

rns_net/
event.rs

1//! Event types for the driver loop.
2
3use std::fmt;
4use std::sync::mpsc;
5
6use rns_core::transport::types::{InterfaceId, InterfaceInfo};
7
8use crate::interface::Writer;
9
10/// Events sent to the driver thread.
11pub enum Event {
12    /// A decoded frame arrived from an interface.
13    Frame { interface_id: InterfaceId, data: Vec<u8> },
14    /// An interface came online after (re)connecting.
15    /// Carries a new writer if the connection was re-established.
16    /// Carries InterfaceInfo if this is a new dynamic interface (e.g. TCP server client).
17    InterfaceUp(InterfaceId, Option<Box<dyn Writer>>, Option<InterfaceInfo>),
18    /// An interface went offline (socket closed, error).
19    InterfaceDown(InterfaceId),
20    /// Periodic maintenance tick (1s interval).
21    Tick,
22    /// Shut down the driver loop.
23    Shutdown,
24    /// Send an outbound packet.
25    SendOutbound {
26        raw: Vec<u8>,
27        dest_type: u8,
28        attached_interface: Option<InterfaceId>,
29    },
30    /// Register a local destination.
31    RegisterDestination {
32        dest_hash: [u8; 16],
33        dest_type: u8,
34    },
35    /// Deregister a local destination.
36    DeregisterDestination {
37        dest_hash: [u8; 16],
38    },
39    /// Query driver state. Response is sent via the provided channel.
40    Query(QueryRequest, mpsc::Sender<QueryResponse>),
41    /// Register a link destination (accepts incoming LINKREQUEST).
42    RegisterLinkDestination {
43        dest_hash: [u8; 16],
44        sig_prv_bytes: [u8; 32],
45        sig_pub_bytes: [u8; 32],
46    },
47    /// Register a request handler for a path on established links.
48    RegisterRequestHandler {
49        path: String,
50        allowed_list: Option<Vec<[u8; 16]>>,
51        handler: Box<dyn Fn([u8; 16], &str, &[u8], Option<&([u8; 16], [u8; 64])>) -> Option<Vec<u8>> + Send>,
52    },
53    /// Create an outbound link. Response sends (link_id) back.
54    CreateLink {
55        dest_hash: [u8; 16],
56        dest_sig_pub_bytes: [u8; 32],
57        response_tx: mpsc::Sender<[u8; 16]>,
58    },
59    /// Send a request on an established link.
60    SendRequest {
61        link_id: [u8; 16],
62        path: String,
63        data: Vec<u8>,
64    },
65    /// Identify on a link (send identity to remote peer).
66    IdentifyOnLink {
67        link_id: [u8; 16],
68        identity_prv_key: [u8; 64],
69    },
70    /// Tear down a link.
71    TeardownLink {
72        link_id: [u8; 16],
73    },
74    /// Send a resource on a link.
75    SendResource {
76        link_id: [u8; 16],
77        data: Vec<u8>,
78        metadata: Option<Vec<u8>>,
79    },
80    /// Set the resource acceptance strategy for a link.
81    SetResourceStrategy {
82        link_id: [u8; 16],
83        strategy: u8,
84    },
85    /// Accept or reject a pending resource (for AcceptApp strategy).
86    AcceptResource {
87        link_id: [u8; 16],
88        resource_hash: Vec<u8>,
89        accept: bool,
90    },
91    /// Send a channel message on a link.
92    SendChannelMessage {
93        link_id: [u8; 16],
94        msgtype: u16,
95        payload: Vec<u8>,
96    },
97    /// Send generic data on a link with a given context.
98    SendOnLink {
99        link_id: [u8; 16],
100        data: Vec<u8>,
101        context: u8,
102    },
103    /// Request a path to a destination from the network.
104    RequestPath {
105        dest_hash: [u8; 16],
106    },
107    /// Register a proof strategy for a destination.
108    RegisterProofStrategy {
109        dest_hash: [u8; 16],
110        strategy: rns_core::types::ProofStrategy,
111        /// Full identity private key (64 bytes) for signing proofs.
112        signing_key: Option<[u8; 64]>,
113    },
114}
115
116/// Queries that can be sent to the driver.
117#[derive(Debug)]
118pub enum QueryRequest {
119    /// Get interface statistics and transport info.
120    InterfaceStats,
121    /// Get path table entries, optionally filtered by max hops.
122    PathTable { max_hops: Option<u8> },
123    /// Get rate table entries.
124    RateTable,
125    /// Look up the next hop for a destination.
126    NextHop { dest_hash: [u8; 16] },
127    /// Look up the next hop interface name for a destination.
128    NextHopIfName { dest_hash: [u8; 16] },
129    /// Get link table entry count.
130    LinkCount,
131    /// Drop a specific path.
132    DropPath { dest_hash: [u8; 16] },
133    /// Drop all paths that route via a given transport hash.
134    DropAllVia { transport_hash: [u8; 16] },
135    /// Drop all announce queues.
136    DropAnnounceQueues,
137    /// Get the transport identity hash.
138    TransportIdentity,
139    /// Get all blackholed identities.
140    GetBlackholed,
141    /// Add an identity to the blackhole list.
142    BlackholeIdentity {
143        identity_hash: [u8; 16],
144        duration_hours: Option<f64>,
145        reason: Option<String>,
146    },
147    /// Remove an identity from the blackhole list.
148    UnblackholeIdentity {
149        identity_hash: [u8; 16],
150    },
151    /// Check if a path exists to a destination.
152    HasPath { dest_hash: [u8; 16] },
153    /// Get hop count to a destination.
154    HopsTo { dest_hash: [u8; 16] },
155    /// Recall identity info for a destination.
156    RecallIdentity { dest_hash: [u8; 16] },
157    /// Get locally registered destinations.
158    LocalDestinations,
159    /// Get active links.
160    Links,
161    /// Get active resource transfers.
162    Resources,
163}
164
165/// Responses to queries.
166#[derive(Debug)]
167pub enum QueryResponse {
168    InterfaceStats(InterfaceStatsResponse),
169    PathTable(Vec<PathTableEntry>),
170    RateTable(Vec<RateTableEntry>),
171    NextHop(Option<NextHopResponse>),
172    NextHopIfName(Option<String>),
173    LinkCount(usize),
174    DropPath(bool),
175    DropAllVia(usize),
176    DropAnnounceQueues,
177    TransportIdentity(Option<[u8; 16]>),
178    Blackholed(Vec<BlackholeInfo>),
179    BlackholeResult(bool),
180    UnblackholeResult(bool),
181    HasPath(bool),
182    HopsTo(Option<u8>),
183    RecallIdentity(Option<crate::destination::AnnouncedIdentity>),
184    LocalDestinations(Vec<LocalDestinationEntry>),
185    Links(Vec<LinkInfoEntry>),
186    Resources(Vec<ResourceInfoEntry>),
187}
188
189/// Interface statistics response.
190#[derive(Debug, Clone)]
191pub struct InterfaceStatsResponse {
192    pub interfaces: Vec<SingleInterfaceStat>,
193    pub transport_id: Option<[u8; 16]>,
194    pub transport_enabled: bool,
195    pub transport_uptime: f64,
196    /// Total received bytes across all interfaces.
197    pub total_rxb: u64,
198    /// Total transmitted bytes across all interfaces.
199    pub total_txb: u64,
200}
201
202/// Statistics for a single interface.
203#[derive(Debug, Clone)]
204pub struct SingleInterfaceStat {
205    pub name: String,
206    pub status: bool,
207    pub mode: u8,
208    pub rxb: u64,
209    pub txb: u64,
210    pub rx_packets: u64,
211    pub tx_packets: u64,
212    pub bitrate: Option<u64>,
213    pub ifac_size: Option<usize>,
214    pub started: f64,
215    /// Incoming announce frequency (per second).
216    pub ia_freq: f64,
217    /// Outgoing announce frequency (per second).
218    pub oa_freq: f64,
219    /// Human-readable interface type string (e.g. "TCPClientInterface").
220    pub interface_type: String,
221}
222
223/// A locally registered destination.
224#[derive(Debug, Clone)]
225pub struct LocalDestinationEntry {
226    pub hash: [u8; 16],
227    pub dest_type: u8,
228}
229
230/// Information about an active link.
231#[derive(Debug, Clone)]
232pub struct LinkInfoEntry {
233    pub link_id: [u8; 16],
234    pub state: String,
235    pub is_initiator: bool,
236    pub dest_hash: [u8; 16],
237    pub remote_identity: Option<[u8; 16]>,
238    pub rtt: Option<f64>,
239}
240
241/// Information about an active resource transfer.
242#[derive(Debug, Clone)]
243pub struct ResourceInfoEntry {
244    pub link_id: [u8; 16],
245    pub direction: String,
246    pub total_parts: usize,
247    pub transferred_parts: usize,
248    pub complete: bool,
249}
250
251/// A single path table entry for query responses.
252#[derive(Debug, Clone)]
253pub struct PathTableEntry {
254    pub hash: [u8; 16],
255    pub timestamp: f64,
256    pub via: [u8; 16],
257    pub hops: u8,
258    pub expires: f64,
259    pub interface: InterfaceId,
260    pub interface_name: String,
261}
262
263/// A single rate table entry for query responses.
264#[derive(Debug, Clone)]
265pub struct RateTableEntry {
266    pub hash: [u8; 16],
267    pub last: f64,
268    pub rate_violations: u32,
269    pub blocked_until: f64,
270    pub timestamps: Vec<f64>,
271}
272
273/// A blackholed identity for query responses.
274#[derive(Debug, Clone)]
275pub struct BlackholeInfo {
276    pub identity_hash: [u8; 16],
277    pub created: f64,
278    pub expires: f64,
279    pub reason: Option<String>,
280}
281
282/// Next hop lookup result.
283#[derive(Debug, Clone)]
284pub struct NextHopResponse {
285    pub next_hop: [u8; 16],
286    pub hops: u8,
287    pub interface: InterfaceId,
288}
289
290impl fmt::Debug for Event {
291    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
292        match self {
293            Event::Frame { interface_id, data } => {
294                f.debug_struct("Frame")
295                    .field("interface_id", interface_id)
296                    .field("data_len", &data.len())
297                    .finish()
298            }
299            Event::InterfaceUp(id, writer, info) => {
300                f.debug_tuple("InterfaceUp")
301                    .field(id)
302                    .field(&writer.is_some())
303                    .field(&info.is_some())
304                    .finish()
305            }
306            Event::InterfaceDown(id) => f.debug_tuple("InterfaceDown").field(id).finish(),
307            Event::Tick => write!(f, "Tick"),
308            Event::Shutdown => write!(f, "Shutdown"),
309            Event::SendOutbound { raw, dest_type, .. } => {
310                f.debug_struct("SendOutbound")
311                    .field("raw_len", &raw.len())
312                    .field("dest_type", dest_type)
313                    .finish()
314            }
315            Event::RegisterDestination { dest_hash, dest_type } => {
316                f.debug_struct("RegisterDestination")
317                    .field("dest_hash", dest_hash)
318                    .field("dest_type", dest_type)
319                    .finish()
320            }
321            Event::DeregisterDestination { dest_hash } => {
322                f.debug_struct("DeregisterDestination")
323                    .field("dest_hash", dest_hash)
324                    .finish()
325            }
326            Event::Query(req, _) => {
327                f.debug_tuple("Query")
328                    .field(req)
329                    .finish()
330            }
331            Event::RegisterLinkDestination { dest_hash, .. } => {
332                f.debug_struct("RegisterLinkDestination")
333                    .field("dest_hash", dest_hash)
334                    .finish()
335            }
336            Event::RegisterRequestHandler { path, .. } => {
337                f.debug_struct("RegisterRequestHandler")
338                    .field("path", path)
339                    .finish()
340            }
341            Event::CreateLink { dest_hash, .. } => {
342                f.debug_struct("CreateLink")
343                    .field("dest_hash", dest_hash)
344                    .finish()
345            }
346            Event::SendRequest { link_id, path, .. } => {
347                f.debug_struct("SendRequest")
348                    .field("link_id", link_id)
349                    .field("path", path)
350                    .finish()
351            }
352            Event::IdentifyOnLink { link_id, .. } => {
353                f.debug_struct("IdentifyOnLink")
354                    .field("link_id", link_id)
355                    .finish()
356            }
357            Event::TeardownLink { link_id } => {
358                f.debug_struct("TeardownLink")
359                    .field("link_id", link_id)
360                    .finish()
361            }
362            Event::SendResource { link_id, data, .. } => {
363                f.debug_struct("SendResource")
364                    .field("link_id", link_id)
365                    .field("data_len", &data.len())
366                    .finish()
367            }
368            Event::SetResourceStrategy { link_id, strategy } => {
369                f.debug_struct("SetResourceStrategy")
370                    .field("link_id", link_id)
371                    .field("strategy", strategy)
372                    .finish()
373            }
374            Event::AcceptResource { link_id, accept, .. } => {
375                f.debug_struct("AcceptResource")
376                    .field("link_id", link_id)
377                    .field("accept", accept)
378                    .finish()
379            }
380            Event::SendChannelMessage { link_id, msgtype, payload } => {
381                f.debug_struct("SendChannelMessage")
382                    .field("link_id", link_id)
383                    .field("msgtype", msgtype)
384                    .field("payload_len", &payload.len())
385                    .finish()
386            }
387            Event::SendOnLink { link_id, data, context } => {
388                f.debug_struct("SendOnLink")
389                    .field("link_id", link_id)
390                    .field("data_len", &data.len())
391                    .field("context", context)
392                    .finish()
393            }
394            Event::RequestPath { dest_hash } => {
395                f.debug_struct("RequestPath")
396                    .field("dest_hash", dest_hash)
397                    .finish()
398            }
399            Event::RegisterProofStrategy { dest_hash, strategy, .. } => {
400                f.debug_struct("RegisterProofStrategy")
401                    .field("dest_hash", dest_hash)
402                    .field("strategy", strategy)
403                    .finish()
404            }
405        }
406    }
407}
408
409pub type EventSender = mpsc::Sender<Event>;
410pub type EventReceiver = mpsc::Receiver<Event>;
411
412pub fn channel() -> (EventSender, EventReceiver) {
413    mpsc::channel()
414}