1use std::fmt;
4use std::sync::mpsc;
5
6use rns_core::transport::types::{InterfaceId, InterfaceInfo};
7
8use crate::interface::Writer;
9
10pub enum Event {
12 Frame { interface_id: InterfaceId, data: Vec<u8> },
14 InterfaceUp(InterfaceId, Option<Box<dyn Writer>>, Option<InterfaceInfo>),
18 InterfaceDown(InterfaceId),
20 Tick,
22 Shutdown,
24 SendOutbound {
26 raw: Vec<u8>,
27 dest_type: u8,
28 attached_interface: Option<InterfaceId>,
29 },
30 RegisterDestination {
32 dest_hash: [u8; 16],
33 dest_type: u8,
34 },
35 DeregisterDestination {
37 dest_hash: [u8; 16],
38 },
39 DeregisterLinkDestination {
41 dest_hash: [u8; 16],
42 },
43 Query(QueryRequest, mpsc::Sender<QueryResponse>),
45 RegisterLinkDestination {
47 dest_hash: [u8; 16],
48 sig_prv_bytes: [u8; 32],
49 sig_pub_bytes: [u8; 32],
50 },
51 RegisterRequestHandler {
53 path: String,
54 allowed_list: Option<Vec<[u8; 16]>>,
55 handler: Box<dyn Fn([u8; 16], &str, &[u8], Option<&([u8; 16], [u8; 64])>) -> Option<Vec<u8>> + Send>,
56 },
57 CreateLink {
59 dest_hash: [u8; 16],
60 dest_sig_pub_bytes: [u8; 32],
61 response_tx: mpsc::Sender<[u8; 16]>,
62 },
63 SendRequest {
65 link_id: [u8; 16],
66 path: String,
67 data: Vec<u8>,
68 },
69 IdentifyOnLink {
71 link_id: [u8; 16],
72 identity_prv_key: [u8; 64],
73 },
74 TeardownLink {
76 link_id: [u8; 16],
77 },
78 SendResource {
80 link_id: [u8; 16],
81 data: Vec<u8>,
82 metadata: Option<Vec<u8>>,
83 },
84 SetResourceStrategy {
86 link_id: [u8; 16],
87 strategy: u8,
88 },
89 AcceptResource {
91 link_id: [u8; 16],
92 resource_hash: Vec<u8>,
93 accept: bool,
94 },
95 SendChannelMessage {
97 link_id: [u8; 16],
98 msgtype: u16,
99 payload: Vec<u8>,
100 },
101 SendOnLink {
103 link_id: [u8; 16],
104 data: Vec<u8>,
105 context: u8,
106 },
107 RequestPath {
109 dest_hash: [u8; 16],
110 },
111 RegisterProofStrategy {
113 dest_hash: [u8; 16],
114 strategy: rns_core::types::ProofStrategy,
115 signing_key: Option<[u8; 64]>,
117 },
118 ProposeDirectConnect {
120 link_id: [u8; 16],
121 },
122 SetDirectConnectPolicy {
124 policy: crate::holepunch::orchestrator::HolePunchPolicy,
125 },
126 HolePunchProbeResult {
128 link_id: [u8; 16],
129 session_id: [u8; 16],
130 observed_addr: std::net::SocketAddr,
131 socket: std::net::UdpSocket,
132 },
133 HolePunchProbeFailed {
135 link_id: [u8; 16],
136 session_id: [u8; 16],
137 },
138}
139
140#[derive(Debug)]
142pub enum QueryRequest {
143 InterfaceStats,
145 PathTable { max_hops: Option<u8> },
147 RateTable,
149 NextHop { dest_hash: [u8; 16] },
151 NextHopIfName { dest_hash: [u8; 16] },
153 LinkCount,
155 DropPath { dest_hash: [u8; 16] },
157 DropAllVia { transport_hash: [u8; 16] },
159 DropAnnounceQueues,
161 TransportIdentity,
163 GetBlackholed,
165 BlackholeIdentity {
167 identity_hash: [u8; 16],
168 duration_hours: Option<f64>,
169 reason: Option<String>,
170 },
171 UnblackholeIdentity {
173 identity_hash: [u8; 16],
174 },
175 HasPath { dest_hash: [u8; 16] },
177 HopsTo { dest_hash: [u8; 16] },
179 RecallIdentity { dest_hash: [u8; 16] },
181 LocalDestinations,
183 Links,
185 Resources,
187}
188
189#[derive(Debug)]
191pub enum QueryResponse {
192 InterfaceStats(InterfaceStatsResponse),
193 PathTable(Vec<PathTableEntry>),
194 RateTable(Vec<RateTableEntry>),
195 NextHop(Option<NextHopResponse>),
196 NextHopIfName(Option<String>),
197 LinkCount(usize),
198 DropPath(bool),
199 DropAllVia(usize),
200 DropAnnounceQueues,
201 TransportIdentity(Option<[u8; 16]>),
202 Blackholed(Vec<BlackholeInfo>),
203 BlackholeResult(bool),
204 UnblackholeResult(bool),
205 HasPath(bool),
206 HopsTo(Option<u8>),
207 RecallIdentity(Option<crate::destination::AnnouncedIdentity>),
208 LocalDestinations(Vec<LocalDestinationEntry>),
209 Links(Vec<LinkInfoEntry>),
210 Resources(Vec<ResourceInfoEntry>),
211}
212
213#[derive(Debug, Clone)]
215pub struct InterfaceStatsResponse {
216 pub interfaces: Vec<SingleInterfaceStat>,
217 pub transport_id: Option<[u8; 16]>,
218 pub transport_enabled: bool,
219 pub transport_uptime: f64,
220 pub total_rxb: u64,
222 pub total_txb: u64,
224}
225
226#[derive(Debug, Clone)]
228pub struct SingleInterfaceStat {
229 pub name: String,
230 pub status: bool,
231 pub mode: u8,
232 pub rxb: u64,
233 pub txb: u64,
234 pub rx_packets: u64,
235 pub tx_packets: u64,
236 pub bitrate: Option<u64>,
237 pub ifac_size: Option<usize>,
238 pub started: f64,
239 pub ia_freq: f64,
241 pub oa_freq: f64,
243 pub interface_type: String,
245}
246
247#[derive(Debug, Clone)]
249pub struct LocalDestinationEntry {
250 pub hash: [u8; 16],
251 pub dest_type: u8,
252}
253
254#[derive(Debug, Clone)]
256pub struct LinkInfoEntry {
257 pub link_id: [u8; 16],
258 pub state: String,
259 pub is_initiator: bool,
260 pub dest_hash: [u8; 16],
261 pub remote_identity: Option<[u8; 16]>,
262 pub rtt: Option<f64>,
263}
264
265#[derive(Debug, Clone)]
267pub struct ResourceInfoEntry {
268 pub link_id: [u8; 16],
269 pub direction: String,
270 pub total_parts: usize,
271 pub transferred_parts: usize,
272 pub complete: bool,
273}
274
275#[derive(Debug, Clone)]
277pub struct PathTableEntry {
278 pub hash: [u8; 16],
279 pub timestamp: f64,
280 pub via: [u8; 16],
281 pub hops: u8,
282 pub expires: f64,
283 pub interface: InterfaceId,
284 pub interface_name: String,
285}
286
287#[derive(Debug, Clone)]
289pub struct RateTableEntry {
290 pub hash: [u8; 16],
291 pub last: f64,
292 pub rate_violations: u32,
293 pub blocked_until: f64,
294 pub timestamps: Vec<f64>,
295}
296
297#[derive(Debug, Clone)]
299pub struct BlackholeInfo {
300 pub identity_hash: [u8; 16],
301 pub created: f64,
302 pub expires: f64,
303 pub reason: Option<String>,
304}
305
306#[derive(Debug, Clone)]
308pub struct NextHopResponse {
309 pub next_hop: [u8; 16],
310 pub hops: u8,
311 pub interface: InterfaceId,
312}
313
314impl fmt::Debug for Event {
315 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
316 match self {
317 Event::Frame { interface_id, data } => {
318 f.debug_struct("Frame")
319 .field("interface_id", interface_id)
320 .field("data_len", &data.len())
321 .finish()
322 }
323 Event::InterfaceUp(id, writer, info) => {
324 f.debug_tuple("InterfaceUp")
325 .field(id)
326 .field(&writer.is_some())
327 .field(&info.is_some())
328 .finish()
329 }
330 Event::InterfaceDown(id) => f.debug_tuple("InterfaceDown").field(id).finish(),
331 Event::Tick => write!(f, "Tick"),
332 Event::Shutdown => write!(f, "Shutdown"),
333 Event::SendOutbound { raw, dest_type, .. } => {
334 f.debug_struct("SendOutbound")
335 .field("raw_len", &raw.len())
336 .field("dest_type", dest_type)
337 .finish()
338 }
339 Event::RegisterDestination { dest_hash, dest_type } => {
340 f.debug_struct("RegisterDestination")
341 .field("dest_hash", dest_hash)
342 .field("dest_type", dest_type)
343 .finish()
344 }
345 Event::DeregisterDestination { dest_hash } => {
346 f.debug_struct("DeregisterDestination")
347 .field("dest_hash", dest_hash)
348 .finish()
349 }
350 Event::DeregisterLinkDestination { dest_hash } => {
351 f.debug_struct("DeregisterLinkDestination")
352 .field("dest_hash", dest_hash)
353 .finish()
354 }
355 Event::Query(req, _) => {
356 f.debug_tuple("Query")
357 .field(req)
358 .finish()
359 }
360 Event::RegisterLinkDestination { dest_hash, .. } => {
361 f.debug_struct("RegisterLinkDestination")
362 .field("dest_hash", dest_hash)
363 .finish()
364 }
365 Event::RegisterRequestHandler { path, .. } => {
366 f.debug_struct("RegisterRequestHandler")
367 .field("path", path)
368 .finish()
369 }
370 Event::CreateLink { dest_hash, .. } => {
371 f.debug_struct("CreateLink")
372 .field("dest_hash", dest_hash)
373 .finish()
374 }
375 Event::SendRequest { link_id, path, .. } => {
376 f.debug_struct("SendRequest")
377 .field("link_id", link_id)
378 .field("path", path)
379 .finish()
380 }
381 Event::IdentifyOnLink { link_id, .. } => {
382 f.debug_struct("IdentifyOnLink")
383 .field("link_id", link_id)
384 .finish()
385 }
386 Event::TeardownLink { link_id } => {
387 f.debug_struct("TeardownLink")
388 .field("link_id", link_id)
389 .finish()
390 }
391 Event::SendResource { link_id, data, .. } => {
392 f.debug_struct("SendResource")
393 .field("link_id", link_id)
394 .field("data_len", &data.len())
395 .finish()
396 }
397 Event::SetResourceStrategy { link_id, strategy } => {
398 f.debug_struct("SetResourceStrategy")
399 .field("link_id", link_id)
400 .field("strategy", strategy)
401 .finish()
402 }
403 Event::AcceptResource { link_id, accept, .. } => {
404 f.debug_struct("AcceptResource")
405 .field("link_id", link_id)
406 .field("accept", accept)
407 .finish()
408 }
409 Event::SendChannelMessage { link_id, msgtype, payload } => {
410 f.debug_struct("SendChannelMessage")
411 .field("link_id", link_id)
412 .field("msgtype", msgtype)
413 .field("payload_len", &payload.len())
414 .finish()
415 }
416 Event::SendOnLink { link_id, data, context } => {
417 f.debug_struct("SendOnLink")
418 .field("link_id", link_id)
419 .field("data_len", &data.len())
420 .field("context", context)
421 .finish()
422 }
423 Event::RequestPath { dest_hash } => {
424 f.debug_struct("RequestPath")
425 .field("dest_hash", dest_hash)
426 .finish()
427 }
428 Event::RegisterProofStrategy { dest_hash, strategy, .. } => {
429 f.debug_struct("RegisterProofStrategy")
430 .field("dest_hash", dest_hash)
431 .field("strategy", strategy)
432 .finish()
433 }
434 Event::ProposeDirectConnect { link_id } => {
435 f.debug_struct("ProposeDirectConnect")
436 .field("link_id", link_id)
437 .finish()
438 }
439 Event::SetDirectConnectPolicy { .. } => {
440 write!(f, "SetDirectConnectPolicy")
441 }
442 Event::HolePunchProbeResult { link_id, session_id, observed_addr, .. } => {
443 f.debug_struct("HolePunchProbeResult")
444 .field("link_id", link_id)
445 .field("session_id", session_id)
446 .field("observed_addr", observed_addr)
447 .finish()
448 }
449 Event::HolePunchProbeFailed { link_id, session_id } => {
450 f.debug_struct("HolePunchProbeFailed")
451 .field("link_id", link_id)
452 .field("session_id", session_id)
453 .finish()
454 }
455 }
456 }
457}
458
459pub type EventSender = mpsc::Sender<Event>;
460pub type EventReceiver = mpsc::Receiver<Event>;
461
462pub fn channel() -> (EventSender, EventReceiver) {
463 mpsc::channel()
464}