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 InterfaceConfigChanged(InterfaceId),
140 LoadHook {
142 name: String,
143 wasm_bytes: Vec<u8>,
144 attach_point: String,
145 priority: i32,
146 response_tx: mpsc::Sender<Result<(), String>>,
147 },
148 UnloadHook {
150 name: String,
151 attach_point: String,
152 response_tx: mpsc::Sender<Result<(), String>>,
153 },
154 ReloadHook {
156 name: String,
157 attach_point: String,
158 wasm_bytes: Vec<u8>,
159 response_tx: mpsc::Sender<Result<(), String>>,
160 },
161 ListHooks {
163 response_tx: mpsc::Sender<Vec<HookInfo>>,
164 },
165}
166
167#[derive(Debug, Clone)]
169pub struct HookInfo {
170 pub name: String,
171 pub attach_point: String,
172 pub priority: i32,
173 pub enabled: bool,
174 pub consecutive_traps: u32,
175}
176
177#[derive(Debug)]
179pub enum QueryRequest {
180 InterfaceStats,
182 PathTable { max_hops: Option<u8> },
184 RateTable,
186 NextHop { dest_hash: [u8; 16] },
188 NextHopIfName { dest_hash: [u8; 16] },
190 LinkCount,
192 DropPath { dest_hash: [u8; 16] },
194 DropAllVia { transport_hash: [u8; 16] },
196 DropAnnounceQueues,
198 TransportIdentity,
200 GetBlackholed,
202 BlackholeIdentity {
204 identity_hash: [u8; 16],
205 duration_hours: Option<f64>,
206 reason: Option<String>,
207 },
208 UnblackholeIdentity {
210 identity_hash: [u8; 16],
211 },
212 HasPath { dest_hash: [u8; 16] },
214 HopsTo { dest_hash: [u8; 16] },
216 RecallIdentity { dest_hash: [u8; 16] },
218 LocalDestinations,
220 Links,
222 Resources,
224 InjectPath {
226 dest_hash: [u8; 16],
227 next_hop: [u8; 16],
228 hops: u8,
229 expires: f64,
230 interface_name: String,
231 packet_hash: [u8; 32],
232 },
233 InjectIdentity {
235 dest_hash: [u8; 16],
236 identity_hash: [u8; 16],
237 public_key: [u8; 64],
238 app_data: Option<Vec<u8>>,
239 hops: u8,
240 received_at: f64,
241 },
242 DiscoveredInterfaces {
244 only_available: bool,
245 only_transport: bool,
246 },
247}
248
249#[derive(Debug)]
251pub enum QueryResponse {
252 InterfaceStats(InterfaceStatsResponse),
253 PathTable(Vec<PathTableEntry>),
254 RateTable(Vec<RateTableEntry>),
255 NextHop(Option<NextHopResponse>),
256 NextHopIfName(Option<String>),
257 LinkCount(usize),
258 DropPath(bool),
259 DropAllVia(usize),
260 DropAnnounceQueues,
261 TransportIdentity(Option<[u8; 16]>),
262 Blackholed(Vec<BlackholeInfo>),
263 BlackholeResult(bool),
264 UnblackholeResult(bool),
265 HasPath(bool),
266 HopsTo(Option<u8>),
267 RecallIdentity(Option<crate::destination::AnnouncedIdentity>),
268 LocalDestinations(Vec<LocalDestinationEntry>),
269 Links(Vec<LinkInfoEntry>),
270 Resources(Vec<ResourceInfoEntry>),
271 InjectPath(bool),
272 InjectIdentity(bool),
273 DiscoveredInterfaces(Vec<crate::discovery::DiscoveredInterface>),
275}
276
277#[derive(Debug, Clone)]
279pub struct InterfaceStatsResponse {
280 pub interfaces: Vec<SingleInterfaceStat>,
281 pub transport_id: Option<[u8; 16]>,
282 pub transport_enabled: bool,
283 pub transport_uptime: f64,
284 pub total_rxb: u64,
286 pub total_txb: u64,
288}
289
290#[derive(Debug, Clone)]
292pub struct SingleInterfaceStat {
293 pub name: String,
294 pub status: bool,
295 pub mode: u8,
296 pub rxb: u64,
297 pub txb: u64,
298 pub rx_packets: u64,
299 pub tx_packets: u64,
300 pub bitrate: Option<u64>,
301 pub ifac_size: Option<usize>,
302 pub started: f64,
303 pub ia_freq: f64,
305 pub oa_freq: f64,
307 pub interface_type: String,
309}
310
311#[derive(Debug, Clone)]
313pub struct LocalDestinationEntry {
314 pub hash: [u8; 16],
315 pub dest_type: u8,
316}
317
318#[derive(Debug, Clone)]
320pub struct LinkInfoEntry {
321 pub link_id: [u8; 16],
322 pub state: String,
323 pub is_initiator: bool,
324 pub dest_hash: [u8; 16],
325 pub remote_identity: Option<[u8; 16]>,
326 pub rtt: Option<f64>,
327}
328
329#[derive(Debug, Clone)]
331pub struct ResourceInfoEntry {
332 pub link_id: [u8; 16],
333 pub direction: String,
334 pub total_parts: usize,
335 pub transferred_parts: usize,
336 pub complete: bool,
337}
338
339#[derive(Debug, Clone)]
341pub struct PathTableEntry {
342 pub hash: [u8; 16],
343 pub timestamp: f64,
344 pub via: [u8; 16],
345 pub hops: u8,
346 pub expires: f64,
347 pub interface: InterfaceId,
348 pub interface_name: String,
349}
350
351#[derive(Debug, Clone)]
353pub struct RateTableEntry {
354 pub hash: [u8; 16],
355 pub last: f64,
356 pub rate_violations: u32,
357 pub blocked_until: f64,
358 pub timestamps: Vec<f64>,
359}
360
361#[derive(Debug, Clone)]
363pub struct BlackholeInfo {
364 pub identity_hash: [u8; 16],
365 pub created: f64,
366 pub expires: f64,
367 pub reason: Option<String>,
368}
369
370#[derive(Debug, Clone)]
372pub struct NextHopResponse {
373 pub next_hop: [u8; 16],
374 pub hops: u8,
375 pub interface: InterfaceId,
376}
377
378impl fmt::Debug for Event {
379 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
380 match self {
381 Event::Frame { interface_id, data } => {
382 f.debug_struct("Frame")
383 .field("interface_id", interface_id)
384 .field("data_len", &data.len())
385 .finish()
386 }
387 Event::InterfaceUp(id, writer, info) => {
388 f.debug_tuple("InterfaceUp")
389 .field(id)
390 .field(&writer.is_some())
391 .field(&info.is_some())
392 .finish()
393 }
394 Event::InterfaceDown(id) => f.debug_tuple("InterfaceDown").field(id).finish(),
395 Event::Tick => write!(f, "Tick"),
396 Event::Shutdown => write!(f, "Shutdown"),
397 Event::SendOutbound { raw, dest_type, .. } => {
398 f.debug_struct("SendOutbound")
399 .field("raw_len", &raw.len())
400 .field("dest_type", dest_type)
401 .finish()
402 }
403 Event::RegisterDestination { dest_hash, dest_type } => {
404 f.debug_struct("RegisterDestination")
405 .field("dest_hash", dest_hash)
406 .field("dest_type", dest_type)
407 .finish()
408 }
409 Event::DeregisterDestination { dest_hash } => {
410 f.debug_struct("DeregisterDestination")
411 .field("dest_hash", dest_hash)
412 .finish()
413 }
414 Event::DeregisterLinkDestination { dest_hash } => {
415 f.debug_struct("DeregisterLinkDestination")
416 .field("dest_hash", dest_hash)
417 .finish()
418 }
419 Event::Query(req, _) => {
420 f.debug_tuple("Query")
421 .field(req)
422 .finish()
423 }
424 Event::RegisterLinkDestination { dest_hash, .. } => {
425 f.debug_struct("RegisterLinkDestination")
426 .field("dest_hash", dest_hash)
427 .finish()
428 }
429 Event::RegisterRequestHandler { path, .. } => {
430 f.debug_struct("RegisterRequestHandler")
431 .field("path", path)
432 .finish()
433 }
434 Event::CreateLink { dest_hash, .. } => {
435 f.debug_struct("CreateLink")
436 .field("dest_hash", dest_hash)
437 .finish()
438 }
439 Event::SendRequest { link_id, path, .. } => {
440 f.debug_struct("SendRequest")
441 .field("link_id", link_id)
442 .field("path", path)
443 .finish()
444 }
445 Event::IdentifyOnLink { link_id, .. } => {
446 f.debug_struct("IdentifyOnLink")
447 .field("link_id", link_id)
448 .finish()
449 }
450 Event::TeardownLink { link_id } => {
451 f.debug_struct("TeardownLink")
452 .field("link_id", link_id)
453 .finish()
454 }
455 Event::SendResource { link_id, data, .. } => {
456 f.debug_struct("SendResource")
457 .field("link_id", link_id)
458 .field("data_len", &data.len())
459 .finish()
460 }
461 Event::SetResourceStrategy { link_id, strategy } => {
462 f.debug_struct("SetResourceStrategy")
463 .field("link_id", link_id)
464 .field("strategy", strategy)
465 .finish()
466 }
467 Event::AcceptResource { link_id, accept, .. } => {
468 f.debug_struct("AcceptResource")
469 .field("link_id", link_id)
470 .field("accept", accept)
471 .finish()
472 }
473 Event::SendChannelMessage { link_id, msgtype, payload } => {
474 f.debug_struct("SendChannelMessage")
475 .field("link_id", link_id)
476 .field("msgtype", msgtype)
477 .field("payload_len", &payload.len())
478 .finish()
479 }
480 Event::SendOnLink { link_id, data, context } => {
481 f.debug_struct("SendOnLink")
482 .field("link_id", link_id)
483 .field("data_len", &data.len())
484 .field("context", context)
485 .finish()
486 }
487 Event::RequestPath { dest_hash } => {
488 f.debug_struct("RequestPath")
489 .field("dest_hash", dest_hash)
490 .finish()
491 }
492 Event::RegisterProofStrategy { dest_hash, strategy, .. } => {
493 f.debug_struct("RegisterProofStrategy")
494 .field("dest_hash", dest_hash)
495 .field("strategy", strategy)
496 .finish()
497 }
498 Event::ProposeDirectConnect { link_id } => {
499 f.debug_struct("ProposeDirectConnect")
500 .field("link_id", link_id)
501 .finish()
502 }
503 Event::SetDirectConnectPolicy { .. } => {
504 write!(f, "SetDirectConnectPolicy")
505 }
506 Event::HolePunchProbeResult { link_id, session_id, observed_addr, .. } => {
507 f.debug_struct("HolePunchProbeResult")
508 .field("link_id", link_id)
509 .field("session_id", session_id)
510 .field("observed_addr", observed_addr)
511 .finish()
512 }
513 Event::HolePunchProbeFailed { link_id, session_id } => {
514 f.debug_struct("HolePunchProbeFailed")
515 .field("link_id", link_id)
516 .field("session_id", session_id)
517 .finish()
518 }
519 Event::InterfaceConfigChanged(id) => {
520 f.debug_tuple("InterfaceConfigChanged").field(id).finish()
521 }
522 Event::LoadHook { name, attach_point, priority, .. } => {
523 f.debug_struct("LoadHook")
524 .field("name", name)
525 .field("attach_point", attach_point)
526 .field("priority", priority)
527 .finish()
528 }
529 Event::UnloadHook { name, attach_point, .. } => {
530 f.debug_struct("UnloadHook")
531 .field("name", name)
532 .field("attach_point", attach_point)
533 .finish()
534 }
535 Event::ReloadHook { name, attach_point, .. } => {
536 f.debug_struct("ReloadHook")
537 .field("name", name)
538 .field("attach_point", attach_point)
539 .finish()
540 }
541 Event::ListHooks { .. } => write!(f, "ListHooks"),
542 }
543 }
544}
545
546pub type EventSender = mpsc::Sender<Event>;
547pub type EventReceiver = mpsc::Receiver<Event>;
548
549pub fn channel() -> (EventSender, EventReceiver) {
550 mpsc::channel()
551}