1use std::collections::HashMap;
4
5use rns_core::packet::RawPacket;
6use rns_core::transport::types::{InterfaceId, TransportAction, TransportConfig};
7use rns_core::transport::TransportEngine;
8use rns_crypto::{OsRng, Rng};
9
10use crate::event::{
11 BlackholeInfo, Event, EventReceiver, InterfaceStatsResponse,
12 LocalDestinationEntry, NextHopResponse, PathTableEntry, QueryRequest, QueryResponse,
13 RateTableEntry, SingleInterfaceStat,
14};
15use crate::ifac;
16use crate::interface::{InterfaceEntry, InterfaceStats};
17use crate::link_manager::{LinkManager, LinkManagerAction};
18use crate::time;
19
20fn infer_interface_type(name: &str) -> String {
24 if name.starts_with("TCPServerInterface") {
25 "TCPServerClientInterface".to_string()
26 } else if name.starts_with("BackboneInterface") {
27 "BackboneInterface".to_string()
28 } else if name.starts_with("LocalInterface") {
29 "LocalServerClientInterface".to_string()
30 } else {
31 "AutoInterface".to_string()
34 }
35}
36
37pub trait Callbacks: Send {
42 fn on_announce(
43 &mut self,
44 announced: crate::destination::AnnouncedIdentity,
45 );
46
47 fn on_path_updated(&mut self, dest_hash: rns_core::types::DestHash, hops: u8);
48
49 fn on_local_delivery(&mut self, dest_hash: rns_core::types::DestHash, raw: Vec<u8>, packet_hash: rns_core::types::PacketHash);
50
51 fn on_interface_up(&mut self, _id: InterfaceId) {}
53
54 fn on_interface_down(&mut self, _id: InterfaceId) {}
56
57 fn on_link_established(&mut self, _link_id: rns_core::types::LinkId, _rtt: f64, _is_initiator: bool) {}
59
60 fn on_link_closed(&mut self, _link_id: rns_core::types::LinkId, _reason: Option<rns_core::link::TeardownReason>) {}
62
63 fn on_remote_identified(&mut self, _link_id: rns_core::types::LinkId, _identity_hash: rns_core::types::IdentityHash, _public_key: [u8; 64]) {}
65
66 fn on_resource_received(&mut self, _link_id: rns_core::types::LinkId, _data: Vec<u8>, _metadata: Option<Vec<u8>>) {}
68
69 fn on_resource_completed(&mut self, _link_id: rns_core::types::LinkId) {}
71
72 fn on_resource_failed(&mut self, _link_id: rns_core::types::LinkId, _error: String) {}
74
75 fn on_resource_progress(&mut self, _link_id: rns_core::types::LinkId, _received: usize, _total: usize) {}
77
78 fn on_resource_accept_query(&mut self, _link_id: rns_core::types::LinkId, _resource_hash: Vec<u8>, _transfer_size: u64, _has_metadata: bool) -> bool {
81 false
82 }
83
84 fn on_channel_message(&mut self, _link_id: rns_core::types::LinkId, _msgtype: u16, _payload: Vec<u8>) {}
86
87 fn on_link_data(&mut self, _link_id: rns_core::types::LinkId, _context: u8, _data: Vec<u8>) {}
89
90 fn on_response(&mut self, _link_id: rns_core::types::LinkId, _request_id: [u8; 16], _data: Vec<u8>) {}
92
93 fn on_proof(&mut self, _dest_hash: rns_core::types::DestHash, _packet_hash: rns_core::types::PacketHash, _rtt: f64) {}
96
97 fn on_proof_requested(&mut self, _dest_hash: rns_core::types::DestHash, _packet_hash: rns_core::types::PacketHash) -> bool {
100 true
101 }
102}
103
104pub struct Driver {
106 pub(crate) engine: TransportEngine,
107 pub(crate) interfaces: HashMap<InterfaceId, InterfaceEntry>,
108 pub(crate) rng: OsRng,
109 pub(crate) rx: EventReceiver,
110 pub(crate) callbacks: Box<dyn Callbacks>,
111 pub(crate) started: f64,
112 pub(crate) announce_cache: Option<crate::announce_cache::AnnounceCache>,
113 pub(crate) tunnel_synth_dest: [u8; 16],
115 pub(crate) transport_identity: Option<rns_crypto::identity::Identity>,
117 pub(crate) link_manager: LinkManager,
119 pub(crate) management_config: crate::management::ManagementConfig,
121 pub(crate) last_management_announce: f64,
123 pub(crate) initial_announce_sent: bool,
125 pub(crate) known_destinations: HashMap<[u8; 16], crate::destination::AnnouncedIdentity>,
127 pub(crate) path_request_dest: [u8; 16],
129 pub(crate) proof_strategies: HashMap<[u8; 16], (rns_core::types::ProofStrategy, Option<rns_crypto::identity::Identity>)>,
132 pub(crate) sent_packets: HashMap<[u8; 32], ([u8; 16], f64)>,
134 pub(crate) local_destinations: HashMap<[u8; 16], u8>,
136}
137
138impl Driver {
139 pub fn new(
141 config: TransportConfig,
142 rx: EventReceiver,
143 callbacks: Box<dyn Callbacks>,
144 ) -> Self {
145 let tunnel_synth_dest = rns_core::destination::destination_hash(
146 "rnstransport",
147 &["tunnel", "synthesize"],
148 None,
149 );
150 let path_request_dest = rns_core::destination::destination_hash(
151 "rnstransport",
152 &["path", "request"],
153 None,
154 );
155 let mut engine = TransportEngine::new(config);
156 engine.register_destination(tunnel_synth_dest, rns_core::constants::DESTINATION_PLAIN);
157 engine.register_destination(path_request_dest, rns_core::constants::DESTINATION_PLAIN);
159 let mut local_destinations = HashMap::new();
160 local_destinations.insert(tunnel_synth_dest, rns_core::constants::DESTINATION_PLAIN);
161 local_destinations.insert(path_request_dest, rns_core::constants::DESTINATION_PLAIN);
162 Driver {
163 engine,
164 interfaces: HashMap::new(),
165 rng: OsRng,
166 rx,
167 callbacks,
168 started: time::now(),
169 announce_cache: None,
170 tunnel_synth_dest,
171 transport_identity: None,
172 link_manager: LinkManager::new(),
173 management_config: Default::default(),
174 last_management_announce: 0.0,
175 initial_announce_sent: false,
176 known_destinations: HashMap::new(),
177 path_request_dest,
178 proof_strategies: HashMap::new(),
179 sent_packets: HashMap::new(),
180 local_destinations,
181 }
182 }
183
184 pub fn run(&mut self) {
186 loop {
187 let event = match self.rx.recv() {
188 Ok(e) => e,
189 Err(_) => break, };
191
192 match event {
193 Event::Frame { interface_id, data } => {
194 if let Some(entry) = self.interfaces.get_mut(&interface_id) {
196 entry.stats.rxb += data.len() as u64;
197 entry.stats.rx_packets += 1;
198 }
199
200 let packet = if let Some(entry) = self.interfaces.get(&interface_id) {
202 if let Some(ref ifac_state) = entry.ifac {
203 match ifac::unmask_inbound(&data, ifac_state) {
205 Some(unmasked) => unmasked,
206 None => {
207 log::debug!("[{}] IFAC rejected packet", interface_id.0);
208 continue;
209 }
210 }
211 } else {
212 if data.len() > 2 && data[0] & 0x80 == 0x80 {
214 log::debug!("[{}] dropping packet with IFAC flag on non-IFAC interface", interface_id.0);
215 continue;
216 }
217 data
218 }
219 } else {
220 data
221 };
222
223 let actions = self.engine.handle_inbound(
224 &packet,
225 interface_id,
226 time::now(),
227 &mut self.rng,
228 );
229 self.dispatch_all(actions);
230 }
231 Event::Tick => {
232 let now = time::now();
233 let actions = self.engine.tick(now, &mut self.rng);
234 self.dispatch_all(actions);
235 let link_actions = self.link_manager.tick(&mut self.rng);
237 self.dispatch_link_actions(link_actions);
238 self.tick_management_announces(now);
240 self.sent_packets.retain(|_, (_, sent_time)| now - *sent_time < 60.0);
242 }
243 Event::InterfaceUp(id, new_writer, info) => {
244 let wants_tunnel;
245 if let Some(info) = info {
246 log::info!("[{}] dynamic interface registered", id.0);
248 wants_tunnel = info.wants_tunnel;
249 let iface_type = infer_interface_type(&info.name);
250 self.engine.register_interface(info.clone());
251 if let Some(writer) = new_writer {
252 self.interfaces.insert(
253 id,
254 InterfaceEntry {
255 id,
256 info,
257 writer,
258 online: true,
259 dynamic: true,
260 ifac: None,
261 stats: InterfaceStats {
262 started: time::now(),
263 ..Default::default()
264 },
265 interface_type: iface_type,
266 },
267 );
268 }
269 self.callbacks.on_interface_up(id);
270 } else if let Some(entry) = self.interfaces.get_mut(&id) {
271 log::info!("[{}] interface online", id.0);
273 wants_tunnel = entry.info.wants_tunnel;
274 entry.online = true;
275 if let Some(writer) = new_writer {
276 log::info!("[{}] writer refreshed after reconnect", id.0);
277 entry.writer = writer;
278 }
279 self.callbacks.on_interface_up(id);
280 } else {
281 wants_tunnel = false;
282 }
283
284 if wants_tunnel {
286 self.synthesize_tunnel_for_interface(id);
287 }
288 }
289 Event::InterfaceDown(id) => {
290 if let Some(entry) = self.interfaces.get(&id) {
292 if let Some(tunnel_id) = entry.info.tunnel_id {
293 self.engine.void_tunnel_interface(&tunnel_id);
294 }
295 }
296
297 if let Some(entry) = self.interfaces.get(&id) {
298 if entry.dynamic {
299 log::info!("[{}] dynamic interface removed", id.0);
301 self.engine.deregister_interface(id);
302 self.interfaces.remove(&id);
303 } else {
304 log::info!("[{}] interface offline", id.0);
306 self.interfaces.get_mut(&id).unwrap().online = false;
307 }
308 self.callbacks.on_interface_down(id);
309 }
310 }
311 Event::SendOutbound { raw, dest_type, attached_interface } => {
312 match RawPacket::unpack(&raw) {
313 Ok(packet) => {
314 if packet.flags.packet_type == rns_core::constants::PACKET_TYPE_DATA {
316 self.sent_packets.insert(
317 packet.packet_hash,
318 (packet.destination_hash, time::now()),
319 );
320 }
321 let actions = self.engine.handle_outbound(
322 &packet,
323 dest_type,
324 attached_interface,
325 time::now(),
326 );
327 self.dispatch_all(actions);
328 }
329 Err(e) => {
330 log::warn!("SendOutbound: failed to unpack packet: {:?}", e);
331 }
332 }
333 }
334 Event::RegisterDestination { dest_hash, dest_type } => {
335 self.engine.register_destination(dest_hash, dest_type);
336 self.local_destinations.insert(dest_hash, dest_type);
337 }
338 Event::DeregisterDestination { dest_hash } => {
339 self.engine.deregister_destination(&dest_hash);
340 self.local_destinations.remove(&dest_hash);
341 }
342 Event::Query(request, response_tx) => {
343 let response = self.handle_query_mut(request);
344 let _ = response_tx.send(response);
345 }
346 Event::RegisterLinkDestination { dest_hash, sig_prv_bytes, sig_pub_bytes } => {
347 let sig_prv = rns_crypto::ed25519::Ed25519PrivateKey::from_bytes(&sig_prv_bytes);
348 self.link_manager.register_link_destination(dest_hash, sig_prv, sig_pub_bytes);
349 self.engine.register_destination(dest_hash, rns_core::constants::DESTINATION_SINGLE);
351 self.local_destinations.insert(dest_hash, rns_core::constants::DESTINATION_SINGLE);
352 }
353 Event::RegisterRequestHandler { path, allowed_list, handler } => {
354 self.link_manager.register_request_handler(&path, allowed_list, move |link_id, p, data, remote| {
355 handler(link_id, p, data, remote)
356 });
357 }
358 Event::CreateLink { dest_hash, dest_sig_pub_bytes, response_tx } => {
359 let hops = self.engine.hops_to(&dest_hash).unwrap_or(0);
360 let (link_id, link_actions) = self.link_manager.create_link(
361 &dest_hash, &dest_sig_pub_bytes, hops, &mut self.rng,
362 );
363 let _ = response_tx.send(link_id);
364 self.dispatch_link_actions(link_actions);
365 }
366 Event::SendRequest { link_id, path, data } => {
367 let link_actions = self.link_manager.send_request(
368 &link_id, &path, &data, &mut self.rng,
369 );
370 self.dispatch_link_actions(link_actions);
371 }
372 Event::IdentifyOnLink { link_id, identity_prv_key } => {
373 let identity = rns_crypto::identity::Identity::from_private_key(&identity_prv_key);
374 let link_actions = self.link_manager.identify(&link_id, &identity, &mut self.rng);
375 self.dispatch_link_actions(link_actions);
376 }
377 Event::TeardownLink { link_id } => {
378 let link_actions = self.link_manager.teardown_link(&link_id);
379 self.dispatch_link_actions(link_actions);
380 }
381 Event::SendResource { link_id, data, metadata } => {
382 let link_actions = self.link_manager.send_resource(
383 &link_id, &data, metadata.as_deref(), &mut self.rng,
384 );
385 self.dispatch_link_actions(link_actions);
386 }
387 Event::SetResourceStrategy { link_id, strategy } => {
388 use crate::link_manager::ResourceStrategy;
389 let strat = match strategy {
390 0 => ResourceStrategy::AcceptNone,
391 1 => ResourceStrategy::AcceptAll,
392 2 => ResourceStrategy::AcceptApp,
393 _ => ResourceStrategy::AcceptNone,
394 };
395 self.link_manager.set_resource_strategy(&link_id, strat);
396 }
397 Event::AcceptResource { link_id, resource_hash, accept } => {
398 let link_actions = self.link_manager.accept_resource(
399 &link_id, &resource_hash, accept, &mut self.rng,
400 );
401 self.dispatch_link_actions(link_actions);
402 }
403 Event::SendChannelMessage { link_id, msgtype, payload } => {
404 let link_actions = self.link_manager.send_channel_message(
405 &link_id, msgtype, &payload, &mut self.rng,
406 );
407 self.dispatch_link_actions(link_actions);
408 }
409 Event::SendOnLink { link_id, data, context } => {
410 let link_actions = self.link_manager.send_on_link(
411 &link_id, &data, context, &mut self.rng,
412 );
413 self.dispatch_link_actions(link_actions);
414 }
415 Event::RequestPath { dest_hash } => {
416 self.handle_request_path(dest_hash);
417 }
418 Event::RegisterProofStrategy { dest_hash, strategy, signing_key } => {
419 let identity = signing_key.map(|key| {
420 rns_crypto::identity::Identity::from_private_key(&key)
421 });
422 self.proof_strategies.insert(dest_hash, (strategy, identity));
423 }
424 Event::Shutdown => break,
425 }
426 }
427 }
428
429 fn handle_query(&self, request: QueryRequest) -> QueryResponse {
431 match request {
432 QueryRequest::InterfaceStats => {
433 let mut interfaces = Vec::new();
434 let mut total_rxb: u64 = 0;
435 let mut total_txb: u64 = 0;
436 for entry in self.interfaces.values() {
437 total_rxb += entry.stats.rxb;
438 total_txb += entry.stats.txb;
439 interfaces.push(SingleInterfaceStat {
440 name: entry.info.name.clone(),
441 status: entry.online,
442 mode: entry.info.mode,
443 rxb: entry.stats.rxb,
444 txb: entry.stats.txb,
445 rx_packets: entry.stats.rx_packets,
446 tx_packets: entry.stats.tx_packets,
447 bitrate: entry.info.bitrate,
448 ifac_size: entry.ifac.as_ref().map(|s| s.size),
449 started: entry.stats.started,
450 ia_freq: entry.stats.incoming_announce_freq(),
451 oa_freq: entry.stats.outgoing_announce_freq(),
452 interface_type: entry.interface_type.clone(),
453 });
454 }
455 interfaces.sort_by(|a, b| a.name.cmp(&b.name));
457 QueryResponse::InterfaceStats(InterfaceStatsResponse {
458 interfaces,
459 transport_id: self.engine.identity_hash().copied(),
460 transport_enabled: self.engine.transport_enabled(),
461 transport_uptime: time::now() - self.started,
462 total_rxb,
463 total_txb,
464 })
465 }
466 QueryRequest::PathTable { max_hops } => {
467 let entries: Vec<PathTableEntry> = self
468 .engine
469 .path_table_entries()
470 .filter(|(_, entry)| {
471 max_hops.map_or(true, |max| entry.hops <= max)
472 })
473 .map(|(hash, entry)| {
474 let iface_name = self.interfaces.get(&entry.receiving_interface)
475 .map(|e| e.info.name.clone())
476 .or_else(|| self.engine.interface_info(&entry.receiving_interface)
477 .map(|i| i.name.clone()))
478 .unwrap_or_default();
479 PathTableEntry {
480 hash: *hash,
481 timestamp: entry.timestamp,
482 via: entry.next_hop,
483 hops: entry.hops,
484 expires: entry.expires,
485 interface: entry.receiving_interface,
486 interface_name: iface_name,
487 }
488 })
489 .collect();
490 QueryResponse::PathTable(entries)
491 }
492 QueryRequest::RateTable => {
493 let entries: Vec<RateTableEntry> = self
494 .engine
495 .rate_limiter()
496 .entries()
497 .map(|(hash, entry)| RateTableEntry {
498 hash: *hash,
499 last: entry.last,
500 rate_violations: entry.rate_violations,
501 blocked_until: entry.blocked_until,
502 timestamps: entry.timestamps.clone(),
503 })
504 .collect();
505 QueryResponse::RateTable(entries)
506 }
507 QueryRequest::NextHop { dest_hash } => {
508 let resp = self.engine.next_hop(&dest_hash).map(|next_hop| {
509 NextHopResponse {
510 next_hop,
511 hops: self.engine.hops_to(&dest_hash).unwrap_or(0),
512 interface: self.engine.next_hop_interface(&dest_hash).unwrap_or(InterfaceId(0)),
513 }
514 });
515 QueryResponse::NextHop(resp)
516 }
517 QueryRequest::NextHopIfName { dest_hash } => {
518 let name = self
519 .engine
520 .next_hop_interface(&dest_hash)
521 .and_then(|id| self.interfaces.get(&id))
522 .map(|entry| entry.info.name.clone());
523 QueryResponse::NextHopIfName(name)
524 }
525 QueryRequest::LinkCount => {
526 QueryResponse::LinkCount(self.engine.link_table_count() + self.link_manager.link_count())
527 }
528 QueryRequest::DropPath { .. } => {
529 QueryResponse::DropPath(false)
531 }
532 QueryRequest::DropAllVia { .. } => {
533 QueryResponse::DropAllVia(0)
534 }
535 QueryRequest::DropAnnounceQueues => {
536 QueryResponse::DropAnnounceQueues
537 }
538 QueryRequest::TransportIdentity => {
539 QueryResponse::TransportIdentity(self.engine.identity_hash().copied())
540 }
541 QueryRequest::GetBlackholed => {
542 let now = time::now();
543 let entries: Vec<BlackholeInfo> = self.engine.blackholed_entries()
544 .filter(|(_, e)| e.expires == 0.0 || e.expires > now)
545 .map(|(hash, entry)| BlackholeInfo {
546 identity_hash: *hash,
547 created: entry.created,
548 expires: entry.expires,
549 reason: entry.reason.clone(),
550 })
551 .collect();
552 QueryResponse::Blackholed(entries)
553 }
554 QueryRequest::BlackholeIdentity { .. }
555 | QueryRequest::UnblackholeIdentity { .. } => {
556 QueryResponse::BlackholeResult(false)
558 }
559 QueryRequest::HasPath { dest_hash } => {
560 QueryResponse::HasPath(self.engine.has_path(&dest_hash))
561 }
562 QueryRequest::HopsTo { dest_hash } => {
563 QueryResponse::HopsTo(self.engine.hops_to(&dest_hash))
564 }
565 QueryRequest::RecallIdentity { dest_hash } => {
566 QueryResponse::RecallIdentity(self.known_destinations.get(&dest_hash).cloned())
567 }
568 QueryRequest::LocalDestinations => {
569 let entries: Vec<LocalDestinationEntry> = self
570 .local_destinations
571 .iter()
572 .map(|(hash, dest_type)| LocalDestinationEntry {
573 hash: *hash,
574 dest_type: *dest_type,
575 })
576 .collect();
577 QueryResponse::LocalDestinations(entries)
578 }
579 QueryRequest::Links => {
580 QueryResponse::Links(self.link_manager.link_entries())
581 }
582 QueryRequest::Resources => {
583 QueryResponse::Resources(self.link_manager.resource_entries())
584 }
585 }
586 }
587
588 fn handle_query_mut(&mut self, request: QueryRequest) -> QueryResponse {
590 match request {
591 QueryRequest::BlackholeIdentity { identity_hash, duration_hours, reason } => {
592 let now = time::now();
593 self.engine.blackhole_identity(identity_hash, now, duration_hours, reason);
594 QueryResponse::BlackholeResult(true)
595 }
596 QueryRequest::UnblackholeIdentity { identity_hash } => {
597 let result = self.engine.unblackhole_identity(&identity_hash);
598 QueryResponse::UnblackholeResult(result)
599 }
600 QueryRequest::DropPath { dest_hash } => {
601 QueryResponse::DropPath(self.engine.drop_path(&dest_hash))
602 }
603 QueryRequest::DropAllVia { transport_hash } => {
604 QueryResponse::DropAllVia(self.engine.drop_all_via(&transport_hash))
605 }
606 QueryRequest::DropAnnounceQueues => {
607 self.engine.drop_announce_queues();
608 QueryResponse::DropAnnounceQueues
609 }
610 other => self.handle_query(other),
611 }
612 }
613
614 fn handle_tunnel_synth_delivery(&mut self, raw: &[u8]) {
616 let packet = match RawPacket::unpack(raw) {
618 Ok(p) => p,
619 Err(_) => return,
620 };
621
622 match rns_core::transport::tunnel::validate_tunnel_synthesize_data(&packet.data) {
623 Ok(validated) => {
624 let iface_id = self
627 .interfaces
628 .iter()
629 .find(|(_, entry)| entry.info.wants_tunnel && entry.online)
630 .map(|(id, _)| *id);
631
632 if let Some(iface) = iface_id {
633 let now = time::now();
634 let tunnel_actions =
635 self.engine.handle_tunnel(validated.tunnel_id, iface, now);
636 self.dispatch_all(tunnel_actions);
637 }
638 }
639 Err(e) => {
640 log::debug!("Tunnel synthesis validation failed: {}", e);
641 }
642 }
643 }
644
645 fn synthesize_tunnel_for_interface(&mut self, interface: InterfaceId) {
649 if let Some(ref identity) = self.transport_identity {
650 let actions = self.engine.synthesize_tunnel(identity, interface, &mut self.rng);
651 self.dispatch_all(actions);
652 }
653 }
654
655 fn handle_request_path(&mut self, dest_hash: [u8; 16]) {
657 let mut data = Vec::with_capacity(48);
659 data.extend_from_slice(&dest_hash);
660
661 if self.engine.transport_enabled() {
662 if let Some(id_hash) = self.engine.identity_hash() {
663 data.extend_from_slice(id_hash);
664 }
665 }
666
667 let mut tag = [0u8; 16];
669 self.rng.fill_bytes(&mut tag);
670 data.extend_from_slice(&tag);
671
672 let flags = rns_core::packet::PacketFlags {
674 header_type: rns_core::constants::HEADER_1,
675 context_flag: rns_core::constants::FLAG_UNSET,
676 transport_type: rns_core::constants::TRANSPORT_BROADCAST,
677 destination_type: rns_core::constants::DESTINATION_PLAIN,
678 packet_type: rns_core::constants::PACKET_TYPE_DATA,
679 };
680
681 if let Ok(packet) = RawPacket::pack(
682 flags, 0, &self.path_request_dest, None,
683 rns_core::constants::CONTEXT_NONE, &data,
684 ) {
685 let actions = self.engine.handle_outbound(
686 &packet,
687 rns_core::constants::DESTINATION_PLAIN,
688 None,
689 time::now(),
690 );
691 self.dispatch_all(actions);
692 }
693 }
694
695 fn maybe_generate_proof(&mut self, dest_hash: [u8; 16], packet_hash: &[u8; 32]) {
698 use rns_core::types::ProofStrategy;
699
700 let (strategy, identity) = match self.proof_strategies.get(&dest_hash) {
701 Some((s, id)) => (*s, id.as_ref()),
702 None => return,
703 };
704
705 let should_prove = match strategy {
706 ProofStrategy::ProveAll => true,
707 ProofStrategy::ProveApp => {
708 self.callbacks.on_proof_requested(
709 rns_core::types::DestHash(dest_hash),
710 rns_core::types::PacketHash(*packet_hash),
711 )
712 }
713 ProofStrategy::ProveNone => false,
714 };
715
716 if !should_prove {
717 return;
718 }
719
720 let identity = match identity {
721 Some(id) => id,
722 None => {
723 log::warn!("Cannot generate proof for {:02x?}: no signing key", &dest_hash[..4]);
724 return;
725 }
726 };
727
728 let signature = match identity.sign(packet_hash) {
730 Ok(sig) => sig,
731 Err(e) => {
732 log::warn!("Failed to sign proof for {:02x?}: {:?}", &dest_hash[..4], e);
733 return;
734 }
735 };
736
737 let mut proof_data = Vec::with_capacity(96);
739 proof_data.extend_from_slice(packet_hash);
740 proof_data.extend_from_slice(&signature);
741
742 let mut proof_dest = [0u8; 16];
748 proof_dest.copy_from_slice(&packet_hash[..16]);
749
750 let flags = rns_core::packet::PacketFlags {
751 header_type: rns_core::constants::HEADER_1,
752 context_flag: rns_core::constants::FLAG_UNSET,
753 transport_type: rns_core::constants::TRANSPORT_BROADCAST,
754 destination_type: rns_core::constants::DESTINATION_SINGLE,
755 packet_type: rns_core::constants::PACKET_TYPE_PROOF,
756 };
757
758 if let Ok(packet) = RawPacket::pack(
759 flags, 0, &proof_dest, None,
760 rns_core::constants::CONTEXT_NONE, &proof_data,
761 ) {
762 let actions = self.engine.handle_outbound(
763 &packet,
764 rns_core::constants::DESTINATION_SINGLE,
765 None,
766 time::now(),
767 );
768 self.dispatch_all(actions);
769 log::debug!("Generated proof for packet on dest {:02x?}", &dest_hash[..4]);
770 }
771 }
772
773 fn handle_inbound_proof(&mut self, dest_hash: [u8; 16], proof_data: &[u8], _raw_packet_hash: &[u8; 32]) {
775 if proof_data.len() < 96 {
777 log::debug!("Proof too short for explicit proof: {} bytes", proof_data.len());
778 return;
779 }
780
781 let mut tracked_hash = [0u8; 32];
782 tracked_hash.copy_from_slice(&proof_data[..32]);
783
784 let signature = &proof_data[32..96];
785
786 if let Some((tracked_dest, sent_time)) = self.sent_packets.remove(&tracked_hash) {
788 if let Some(announced) = self.known_destinations.get(&tracked_dest) {
791 let identity = rns_crypto::identity::Identity::from_public_key(&announced.public_key);
792 let mut sig = [0u8; 64];
793 sig.copy_from_slice(signature);
794 if !identity.verify(&sig, &tracked_hash) {
795 log::debug!(
796 "Proof signature invalid for {:02x?}",
797 &tracked_hash[..4],
798 );
799 return;
800 }
801 } else {
802 log::debug!(
803 "No known identity for dest {:02x?}, accepting proof without signature check",
804 &tracked_dest[..4],
805 );
806 }
807
808 let rtt = time::now() - sent_time;
809 log::debug!(
810 "Proof received for {:02x?} rtt={:.3}s",
811 &tracked_hash[..4], rtt,
812 );
813 self.callbacks.on_proof(
814 rns_core::types::DestHash(tracked_dest),
815 rns_core::types::PacketHash(tracked_hash),
816 rtt,
817 );
818 } else {
819 log::debug!(
820 "Proof for unknown packet {:02x?} on dest {:02x?}",
821 &tracked_hash[..4], &dest_hash[..4],
822 );
823 }
824 }
825
826 fn dispatch_all(&mut self, actions: Vec<TransportAction>) {
828 for action in actions {
829 match action {
830 TransportAction::SendOnInterface { interface, raw } => {
831 let is_announce = raw.len() > 2 && (raw[0] & 0x03) == 0x01;
832 if let Some(entry) = self.interfaces.get_mut(&interface) {
833 if entry.online {
834 let data = if let Some(ref ifac_state) = entry.ifac {
835 ifac::mask_outbound(&raw, ifac_state)
836 } else {
837 raw
838 };
839 entry.stats.txb += data.len() as u64;
841 entry.stats.tx_packets += 1;
842 if is_announce {
843 entry.stats.record_outgoing_announce(time::now());
844 }
845 if let Err(e) = entry.writer.send_frame(&data) {
846 log::warn!("[{}] send failed: {}", entry.info.id.0, e);
847 }
848 }
849 }
850 }
851 TransportAction::BroadcastOnAllInterfaces { raw, exclude } => {
852 let is_announce = raw.len() > 2 && (raw[0] & 0x03) == 0x01;
853 for entry in self.interfaces.values_mut() {
854 if entry.online && Some(entry.id) != exclude {
855 let data = if let Some(ref ifac_state) = entry.ifac {
856 ifac::mask_outbound(&raw, ifac_state)
857 } else {
858 raw.clone()
859 };
860 entry.stats.txb += data.len() as u64;
862 entry.stats.tx_packets += 1;
863 if is_announce {
864 entry.stats.record_outgoing_announce(time::now());
865 }
866 if let Err(e) = entry.writer.send_frame(&data) {
867 log::warn!("[{}] broadcast failed: {}", entry.info.id.0, e);
868 }
869 }
870 }
871 }
872 TransportAction::DeliverLocal {
873 destination_hash,
874 raw,
875 packet_hash,
876 } => {
877 if destination_hash == self.tunnel_synth_dest {
878 self.handle_tunnel_synth_delivery(&raw);
880 } else if destination_hash == self.path_request_dest {
881 if let Ok(packet) = RawPacket::unpack(&raw) {
883 let actions = self.engine.handle_path_request(
884 &packet.data,
885 InterfaceId(0), time::now(),
887 );
888 self.dispatch_all(actions);
889 }
890 } else if self.link_manager.is_link_destination(&destination_hash) {
891 let link_actions = self.link_manager.handle_local_delivery(
893 destination_hash, &raw, packet_hash, &mut self.rng,
894 );
895 self.dispatch_link_actions(link_actions);
896 } else {
897 if let Ok(packet) = RawPacket::unpack(&raw) {
899 if packet.flags.packet_type == rns_core::constants::PACKET_TYPE_PROOF {
900 self.handle_inbound_proof(destination_hash, &packet.data, &packet_hash);
901 continue;
902 }
903 }
904
905 self.maybe_generate_proof(destination_hash, &packet_hash);
907
908 self.callbacks
909 .on_local_delivery(
910 rns_core::types::DestHash(destination_hash),
911 raw,
912 rns_core::types::PacketHash(packet_hash),
913 );
914 }
915 }
916 TransportAction::AnnounceReceived {
917 destination_hash,
918 identity_hash,
919 public_key,
920 app_data,
921 hops,
922 receiving_interface,
923 ..
924 } => {
925 if let Some(entry) = self.interfaces.get_mut(&receiving_interface) {
926 entry.stats.record_incoming_announce(time::now());
927 }
928 let announced = crate::destination::AnnouncedIdentity {
930 dest_hash: rns_core::types::DestHash(destination_hash),
931 identity_hash: rns_core::types::IdentityHash(identity_hash),
932 public_key,
933 app_data: app_data.clone(),
934 hops,
935 received_at: time::now(),
936 };
937 self.known_destinations.insert(destination_hash, announced.clone());
938 self.callbacks.on_announce(announced);
939 }
940 TransportAction::PathUpdated {
941 destination_hash,
942 hops,
943 ..
944 } => {
945 self.callbacks.on_path_updated(rns_core::types::DestHash(destination_hash), hops);
946 }
947 TransportAction::ForwardToLocalClients { raw, exclude } => {
948 for entry in self.interfaces.values_mut() {
949 if entry.online
950 && entry.info.is_local_client
951 && Some(entry.id) != exclude
952 {
953 let data = if let Some(ref ifac_state) = entry.ifac {
954 ifac::mask_outbound(&raw, ifac_state)
955 } else {
956 raw.clone()
957 };
958 entry.stats.txb += data.len() as u64;
959 entry.stats.tx_packets += 1;
960 if let Err(e) = entry.writer.send_frame(&data) {
961 log::warn!("[{}] forward to local client failed: {}", entry.info.id.0, e);
962 }
963 }
964 }
965 }
966 TransportAction::ForwardPlainBroadcast { raw, to_local, exclude } => {
967 for entry in self.interfaces.values_mut() {
968 if entry.online
969 && entry.info.is_local_client == to_local
970 && Some(entry.id) != exclude
971 {
972 let data = if let Some(ref ifac_state) = entry.ifac {
973 ifac::mask_outbound(&raw, ifac_state)
974 } else {
975 raw.clone()
976 };
977 entry.stats.txb += data.len() as u64;
978 entry.stats.tx_packets += 1;
979 if let Err(e) = entry.writer.send_frame(&data) {
980 log::warn!("[{}] forward plain broadcast failed: {}", entry.info.id.0, e);
981 }
982 }
983 }
984 }
985 TransportAction::CacheAnnounce { packet_hash, raw } => {
986 if let Some(ref cache) = self.announce_cache {
987 if let Err(e) = cache.store(&packet_hash, &raw, None) {
988 log::warn!("Failed to cache announce: {}", e);
989 }
990 }
991 }
992 TransportAction::TunnelSynthesize { interface, data, dest_hash } => {
993 let flags = rns_core::packet::PacketFlags {
995 header_type: rns_core::constants::HEADER_1,
996 context_flag: rns_core::constants::FLAG_UNSET,
997 transport_type: rns_core::constants::TRANSPORT_BROADCAST,
998 destination_type: rns_core::constants::DESTINATION_PLAIN,
999 packet_type: rns_core::constants::PACKET_TYPE_DATA,
1000 };
1001 if let Ok(packet) = rns_core::packet::RawPacket::pack(
1002 flags, 0, &dest_hash, None,
1003 rns_core::constants::CONTEXT_NONE, &data,
1004 ) {
1005 if let Some(entry) = self.interfaces.get_mut(&interface) {
1006 if entry.online {
1007 let raw = if let Some(ref ifac_state) = entry.ifac {
1008 ifac::mask_outbound(&packet.raw, ifac_state)
1009 } else {
1010 packet.raw
1011 };
1012 entry.stats.txb += raw.len() as u64;
1013 entry.stats.tx_packets += 1;
1014 if let Err(e) = entry.writer.send_frame(&raw) {
1015 log::warn!("[{}] tunnel synthesize send failed: {}", entry.info.id.0, e);
1016 }
1017 }
1018 }
1019 }
1020 }
1021 TransportAction::TunnelEstablished { tunnel_id, interface } => {
1022 log::info!("Tunnel established: {:02x?} on interface {}", &tunnel_id[..4], interface.0);
1023 }
1024 }
1025 }
1026 }
1027
1028 fn dispatch_link_actions(&mut self, actions: Vec<LinkManagerAction>) {
1030 for action in actions {
1031 match action {
1032 LinkManagerAction::SendPacket { raw, dest_type, attached_interface } => {
1033 match RawPacket::unpack(&raw) {
1035 Ok(packet) => {
1036 let transport_actions = self.engine.handle_outbound(
1037 &packet,
1038 dest_type,
1039 attached_interface,
1040 time::now(),
1041 );
1042 self.dispatch_all(transport_actions);
1043 }
1044 Err(e) => {
1045 log::warn!("LinkManager SendPacket: failed to unpack: {:?}", e);
1046 }
1047 }
1048 }
1049 LinkManagerAction::LinkEstablished { link_id, rtt, is_initiator } => {
1050 log::info!(
1051 "Link established: {:02x?} rtt={:.3}s initiator={}",
1052 &link_id[..4], rtt, is_initiator,
1053 );
1054 self.callbacks.on_link_established(rns_core::types::LinkId(link_id), rtt, is_initiator);
1055 }
1056 LinkManagerAction::LinkClosed { link_id, reason } => {
1057 log::info!("Link closed: {:02x?} reason={:?}", &link_id[..4], reason);
1058 self.callbacks.on_link_closed(rns_core::types::LinkId(link_id), reason);
1059 }
1060 LinkManagerAction::RemoteIdentified { link_id, identity_hash, public_key } => {
1061 log::debug!(
1062 "Remote identified on link {:02x?}: {:02x?}",
1063 &link_id[..4], &identity_hash[..4],
1064 );
1065 self.callbacks.on_remote_identified(
1066 rns_core::types::LinkId(link_id),
1067 rns_core::types::IdentityHash(identity_hash),
1068 public_key,
1069 );
1070 }
1071 LinkManagerAction::RegisterLinkDest { link_id } => {
1072 self.engine.register_destination(link_id, rns_core::constants::DESTINATION_LINK);
1074 }
1075 LinkManagerAction::DeregisterLinkDest { link_id } => {
1076 self.engine.deregister_destination(&link_id);
1077 }
1078 LinkManagerAction::ManagementRequest {
1079 link_id, path_hash, data, request_id, remote_identity,
1080 } => {
1081 self.handle_management_request(
1082 link_id, path_hash, data, request_id, remote_identity,
1083 );
1084 }
1085 LinkManagerAction::ResourceReceived { link_id, data, metadata } => {
1086 self.callbacks.on_resource_received(rns_core::types::LinkId(link_id), data, metadata);
1087 }
1088 LinkManagerAction::ResourceCompleted { link_id } => {
1089 self.callbacks.on_resource_completed(rns_core::types::LinkId(link_id));
1090 }
1091 LinkManagerAction::ResourceFailed { link_id, error } => {
1092 log::debug!("Resource failed on link {:02x?}: {}", &link_id[..4], error);
1093 self.callbacks.on_resource_failed(rns_core::types::LinkId(link_id), error);
1094 }
1095 LinkManagerAction::ResourceProgress { link_id, received, total } => {
1096 self.callbacks.on_resource_progress(rns_core::types::LinkId(link_id), received, total);
1097 }
1098 LinkManagerAction::ResourceAcceptQuery { link_id, resource_hash, transfer_size, has_metadata } => {
1099 let accept = self.callbacks.on_resource_accept_query(
1100 rns_core::types::LinkId(link_id), resource_hash.clone(), transfer_size, has_metadata,
1101 );
1102 let accept_actions = self.link_manager.accept_resource(
1103 &link_id, &resource_hash, accept, &mut self.rng,
1104 );
1105 self.dispatch_link_actions(accept_actions);
1107 }
1108 LinkManagerAction::ChannelMessageReceived { link_id, msgtype, payload } => {
1109 self.callbacks.on_channel_message(rns_core::types::LinkId(link_id), msgtype, payload);
1110 }
1111 LinkManagerAction::LinkDataReceived { link_id, context, data } => {
1112 self.callbacks.on_link_data(rns_core::types::LinkId(link_id), context, data);
1113 }
1114 LinkManagerAction::ResponseReceived { link_id, request_id, data } => {
1115 self.callbacks.on_response(rns_core::types::LinkId(link_id), request_id, data);
1116 }
1117 }
1118 }
1119 }
1120
1121 const MANAGEMENT_ANNOUNCE_INTERVAL: f64 = 300.0;
1123
1124 const MANAGEMENT_ANNOUNCE_DELAY: f64 = 5.0;
1126
1127 fn tick_management_announces(&mut self, now: f64) {
1129 if self.transport_identity.is_none() {
1130 return;
1131 }
1132
1133 let uptime = now - self.started;
1134
1135 if !self.initial_announce_sent {
1137 if uptime < Self::MANAGEMENT_ANNOUNCE_DELAY {
1138 return;
1139 }
1140 self.initial_announce_sent = true;
1141 self.emit_management_announces(now);
1142 return;
1143 }
1144
1145 if now - self.last_management_announce >= Self::MANAGEMENT_ANNOUNCE_INTERVAL {
1147 self.emit_management_announces(now);
1148 }
1149 }
1150
1151 fn emit_management_announces(&mut self, now: f64) {
1153 use crate::management;
1154
1155 self.last_management_announce = now;
1156
1157 let identity = match self.transport_identity {
1158 Some(ref id) => id,
1159 None => return,
1160 };
1161
1162 let mgmt_raw = if self.management_config.enable_remote_management {
1164 management::build_management_announce(identity, &mut self.rng)
1165 } else {
1166 None
1167 };
1168
1169 let bh_raw = if self.management_config.publish_blackhole {
1170 management::build_blackhole_announce(identity, &mut self.rng)
1171 } else {
1172 None
1173 };
1174
1175 if let Some(raw) = mgmt_raw {
1176 if let Ok(packet) = RawPacket::unpack(&raw) {
1177 let actions = self.engine.handle_outbound(
1178 &packet,
1179 rns_core::constants::DESTINATION_SINGLE,
1180 None,
1181 now,
1182 );
1183 self.dispatch_all(actions);
1184 log::debug!("Emitted management destination announce");
1185 }
1186 }
1187
1188 if let Some(raw) = bh_raw {
1189 if let Ok(packet) = RawPacket::unpack(&raw) {
1190 let actions = self.engine.handle_outbound(
1191 &packet,
1192 rns_core::constants::DESTINATION_SINGLE,
1193 None,
1194 now,
1195 );
1196 self.dispatch_all(actions);
1197 log::debug!("Emitted blackhole info announce");
1198 }
1199 }
1200 }
1201
1202 fn handle_management_request(
1204 &mut self,
1205 link_id: [u8; 16],
1206 path_hash: [u8; 16],
1207 data: Vec<u8>,
1208 request_id: [u8; 16],
1209 remote_identity: Option<([u8; 16], [u8; 64])>,
1210 ) {
1211 use crate::management;
1212
1213 let is_restricted = path_hash == management::status_path_hash()
1215 || path_hash == management::path_path_hash();
1216
1217 if is_restricted && !self.management_config.remote_management_allowed.is_empty() {
1218 match remote_identity {
1219 Some((identity_hash, _)) => {
1220 if !self.management_config.remote_management_allowed.contains(&identity_hash) {
1221 log::debug!("Management request denied: identity not in allowed list");
1222 return;
1223 }
1224 }
1225 None => {
1226 log::debug!("Management request denied: peer not identified");
1227 return;
1228 }
1229 }
1230 }
1231
1232 let response_data = if path_hash == management::status_path_hash() {
1233 management::handle_status_request(&data, &self.engine, &self.interfaces, self.started)
1234 } else if path_hash == management::path_path_hash() {
1235 management::handle_path_request(&data, &self.engine)
1236 } else if path_hash == management::list_path_hash() {
1237 management::handle_blackhole_list_request(&self.engine)
1238 } else {
1239 log::warn!("Unknown management path_hash: {:02x?}", &path_hash[..4]);
1240 None
1241 };
1242
1243 if let Some(response) = response_data {
1244 let actions = self.link_manager.send_management_response(
1245 &link_id, &request_id, &response, &mut self.rng,
1246 );
1247 self.dispatch_link_actions(actions);
1248 }
1249 }
1250}
1251
1252#[cfg(test)]
1253mod tests {
1254 use super::*;
1255 use crate::event;
1256 use crate::interface::Writer;
1257 use rns_core::announce::AnnounceData;
1258 use rns_core::constants;
1259 use rns_core::packet::PacketFlags;
1260 use rns_core::transport::types::InterfaceInfo;
1261 use rns_crypto::identity::Identity;
1262 use std::io;
1263 use std::sync::mpsc;
1264 use std::sync::{Arc, Mutex};
1265
1266 struct MockWriter {
1267 sent: Arc<Mutex<Vec<Vec<u8>>>>,
1268 }
1269
1270 impl MockWriter {
1271 fn new() -> (Self, Arc<Mutex<Vec<Vec<u8>>>>) {
1272 let sent = Arc::new(Mutex::new(Vec::new()));
1273 (MockWriter { sent: sent.clone() }, sent)
1274 }
1275 }
1276
1277 impl Writer for MockWriter {
1278 fn send_frame(&mut self, data: &[u8]) -> io::Result<()> {
1279 self.sent.lock().unwrap().push(data.to_vec());
1280 Ok(())
1281 }
1282 }
1283
1284 use rns_core::types::{DestHash, IdentityHash, LinkId as TypedLinkId, PacketHash};
1285
1286 struct MockCallbacks {
1287 announces: Arc<Mutex<Vec<(DestHash, u8)>>>,
1288 paths: Arc<Mutex<Vec<(DestHash, u8)>>>,
1289 deliveries: Arc<Mutex<Vec<DestHash>>>,
1290 iface_ups: Arc<Mutex<Vec<InterfaceId>>>,
1291 iface_downs: Arc<Mutex<Vec<InterfaceId>>>,
1292 link_established: Arc<Mutex<Vec<(TypedLinkId, f64, bool)>>>,
1293 link_closed: Arc<Mutex<Vec<TypedLinkId>>>,
1294 remote_identified: Arc<Mutex<Vec<(TypedLinkId, IdentityHash)>>>,
1295 resources_received: Arc<Mutex<Vec<(TypedLinkId, Vec<u8>)>>>,
1296 resource_completed: Arc<Mutex<Vec<TypedLinkId>>>,
1297 resource_failed: Arc<Mutex<Vec<(TypedLinkId, String)>>>,
1298 channel_messages: Arc<Mutex<Vec<(TypedLinkId, u16, Vec<u8>)>>>,
1299 link_data: Arc<Mutex<Vec<(TypedLinkId, u8, Vec<u8>)>>>,
1300 responses: Arc<Mutex<Vec<(TypedLinkId, [u8; 16], Vec<u8>)>>>,
1301 proofs: Arc<Mutex<Vec<(DestHash, PacketHash, f64)>>>,
1302 proof_requested: Arc<Mutex<Vec<(DestHash, PacketHash)>>>,
1303 }
1304
1305 impl MockCallbacks {
1306 fn new() -> (
1307 Self,
1308 Arc<Mutex<Vec<(DestHash, u8)>>>,
1309 Arc<Mutex<Vec<(DestHash, u8)>>>,
1310 Arc<Mutex<Vec<DestHash>>>,
1311 Arc<Mutex<Vec<InterfaceId>>>,
1312 Arc<Mutex<Vec<InterfaceId>>>,
1313 ) {
1314 let announces = Arc::new(Mutex::new(Vec::new()));
1315 let paths = Arc::new(Mutex::new(Vec::new()));
1316 let deliveries = Arc::new(Mutex::new(Vec::new()));
1317 let iface_ups = Arc::new(Mutex::new(Vec::new()));
1318 let iface_downs = Arc::new(Mutex::new(Vec::new()));
1319 (
1320 MockCallbacks {
1321 announces: announces.clone(),
1322 paths: paths.clone(),
1323 deliveries: deliveries.clone(),
1324 iface_ups: iface_ups.clone(),
1325 iface_downs: iface_downs.clone(),
1326 link_established: Arc::new(Mutex::new(Vec::new())),
1327 link_closed: Arc::new(Mutex::new(Vec::new())),
1328 remote_identified: Arc::new(Mutex::new(Vec::new())),
1329 resources_received: Arc::new(Mutex::new(Vec::new())),
1330 resource_completed: Arc::new(Mutex::new(Vec::new())),
1331 resource_failed: Arc::new(Mutex::new(Vec::new())),
1332 channel_messages: Arc::new(Mutex::new(Vec::new())),
1333 link_data: Arc::new(Mutex::new(Vec::new())),
1334 responses: Arc::new(Mutex::new(Vec::new())),
1335 proofs: Arc::new(Mutex::new(Vec::new())),
1336 proof_requested: Arc::new(Mutex::new(Vec::new())),
1337 },
1338 announces,
1339 paths,
1340 deliveries,
1341 iface_ups,
1342 iface_downs,
1343 )
1344 }
1345
1346 fn with_link_tracking() -> (
1347 Self,
1348 Arc<Mutex<Vec<(TypedLinkId, f64, bool)>>>,
1349 Arc<Mutex<Vec<TypedLinkId>>>,
1350 Arc<Mutex<Vec<(TypedLinkId, IdentityHash)>>>,
1351 ) {
1352 let link_established = Arc::new(Mutex::new(Vec::new()));
1353 let link_closed = Arc::new(Mutex::new(Vec::new()));
1354 let remote_identified = Arc::new(Mutex::new(Vec::new()));
1355 (
1356 MockCallbacks {
1357 announces: Arc::new(Mutex::new(Vec::new())),
1358 paths: Arc::new(Mutex::new(Vec::new())),
1359 deliveries: Arc::new(Mutex::new(Vec::new())),
1360 iface_ups: Arc::new(Mutex::new(Vec::new())),
1361 iface_downs: Arc::new(Mutex::new(Vec::new())),
1362 link_established: link_established.clone(),
1363 link_closed: link_closed.clone(),
1364 remote_identified: remote_identified.clone(),
1365 resources_received: Arc::new(Mutex::new(Vec::new())),
1366 resource_completed: Arc::new(Mutex::new(Vec::new())),
1367 resource_failed: Arc::new(Mutex::new(Vec::new())),
1368 channel_messages: Arc::new(Mutex::new(Vec::new())),
1369 link_data: Arc::new(Mutex::new(Vec::new())),
1370 responses: Arc::new(Mutex::new(Vec::new())),
1371 proofs: Arc::new(Mutex::new(Vec::new())),
1372 proof_requested: Arc::new(Mutex::new(Vec::new())),
1373 },
1374 link_established,
1375 link_closed,
1376 remote_identified,
1377 )
1378 }
1379 }
1380
1381 impl Callbacks for MockCallbacks {
1382 fn on_announce(&mut self, announced: crate::destination::AnnouncedIdentity) {
1383 self.announces.lock().unwrap().push((announced.dest_hash, announced.hops));
1384 }
1385
1386 fn on_path_updated(&mut self, dest_hash: DestHash, hops: u8) {
1387 self.paths.lock().unwrap().push((dest_hash, hops));
1388 }
1389
1390 fn on_local_delivery(&mut self, dest_hash: DestHash, _raw: Vec<u8>, _packet_hash: PacketHash) {
1391 self.deliveries.lock().unwrap().push(dest_hash);
1392 }
1393
1394 fn on_interface_up(&mut self, id: InterfaceId) {
1395 self.iface_ups.lock().unwrap().push(id);
1396 }
1397
1398 fn on_interface_down(&mut self, id: InterfaceId) {
1399 self.iface_downs.lock().unwrap().push(id);
1400 }
1401
1402 fn on_link_established(&mut self, link_id: TypedLinkId, rtt: f64, is_initiator: bool) {
1403 self.link_established.lock().unwrap().push((link_id, rtt, is_initiator));
1404 }
1405
1406 fn on_link_closed(&mut self, link_id: TypedLinkId, _reason: Option<rns_core::link::TeardownReason>) {
1407 self.link_closed.lock().unwrap().push(link_id);
1408 }
1409
1410 fn on_remote_identified(&mut self, link_id: TypedLinkId, identity_hash: IdentityHash, _public_key: [u8; 64]) {
1411 self.remote_identified.lock().unwrap().push((link_id, identity_hash));
1412 }
1413
1414 fn on_resource_received(&mut self, link_id: TypedLinkId, data: Vec<u8>, _metadata: Option<Vec<u8>>) {
1415 self.resources_received.lock().unwrap().push((link_id, data));
1416 }
1417
1418 fn on_resource_completed(&mut self, link_id: TypedLinkId) {
1419 self.resource_completed.lock().unwrap().push(link_id);
1420 }
1421
1422 fn on_resource_failed(&mut self, link_id: TypedLinkId, error: String) {
1423 self.resource_failed.lock().unwrap().push((link_id, error));
1424 }
1425
1426 fn on_channel_message(&mut self, link_id: TypedLinkId, msgtype: u16, payload: Vec<u8>) {
1427 self.channel_messages.lock().unwrap().push((link_id, msgtype, payload));
1428 }
1429
1430 fn on_link_data(&mut self, link_id: TypedLinkId, context: u8, data: Vec<u8>) {
1431 self.link_data.lock().unwrap().push((link_id, context, data));
1432 }
1433
1434 fn on_response(&mut self, link_id: TypedLinkId, request_id: [u8; 16], data: Vec<u8>) {
1435 self.responses.lock().unwrap().push((link_id, request_id, data));
1436 }
1437
1438 fn on_proof(&mut self, dest_hash: DestHash, packet_hash: PacketHash, rtt: f64) {
1439 self.proofs.lock().unwrap().push((dest_hash, packet_hash, rtt));
1440 }
1441
1442 fn on_proof_requested(&mut self, dest_hash: DestHash, packet_hash: PacketHash) -> bool {
1443 self.proof_requested.lock().unwrap().push((dest_hash, packet_hash));
1444 true
1445 }
1446 }
1447
1448 fn make_interface_info(id: u64) -> InterfaceInfo {
1449 InterfaceInfo {
1450 id: InterfaceId(id),
1451 name: format!("test-{}", id),
1452 mode: constants::MODE_FULL,
1453 out_capable: true,
1454 in_capable: true,
1455 bitrate: None,
1456 announce_rate_target: None,
1457 announce_rate_grace: 0,
1458 announce_rate_penalty: 0.0,
1459 announce_cap: rns_core::constants::ANNOUNCE_CAP,
1460 is_local_client: false,
1461 wants_tunnel: false,
1462 tunnel_id: None,
1463 }
1464 }
1465
1466 fn make_entry(id: u64, writer: Box<dyn Writer>, online: bool) -> InterfaceEntry {
1467 InterfaceEntry {
1468 id: InterfaceId(id),
1469 info: make_interface_info(id),
1470 writer,
1471 online,
1472 dynamic: false,
1473 ifac: None,
1474 stats: InterfaceStats::default(),
1475 interface_type: String::new(),
1476 }
1477 }
1478
1479 fn build_announce_packet(identity: &Identity) -> Vec<u8> {
1481 let dest_hash = rns_core::destination::destination_hash(
1482 "test",
1483 &["app"],
1484 Some(identity.hash()),
1485 );
1486 let name_hash = rns_core::destination::name_hash("test", &["app"]);
1487 let random_hash = [0x42u8; 10];
1488
1489 let (announce_data, _has_ratchet) = AnnounceData::pack(
1490 identity,
1491 &dest_hash,
1492 &name_hash,
1493 &random_hash,
1494 None,
1495 None,
1496 )
1497 .unwrap();
1498
1499 let flags = PacketFlags {
1500 header_type: constants::HEADER_1,
1501 context_flag: constants::FLAG_UNSET,
1502 transport_type: constants::TRANSPORT_BROADCAST,
1503 destination_type: constants::DESTINATION_SINGLE,
1504 packet_type: constants::PACKET_TYPE_ANNOUNCE,
1505 };
1506
1507 let packet = RawPacket::pack(flags, 0, &dest_hash, None, constants::CONTEXT_NONE, &announce_data).unwrap();
1508 packet.raw
1509 }
1510
1511 #[test]
1512 fn process_inbound_frame() {
1513 let (tx, rx) = event::channel();
1514 let (cbs, announces, _, _, _, _) = MockCallbacks::new();
1515 let mut driver = Driver::new(
1516 TransportConfig { transport_enabled: false, identity_hash: None },
1517 rx,
1518 Box::new(cbs),
1519 );
1520 let info = make_interface_info(1);
1521 driver.engine.register_interface(info.clone());
1522 let (writer, _sent) = MockWriter::new();
1523 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
1524
1525 let identity = Identity::new(&mut OsRng);
1526 let announce_raw = build_announce_packet(&identity);
1527
1528 tx.send(Event::Frame { interface_id: InterfaceId(1), data: announce_raw }).unwrap();
1530 tx.send(Event::Shutdown).unwrap();
1531 driver.run();
1532
1533 assert_eq!(announces.lock().unwrap().len(), 1);
1534 }
1535
1536 #[test]
1537 fn dispatch_send() {
1538 let (tx, rx) = event::channel();
1539 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1540 let mut driver = Driver::new(
1541 TransportConfig { transport_enabled: false, identity_hash: None },
1542 rx,
1543 Box::new(cbs),
1544 );
1545 let (writer, sent) = MockWriter::new();
1546 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
1547
1548 driver.dispatch_all(vec![TransportAction::SendOnInterface {
1549 interface: InterfaceId(1),
1550 raw: vec![0x01, 0x02, 0x03],
1551 }]);
1552
1553 assert_eq!(sent.lock().unwrap().len(), 1);
1554 assert_eq!(sent.lock().unwrap()[0], vec![0x01, 0x02, 0x03]);
1555
1556 drop(tx);
1557 }
1558
1559 #[test]
1560 fn dispatch_broadcast() {
1561 let (tx, rx) = event::channel();
1562 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1563 let mut driver = Driver::new(
1564 TransportConfig { transport_enabled: false, identity_hash: None },
1565 rx,
1566 Box::new(cbs),
1567 );
1568
1569 let (w1, sent1) = MockWriter::new();
1570 let (w2, sent2) = MockWriter::new();
1571 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(w1), true));
1572 driver.interfaces.insert(InterfaceId(2), make_entry(2, Box::new(w2), true));
1573
1574 driver.dispatch_all(vec![TransportAction::BroadcastOnAllInterfaces {
1575 raw: vec![0xAA],
1576 exclude: None,
1577 }]);
1578
1579 assert_eq!(sent1.lock().unwrap().len(), 1);
1580 assert_eq!(sent2.lock().unwrap().len(), 1);
1581
1582 drop(tx);
1583 }
1584
1585 #[test]
1586 fn dispatch_broadcast_exclude() {
1587 let (tx, rx) = event::channel();
1588 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1589 let mut driver = Driver::new(
1590 TransportConfig { transport_enabled: false, identity_hash: None },
1591 rx,
1592 Box::new(cbs),
1593 );
1594
1595 let (w1, sent1) = MockWriter::new();
1596 let (w2, sent2) = MockWriter::new();
1597 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(w1), true));
1598 driver.interfaces.insert(InterfaceId(2), make_entry(2, Box::new(w2), true));
1599
1600 driver.dispatch_all(vec![TransportAction::BroadcastOnAllInterfaces {
1601 raw: vec![0xBB],
1602 exclude: Some(InterfaceId(1)),
1603 }]);
1604
1605 assert_eq!(sent1.lock().unwrap().len(), 0); assert_eq!(sent2.lock().unwrap().len(), 1);
1607
1608 drop(tx);
1609 }
1610
1611 #[test]
1612 fn tick_event() {
1613 let (tx, rx) = event::channel();
1614 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1615 let mut driver = Driver::new(
1616 TransportConfig { transport_enabled: true, identity_hash: Some([0x42; 16]) },
1617 rx,
1618 Box::new(cbs),
1619 );
1620 let info = make_interface_info(1);
1621 driver.engine.register_interface(info.clone());
1622 let (writer, _sent) = MockWriter::new();
1623 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
1624
1625 tx.send(Event::Tick).unwrap();
1627 tx.send(Event::Shutdown).unwrap();
1628 driver.run();
1629 }
1631
1632 #[test]
1633 fn shutdown_event() {
1634 let (tx, rx) = event::channel();
1635 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1636 let mut driver = Driver::new(
1637 TransportConfig { transport_enabled: false, identity_hash: None },
1638 rx,
1639 Box::new(cbs),
1640 );
1641
1642 tx.send(Event::Shutdown).unwrap();
1643 driver.run(); }
1645
1646 #[test]
1647 fn announce_callback() {
1648 let (tx, rx) = event::channel();
1649 let (cbs, announces, paths, _, _, _) = MockCallbacks::new();
1650 let mut driver = Driver::new(
1651 TransportConfig { transport_enabled: false, identity_hash: None },
1652 rx,
1653 Box::new(cbs),
1654 );
1655 let info = make_interface_info(1);
1656 driver.engine.register_interface(info.clone());
1657 let (writer, _sent) = MockWriter::new();
1658 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
1659
1660 let identity = Identity::new(&mut OsRng);
1661 let announce_raw = build_announce_packet(&identity);
1662
1663 tx.send(Event::Frame { interface_id: InterfaceId(1), data: announce_raw }).unwrap();
1664 tx.send(Event::Shutdown).unwrap();
1665 driver.run();
1666
1667 let ann = announces.lock().unwrap();
1668 assert_eq!(ann.len(), 1);
1669 assert_eq!(ann[0].1, 1);
1671
1672 let p = paths.lock().unwrap();
1673 assert_eq!(p.len(), 1);
1674 }
1675
1676 #[test]
1677 fn dispatch_skips_offline_interface() {
1678 let (tx, rx) = event::channel();
1679 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1680 let mut driver = Driver::new(
1681 TransportConfig { transport_enabled: false, identity_hash: None },
1682 rx,
1683 Box::new(cbs),
1684 );
1685
1686 let (w1, sent1) = MockWriter::new();
1687 let (w2, sent2) = MockWriter::new();
1688 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(w1), false)); driver.interfaces.insert(InterfaceId(2), make_entry(2, Box::new(w2), true));
1690
1691 driver.dispatch_all(vec![TransportAction::SendOnInterface {
1693 interface: InterfaceId(1),
1694 raw: vec![0x01],
1695 }]);
1696 assert_eq!(sent1.lock().unwrap().len(), 0);
1697
1698 driver.dispatch_all(vec![TransportAction::BroadcastOnAllInterfaces {
1700 raw: vec![0x02],
1701 exclude: None,
1702 }]);
1703 assert_eq!(sent1.lock().unwrap().len(), 0); assert_eq!(sent2.lock().unwrap().len(), 1);
1705
1706 drop(tx);
1707 }
1708
1709 #[test]
1710 fn interface_up_refreshes_writer() {
1711 let (tx, rx) = event::channel();
1712 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1713 let mut driver = Driver::new(
1714 TransportConfig { transport_enabled: false, identity_hash: None },
1715 rx,
1716 Box::new(cbs),
1717 );
1718
1719 let (w_old, sent_old) = MockWriter::new();
1720 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(w_old), false));
1721
1722 let (w_new, sent_new) = MockWriter::new();
1724 tx.send(Event::InterfaceUp(InterfaceId(1), Some(Box::new(w_new)), None)).unwrap();
1725 tx.send(Event::Shutdown).unwrap();
1726 driver.run();
1727
1728 assert!(driver.interfaces[&InterfaceId(1)].online);
1730
1731 driver.dispatch_all(vec![TransportAction::SendOnInterface {
1733 interface: InterfaceId(1),
1734 raw: vec![0xFF],
1735 }]);
1736
1737 assert_eq!(sent_old.lock().unwrap().len(), 0);
1739 assert_eq!(sent_new.lock().unwrap().len(), 1);
1741 assert_eq!(sent_new.lock().unwrap()[0], vec![0xFF]);
1742
1743 drop(tx);
1744 }
1745
1746 #[test]
1747 fn dynamic_interface_register() {
1748 let (tx, rx) = event::channel();
1749 let (cbs, _, _, _, iface_ups, _) = MockCallbacks::new();
1750 let mut driver = Driver::new(
1751 TransportConfig { transport_enabled: false, identity_hash: None },
1752 rx,
1753 Box::new(cbs),
1754 );
1755
1756 let info = make_interface_info(100);
1757 let (writer, sent) = MockWriter::new();
1758
1759 tx.send(Event::InterfaceUp(
1761 InterfaceId(100),
1762 Some(Box::new(writer)),
1763 Some(info),
1764 ))
1765 .unwrap();
1766 tx.send(Event::Shutdown).unwrap();
1767 driver.run();
1768
1769 assert!(driver.interfaces.contains_key(&InterfaceId(100)));
1771 assert!(driver.interfaces[&InterfaceId(100)].online);
1772 assert!(driver.interfaces[&InterfaceId(100)].dynamic);
1773
1774 assert_eq!(iface_ups.lock().unwrap().len(), 1);
1776 assert_eq!(iface_ups.lock().unwrap()[0], InterfaceId(100));
1777
1778 driver.dispatch_all(vec![TransportAction::SendOnInterface {
1780 interface: InterfaceId(100),
1781 raw: vec![0x42],
1782 }]);
1783 assert_eq!(sent.lock().unwrap().len(), 1);
1784
1785 drop(tx);
1786 }
1787
1788 #[test]
1789 fn dynamic_interface_deregister() {
1790 let (tx, rx) = event::channel();
1791 let (cbs, _, _, _, _, iface_downs) = MockCallbacks::new();
1792 let mut driver = Driver::new(
1793 TransportConfig { transport_enabled: false, identity_hash: None },
1794 rx,
1795 Box::new(cbs),
1796 );
1797
1798 let info = make_interface_info(200);
1800 driver.engine.register_interface(info.clone());
1801 let (writer, _sent) = MockWriter::new();
1802 driver.interfaces.insert(InterfaceId(200), InterfaceEntry {
1803 id: InterfaceId(200),
1804 info,
1805 writer: Box::new(writer),
1806 online: true,
1807 dynamic: true,
1808 ifac: None,
1809 stats: InterfaceStats::default(),
1810 interface_type: String::new(),
1811 });
1812
1813 tx.send(Event::InterfaceDown(InterfaceId(200))).unwrap();
1815 tx.send(Event::Shutdown).unwrap();
1816 driver.run();
1817
1818 assert!(!driver.interfaces.contains_key(&InterfaceId(200)));
1819 assert_eq!(iface_downs.lock().unwrap().len(), 1);
1820 assert_eq!(iface_downs.lock().unwrap()[0], InterfaceId(200));
1821 }
1822
1823 #[test]
1824 fn interface_callbacks_fire() {
1825 let (tx, rx) = event::channel();
1826 let (cbs, _, _, _, iface_ups, iface_downs) = MockCallbacks::new();
1827 let mut driver = Driver::new(
1828 TransportConfig { transport_enabled: false, identity_hash: None },
1829 rx,
1830 Box::new(cbs),
1831 );
1832
1833 let (writer, _) = MockWriter::new();
1835 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), false));
1836
1837 tx.send(Event::InterfaceUp(InterfaceId(1), None, None)).unwrap();
1838 tx.send(Event::InterfaceDown(InterfaceId(1))).unwrap();
1839 tx.send(Event::Shutdown).unwrap();
1840 driver.run();
1841
1842 assert_eq!(iface_ups.lock().unwrap().len(), 1);
1843 assert_eq!(iface_downs.lock().unwrap().len(), 1);
1844 assert!(driver.interfaces.contains_key(&InterfaceId(1)));
1846 assert!(!driver.interfaces[&InterfaceId(1)].online);
1847 }
1848
1849 #[test]
1854 fn frame_updates_rx_stats() {
1855 let (tx, rx) = event::channel();
1856 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1857 let mut driver = Driver::new(
1858 TransportConfig { transport_enabled: false, identity_hash: None },
1859 rx,
1860 Box::new(cbs),
1861 );
1862 let info = make_interface_info(1);
1863 driver.engine.register_interface(info.clone());
1864 let (writer, _sent) = MockWriter::new();
1865 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
1866
1867 let identity = Identity::new(&mut OsRng);
1868 let announce_raw = build_announce_packet(&identity);
1869 let announce_len = announce_raw.len() as u64;
1870
1871 tx.send(Event::Frame { interface_id: InterfaceId(1), data: announce_raw }).unwrap();
1872 tx.send(Event::Shutdown).unwrap();
1873 driver.run();
1874
1875 let stats = &driver.interfaces[&InterfaceId(1)].stats;
1876 assert_eq!(stats.rxb, announce_len);
1877 assert_eq!(stats.rx_packets, 1);
1878 }
1879
1880 #[test]
1881 fn send_updates_tx_stats() {
1882 let (tx, rx) = event::channel();
1883 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1884 let mut driver = Driver::new(
1885 TransportConfig { transport_enabled: false, identity_hash: None },
1886 rx,
1887 Box::new(cbs),
1888 );
1889 let (writer, _sent) = MockWriter::new();
1890 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
1891
1892 driver.dispatch_all(vec![TransportAction::SendOnInterface {
1893 interface: InterfaceId(1),
1894 raw: vec![0x01, 0x02, 0x03],
1895 }]);
1896
1897 let stats = &driver.interfaces[&InterfaceId(1)].stats;
1898 assert_eq!(stats.txb, 3);
1899 assert_eq!(stats.tx_packets, 1);
1900
1901 drop(tx);
1902 }
1903
1904 #[test]
1905 fn broadcast_updates_tx_stats() {
1906 let (tx, rx) = event::channel();
1907 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1908 let mut driver = Driver::new(
1909 TransportConfig { transport_enabled: false, identity_hash: None },
1910 rx,
1911 Box::new(cbs),
1912 );
1913 let (w1, _s1) = MockWriter::new();
1914 let (w2, _s2) = MockWriter::new();
1915 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(w1), true));
1916 driver.interfaces.insert(InterfaceId(2), make_entry(2, Box::new(w2), true));
1917
1918 driver.dispatch_all(vec![TransportAction::BroadcastOnAllInterfaces {
1919 raw: vec![0xAA, 0xBB],
1920 exclude: None,
1921 }]);
1922
1923 assert_eq!(driver.interfaces[&InterfaceId(1)].stats.txb, 2);
1925 assert_eq!(driver.interfaces[&InterfaceId(1)].stats.tx_packets, 1);
1926 assert_eq!(driver.interfaces[&InterfaceId(2)].stats.txb, 2);
1927 assert_eq!(driver.interfaces[&InterfaceId(2)].stats.tx_packets, 1);
1928
1929 drop(tx);
1930 }
1931
1932 #[test]
1933 fn query_interface_stats() {
1934 let (tx, rx) = event::channel();
1935 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1936 let mut driver = Driver::new(
1937 TransportConfig { transport_enabled: true, identity_hash: Some([0x42; 16]) },
1938 rx,
1939 Box::new(cbs),
1940 );
1941 let (writer, _sent) = MockWriter::new();
1942 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
1943
1944 let (resp_tx, resp_rx) = mpsc::channel();
1945 tx.send(Event::Query(QueryRequest::InterfaceStats, resp_tx)).unwrap();
1946 tx.send(Event::Shutdown).unwrap();
1947 driver.run();
1948
1949 let resp = resp_rx.recv().unwrap();
1950 match resp {
1951 QueryResponse::InterfaceStats(stats) => {
1952 assert_eq!(stats.interfaces.len(), 1);
1953 assert_eq!(stats.interfaces[0].name, "test-1");
1954 assert!(stats.interfaces[0].status);
1955 assert_eq!(stats.transport_id, Some([0x42; 16]));
1956 assert!(stats.transport_enabled);
1957 }
1958 _ => panic!("unexpected response"),
1959 }
1960 }
1961
1962 #[test]
1963 fn query_path_table() {
1964 let (tx, rx) = event::channel();
1965 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1966 let mut driver = Driver::new(
1967 TransportConfig { transport_enabled: false, identity_hash: None },
1968 rx,
1969 Box::new(cbs),
1970 );
1971 let info = make_interface_info(1);
1972 driver.engine.register_interface(info);
1973 let (writer, _sent) = MockWriter::new();
1974 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
1975
1976 let identity = Identity::new(&mut OsRng);
1978 let announce_raw = build_announce_packet(&identity);
1979 tx.send(Event::Frame { interface_id: InterfaceId(1), data: announce_raw }).unwrap();
1980
1981 let (resp_tx, resp_rx) = mpsc::channel();
1982 tx.send(Event::Query(QueryRequest::PathTable { max_hops: None }, resp_tx)).unwrap();
1983 tx.send(Event::Shutdown).unwrap();
1984 driver.run();
1985
1986 let resp = resp_rx.recv().unwrap();
1987 match resp {
1988 QueryResponse::PathTable(entries) => {
1989 assert_eq!(entries.len(), 1);
1990 assert_eq!(entries[0].hops, 1);
1991 }
1992 _ => panic!("unexpected response"),
1993 }
1994 }
1995
1996 #[test]
1997 fn query_drop_path() {
1998 let (tx, rx) = event::channel();
1999 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2000 let mut driver = Driver::new(
2001 TransportConfig { transport_enabled: false, identity_hash: None },
2002 rx,
2003 Box::new(cbs),
2004 );
2005 let info = make_interface_info(1);
2006 driver.engine.register_interface(info);
2007 let (writer, _sent) = MockWriter::new();
2008 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2009
2010 let identity = Identity::new(&mut OsRng);
2012 let announce_raw = build_announce_packet(&identity);
2013 let dest_hash = rns_core::destination::destination_hash(
2014 "test", &["app"], Some(identity.hash()),
2015 );
2016
2017 tx.send(Event::Frame { interface_id: InterfaceId(1), data: announce_raw }).unwrap();
2018
2019 let (resp_tx, resp_rx) = mpsc::channel();
2020 tx.send(Event::Query(QueryRequest::DropPath { dest_hash }, resp_tx)).unwrap();
2021 tx.send(Event::Shutdown).unwrap();
2022 driver.run();
2023
2024 let resp = resp_rx.recv().unwrap();
2025 match resp {
2026 QueryResponse::DropPath(dropped) => {
2027 assert!(dropped);
2028 }
2029 _ => panic!("unexpected response"),
2030 }
2031 }
2032
2033 #[test]
2034 fn send_outbound_event() {
2035 let (tx, rx) = event::channel();
2036 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2037 let mut driver = Driver::new(
2038 TransportConfig { transport_enabled: false, identity_hash: None },
2039 rx,
2040 Box::new(cbs),
2041 );
2042 let (writer, sent) = MockWriter::new();
2043 let info = make_interface_info(1);
2044 driver.engine.register_interface(info);
2045 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2046
2047 let dest = [0xAA; 16];
2049 let flags = PacketFlags {
2050 header_type: constants::HEADER_1,
2051 context_flag: constants::FLAG_UNSET,
2052 transport_type: constants::TRANSPORT_BROADCAST,
2053 destination_type: constants::DESTINATION_PLAIN,
2054 packet_type: constants::PACKET_TYPE_DATA,
2055 };
2056 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, b"hello").unwrap();
2057
2058 tx.send(Event::SendOutbound {
2059 raw: packet.raw,
2060 dest_type: constants::DESTINATION_PLAIN,
2061 attached_interface: None,
2062 }).unwrap();
2063 tx.send(Event::Shutdown).unwrap();
2064 driver.run();
2065
2066 assert_eq!(sent.lock().unwrap().len(), 1);
2068 }
2069
2070 #[test]
2071 fn register_destination_and_deliver() {
2072 let (tx, rx) = event::channel();
2073 let (cbs, _, _, deliveries, _, _) = MockCallbacks::new();
2074 let mut driver = Driver::new(
2075 TransportConfig { transport_enabled: false, identity_hash: None },
2076 rx,
2077 Box::new(cbs),
2078 );
2079 let info = make_interface_info(1);
2080 driver.engine.register_interface(info);
2081 let (writer, _sent) = MockWriter::new();
2082 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2083
2084 let dest = [0xBB; 16];
2085
2086 tx.send(Event::RegisterDestination {
2088 dest_hash: dest,
2089 dest_type: constants::DESTINATION_SINGLE,
2090 }).unwrap();
2091
2092 let flags = PacketFlags {
2093 header_type: constants::HEADER_1,
2094 context_flag: constants::FLAG_UNSET,
2095 transport_type: constants::TRANSPORT_BROADCAST,
2096 destination_type: constants::DESTINATION_SINGLE,
2097 packet_type: constants::PACKET_TYPE_DATA,
2098 };
2099 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, b"data").unwrap();
2100 tx.send(Event::Frame { interface_id: InterfaceId(1), data: packet.raw }).unwrap();
2101 tx.send(Event::Shutdown).unwrap();
2102 driver.run();
2103
2104 assert_eq!(deliveries.lock().unwrap().len(), 1);
2105 assert_eq!(deliveries.lock().unwrap()[0], DestHash(dest));
2106 }
2107
2108 #[test]
2109 fn query_transport_identity() {
2110 let (tx, rx) = event::channel();
2111 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2112 let mut driver = Driver::new(
2113 TransportConfig { transport_enabled: true, identity_hash: Some([0xAA; 16]) },
2114 rx,
2115 Box::new(cbs),
2116 );
2117
2118 let (resp_tx, resp_rx) = mpsc::channel();
2119 tx.send(Event::Query(QueryRequest::TransportIdentity, resp_tx)).unwrap();
2120 tx.send(Event::Shutdown).unwrap();
2121 driver.run();
2122
2123 match resp_rx.recv().unwrap() {
2124 QueryResponse::TransportIdentity(Some(hash)) => {
2125 assert_eq!(hash, [0xAA; 16]);
2126 }
2127 _ => panic!("unexpected response"),
2128 }
2129 }
2130
2131 #[test]
2132 fn query_link_count() {
2133 let (tx, rx) = event::channel();
2134 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2135 let mut driver = Driver::new(
2136 TransportConfig { transport_enabled: false, identity_hash: None },
2137 rx,
2138 Box::new(cbs),
2139 );
2140
2141 let (resp_tx, resp_rx) = mpsc::channel();
2142 tx.send(Event::Query(QueryRequest::LinkCount, resp_tx)).unwrap();
2143 tx.send(Event::Shutdown).unwrap();
2144 driver.run();
2145
2146 match resp_rx.recv().unwrap() {
2147 QueryResponse::LinkCount(count) => assert_eq!(count, 0),
2148 _ => panic!("unexpected response"),
2149 }
2150 }
2151
2152 #[test]
2153 fn query_rate_table() {
2154 let (tx, rx) = event::channel();
2155 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2156 let mut driver = Driver::new(
2157 TransportConfig { transport_enabled: false, identity_hash: None },
2158 rx,
2159 Box::new(cbs),
2160 );
2161
2162 let (resp_tx, resp_rx) = mpsc::channel();
2163 tx.send(Event::Query(QueryRequest::RateTable, resp_tx)).unwrap();
2164 tx.send(Event::Shutdown).unwrap();
2165 driver.run();
2166
2167 match resp_rx.recv().unwrap() {
2168 QueryResponse::RateTable(entries) => assert!(entries.is_empty()),
2169 _ => panic!("unexpected response"),
2170 }
2171 }
2172
2173 #[test]
2174 fn query_next_hop() {
2175 let (tx, rx) = event::channel();
2176 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2177 let mut driver = Driver::new(
2178 TransportConfig { transport_enabled: false, identity_hash: None },
2179 rx,
2180 Box::new(cbs),
2181 );
2182
2183 let dest = [0xBB; 16];
2184 let (resp_tx, resp_rx) = mpsc::channel();
2185 tx.send(Event::Query(QueryRequest::NextHop { dest_hash: dest }, resp_tx)).unwrap();
2186 tx.send(Event::Shutdown).unwrap();
2187 driver.run();
2188
2189 match resp_rx.recv().unwrap() {
2190 QueryResponse::NextHop(None) => {}
2191 _ => panic!("unexpected response"),
2192 }
2193 }
2194
2195 #[test]
2196 fn query_next_hop_if_name() {
2197 let (tx, rx) = event::channel();
2198 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2199 let mut driver = Driver::new(
2200 TransportConfig { transport_enabled: false, identity_hash: None },
2201 rx,
2202 Box::new(cbs),
2203 );
2204
2205 let dest = [0xCC; 16];
2206 let (resp_tx, resp_rx) = mpsc::channel();
2207 tx.send(Event::Query(QueryRequest::NextHopIfName { dest_hash: dest }, resp_tx)).unwrap();
2208 tx.send(Event::Shutdown).unwrap();
2209 driver.run();
2210
2211 match resp_rx.recv().unwrap() {
2212 QueryResponse::NextHopIfName(None) => {}
2213 _ => panic!("unexpected response"),
2214 }
2215 }
2216
2217 #[test]
2218 fn query_drop_all_via() {
2219 let (tx, rx) = event::channel();
2220 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2221 let mut driver = Driver::new(
2222 TransportConfig { transport_enabled: false, identity_hash: None },
2223 rx,
2224 Box::new(cbs),
2225 );
2226
2227 let transport = [0xDD; 16];
2228 let (resp_tx, resp_rx) = mpsc::channel();
2229 tx.send(Event::Query(
2230 QueryRequest::DropAllVia { transport_hash: transport },
2231 resp_tx,
2232 )).unwrap();
2233 tx.send(Event::Shutdown).unwrap();
2234 driver.run();
2235
2236 match resp_rx.recv().unwrap() {
2237 QueryResponse::DropAllVia(count) => assert_eq!(count, 0),
2238 _ => panic!("unexpected response"),
2239 }
2240 }
2241
2242 #[test]
2243 fn query_drop_announce_queues() {
2244 let (tx, rx) = event::channel();
2245 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2246 let mut driver = Driver::new(
2247 TransportConfig { transport_enabled: false, identity_hash: None },
2248 rx,
2249 Box::new(cbs),
2250 );
2251
2252 let (resp_tx, resp_rx) = mpsc::channel();
2253 tx.send(Event::Query(QueryRequest::DropAnnounceQueues, resp_tx)).unwrap();
2254 tx.send(Event::Shutdown).unwrap();
2255 driver.run();
2256
2257 match resp_rx.recv().unwrap() {
2258 QueryResponse::DropAnnounceQueues => {}
2259 _ => panic!("unexpected response"),
2260 }
2261 }
2262
2263 #[test]
2268 fn register_link_dest_event() {
2269 let (tx, rx) = event::channel();
2270 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2271 let mut driver = Driver::new(
2272 TransportConfig { transport_enabled: false, identity_hash: None },
2273 rx,
2274 Box::new(cbs),
2275 );
2276 let info = make_interface_info(1);
2277 driver.engine.register_interface(info);
2278 let (writer, _sent) = MockWriter::new();
2279 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2280
2281 let mut rng = OsRng;
2282 let sig_prv = rns_crypto::ed25519::Ed25519PrivateKey::generate(&mut rng);
2283 let sig_pub_bytes = sig_prv.public_key().public_bytes();
2284 let sig_prv_bytes = sig_prv.private_bytes();
2285 let dest_hash = [0xDD; 16];
2286
2287 tx.send(Event::RegisterLinkDestination {
2288 dest_hash,
2289 sig_prv_bytes,
2290 sig_pub_bytes,
2291 }).unwrap();
2292 tx.send(Event::Shutdown).unwrap();
2293 driver.run();
2294
2295 assert!(driver.link_manager.is_link_destination(&dest_hash));
2297 }
2298
2299 #[test]
2300 fn create_link_event() {
2301 let (tx, rx) = event::channel();
2302 let (cbs, _link_established, _, _) = MockCallbacks::with_link_tracking();
2303 let mut driver = Driver::new(
2304 TransportConfig { transport_enabled: false, identity_hash: None },
2305 rx,
2306 Box::new(cbs),
2307 );
2308 let info = make_interface_info(1);
2309 driver.engine.register_interface(info);
2310 let (writer, _sent) = MockWriter::new();
2311 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2312
2313 let dest_hash = [0xDD; 16];
2314 let dummy_sig_pub = [0xAA; 32];
2315
2316 let (resp_tx, resp_rx) = mpsc::channel();
2317 tx.send(Event::CreateLink {
2318 dest_hash,
2319 dest_sig_pub_bytes: dummy_sig_pub,
2320 response_tx: resp_tx,
2321 }).unwrap();
2322 tx.send(Event::Shutdown).unwrap();
2323 driver.run();
2324
2325 let link_id = resp_rx.recv().unwrap();
2327 assert_ne!(link_id, [0u8; 16]);
2328
2329 assert_eq!(driver.link_manager.link_count(), 1);
2331
2332 }
2337
2338 #[test]
2339 fn deliver_local_routes_to_link_manager() {
2340 let (tx, rx) = event::channel();
2343 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2344 let mut driver = Driver::new(
2345 TransportConfig { transport_enabled: false, identity_hash: None },
2346 rx,
2347 Box::new(cbs),
2348 );
2349 let info = make_interface_info(1);
2350 driver.engine.register_interface(info);
2351 let (writer, _sent) = MockWriter::new();
2352 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2353
2354 let mut rng = OsRng;
2356 let sig_prv = rns_crypto::ed25519::Ed25519PrivateKey::generate(&mut rng);
2357 let sig_pub_bytes = sig_prv.public_key().public_bytes();
2358 let dest_hash = [0xEE; 16];
2359 driver.link_manager.register_link_destination(dest_hash, sig_prv, sig_pub_bytes);
2360
2361 assert!(driver.link_manager.is_link_destination(&dest_hash));
2365
2366 assert!(!driver.link_manager.is_link_destination(&[0xFF; 16]));
2368
2369 drop(tx);
2370 }
2371
2372 #[test]
2373 fn teardown_link_event() {
2374 let (tx, rx) = event::channel();
2375 let (cbs, _, link_closed, _) = MockCallbacks::with_link_tracking();
2376 let mut driver = Driver::new(
2377 TransportConfig { transport_enabled: false, identity_hash: None },
2378 rx,
2379 Box::new(cbs),
2380 );
2381 let info = make_interface_info(1);
2382 driver.engine.register_interface(info);
2383 let (writer, _sent) = MockWriter::new();
2384 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2385
2386 let (resp_tx, resp_rx) = mpsc::channel();
2388 tx.send(Event::CreateLink {
2389 dest_hash: [0xDD; 16],
2390 dest_sig_pub_bytes: [0xAA; 32],
2391 response_tx: resp_tx,
2392 }).unwrap();
2393 tx.send(Event::Shutdown).unwrap();
2398 driver.run();
2399
2400 let link_id = resp_rx.recv().unwrap();
2401 assert_ne!(link_id, [0u8; 16]);
2402 assert_eq!(driver.link_manager.link_count(), 1);
2403
2404 let teardown_actions = driver.link_manager.teardown_link(&link_id);
2406 driver.dispatch_link_actions(teardown_actions);
2407
2408 assert_eq!(link_closed.lock().unwrap().len(), 1);
2410 assert_eq!(link_closed.lock().unwrap()[0], TypedLinkId(link_id));
2411 }
2412
2413 #[test]
2414 fn link_count_includes_link_manager() {
2415 let (tx, rx) = event::channel();
2416 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2417 let mut driver = Driver::new(
2418 TransportConfig { transport_enabled: false, identity_hash: None },
2419 rx,
2420 Box::new(cbs),
2421 );
2422 let info = make_interface_info(1);
2423 driver.engine.register_interface(info);
2424 let (writer, _sent) = MockWriter::new();
2425 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2426
2427 let mut rng = OsRng;
2429 let dummy_sig = [0xAA; 32];
2430 driver.link_manager.create_link(&[0xDD; 16], &dummy_sig, 1, &mut rng);
2431
2432 let (resp_tx, resp_rx) = mpsc::channel();
2434 tx.send(Event::Query(QueryRequest::LinkCount, resp_tx)).unwrap();
2435 tx.send(Event::Shutdown).unwrap();
2436 driver.run();
2437
2438 match resp_rx.recv().unwrap() {
2439 QueryResponse::LinkCount(count) => assert_eq!(count, 1),
2440 _ => panic!("unexpected response"),
2441 }
2442 }
2443
2444 #[test]
2445 fn register_request_handler_event() {
2446 let (tx, rx) = event::channel();
2447 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2448 let mut driver = Driver::new(
2449 TransportConfig { transport_enabled: false, identity_hash: None },
2450 rx,
2451 Box::new(cbs),
2452 );
2453
2454 tx.send(Event::RegisterRequestHandler {
2455 path: "/status".to_string(),
2456 allowed_list: None,
2457 handler: Box::new(|_link_id, _path, _data, _remote| Some(b"OK".to_vec())),
2458 }).unwrap();
2459 tx.send(Event::Shutdown).unwrap();
2460 driver.run();
2461
2462 }
2465
2466 #[test]
2469 fn management_announces_emitted_after_delay() {
2470 let (tx, rx) = event::channel();
2471 let (cbs, announces, _, _, _, _) = MockCallbacks::new();
2472 let identity = Identity::new(&mut OsRng);
2473 let identity_hash = *identity.hash();
2474 let mut driver = Driver::new(
2475 TransportConfig { transport_enabled: true, identity_hash: Some(identity_hash) },
2476 rx,
2477 Box::new(cbs),
2478 );
2479
2480 let info = make_interface_info(1);
2482 driver.engine.register_interface(info.clone());
2483 let (writer, sent) = MockWriter::new();
2484 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2485
2486 driver.management_config.enable_remote_management = true;
2488 driver.transport_identity = Some(identity);
2489
2490 driver.started = time::now() - 10.0;
2492
2493 tx.send(Event::Tick).unwrap();
2495 tx.send(Event::Shutdown).unwrap();
2496 driver.run();
2497
2498 let sent_packets = sent.lock().unwrap();
2500 assert!(!sent_packets.is_empty(),
2501 "Management announce should be sent after startup delay");
2502 }
2503
2504 #[test]
2505 fn management_announces_not_emitted_when_disabled() {
2506 let (tx, rx) = event::channel();
2507 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2508 let identity = Identity::new(&mut OsRng);
2509 let identity_hash = *identity.hash();
2510 let mut driver = Driver::new(
2511 TransportConfig { transport_enabled: true, identity_hash: Some(identity_hash) },
2512 rx,
2513 Box::new(cbs),
2514 );
2515
2516 let info = make_interface_info(1);
2517 driver.engine.register_interface(info.clone());
2518 let (writer, sent) = MockWriter::new();
2519 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2520
2521 driver.transport_identity = Some(identity);
2523 driver.started = time::now() - 10.0;
2524
2525 tx.send(Event::Tick).unwrap();
2526 tx.send(Event::Shutdown).unwrap();
2527 driver.run();
2528
2529 let sent_packets = sent.lock().unwrap();
2531 assert!(sent_packets.is_empty(),
2532 "No announces should be sent when management is disabled");
2533 }
2534
2535 #[test]
2536 fn management_announces_not_emitted_before_delay() {
2537 let (tx, rx) = event::channel();
2538 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2539 let identity = Identity::new(&mut OsRng);
2540 let identity_hash = *identity.hash();
2541 let mut driver = Driver::new(
2542 TransportConfig { transport_enabled: true, identity_hash: Some(identity_hash) },
2543 rx,
2544 Box::new(cbs),
2545 );
2546
2547 let info = make_interface_info(1);
2548 driver.engine.register_interface(info.clone());
2549 let (writer, sent) = MockWriter::new();
2550 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2551
2552 driver.management_config.enable_remote_management = true;
2553 driver.transport_identity = Some(identity);
2554 driver.started = time::now();
2556
2557 tx.send(Event::Tick).unwrap();
2558 tx.send(Event::Shutdown).unwrap();
2559 driver.run();
2560
2561 let sent_packets = sent.lock().unwrap();
2562 assert!(sent_packets.is_empty(),
2563 "No announces before startup delay");
2564 }
2565
2566 #[test]
2571 fn announce_received_populates_known_destinations() {
2572 let (tx, rx) = event::channel();
2573 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2574 let mut driver = Driver::new(
2575 TransportConfig { transport_enabled: false, identity_hash: None },
2576 rx,
2577 Box::new(cbs),
2578 );
2579 let info = make_interface_info(1);
2580 driver.engine.register_interface(info);
2581 let (writer, _sent) = MockWriter::new();
2582 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2583
2584 let identity = Identity::new(&mut OsRng);
2585 let announce_raw = build_announce_packet(&identity);
2586
2587 let dest_hash = rns_core::destination::destination_hash(
2588 "test", &["app"], Some(identity.hash()),
2589 );
2590
2591 tx.send(Event::Frame { interface_id: InterfaceId(1), data: announce_raw }).unwrap();
2592 tx.send(Event::Shutdown).unwrap();
2593 driver.run();
2594
2595 assert!(driver.known_destinations.contains_key(&dest_hash));
2597 let recalled = &driver.known_destinations[&dest_hash];
2598 assert_eq!(recalled.dest_hash.0, dest_hash);
2599 assert_eq!(recalled.identity_hash.0, *identity.hash());
2600 assert_eq!(&recalled.public_key, &identity.get_public_key().unwrap());
2601 assert_eq!(recalled.hops, 1);
2602 }
2603
2604 #[test]
2605 fn query_has_path() {
2606 let (tx, rx) = event::channel();
2607 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2608 let mut driver = Driver::new(
2609 TransportConfig { transport_enabled: false, identity_hash: None },
2610 rx,
2611 Box::new(cbs),
2612 );
2613 let info = make_interface_info(1);
2614 driver.engine.register_interface(info);
2615 let (writer, _sent) = MockWriter::new();
2616 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2617
2618 let (resp_tx, resp_rx) = mpsc::channel();
2620 tx.send(Event::Query(QueryRequest::HasPath { dest_hash: [0xAA; 16] }, resp_tx)).unwrap();
2621
2622 let identity = Identity::new(&mut OsRng);
2624 let announce_raw = build_announce_packet(&identity);
2625 let dest_hash = rns_core::destination::destination_hash(
2626 "test", &["app"], Some(identity.hash()),
2627 );
2628 tx.send(Event::Frame { interface_id: InterfaceId(1), data: announce_raw }).unwrap();
2629
2630 let (resp_tx2, resp_rx2) = mpsc::channel();
2631 tx.send(Event::Query(QueryRequest::HasPath { dest_hash }, resp_tx2)).unwrap();
2632
2633 tx.send(Event::Shutdown).unwrap();
2634 driver.run();
2635
2636 match resp_rx.recv().unwrap() {
2638 QueryResponse::HasPath(false) => {}
2639 other => panic!("expected HasPath(false), got {:?}", other),
2640 }
2641
2642 match resp_rx2.recv().unwrap() {
2644 QueryResponse::HasPath(true) => {}
2645 other => panic!("expected HasPath(true), got {:?}", other),
2646 }
2647 }
2648
2649 #[test]
2650 fn query_hops_to() {
2651 let (tx, rx) = event::channel();
2652 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2653 let mut driver = Driver::new(
2654 TransportConfig { transport_enabled: false, identity_hash: None },
2655 rx,
2656 Box::new(cbs),
2657 );
2658 let info = make_interface_info(1);
2659 driver.engine.register_interface(info);
2660 let (writer, _sent) = MockWriter::new();
2661 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2662
2663 let identity = Identity::new(&mut OsRng);
2665 let announce_raw = build_announce_packet(&identity);
2666 let dest_hash = rns_core::destination::destination_hash(
2667 "test", &["app"], Some(identity.hash()),
2668 );
2669
2670 tx.send(Event::Frame { interface_id: InterfaceId(1), data: announce_raw }).unwrap();
2671
2672 let (resp_tx, resp_rx) = mpsc::channel();
2673 tx.send(Event::Query(QueryRequest::HopsTo { dest_hash }, resp_tx)).unwrap();
2674 tx.send(Event::Shutdown).unwrap();
2675 driver.run();
2676
2677 match resp_rx.recv().unwrap() {
2678 QueryResponse::HopsTo(Some(1)) => {}
2679 other => panic!("expected HopsTo(Some(1)), got {:?}", other),
2680 }
2681 }
2682
2683 #[test]
2684 fn query_recall_identity() {
2685 let (tx, rx) = event::channel();
2686 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2687 let mut driver = Driver::new(
2688 TransportConfig { transport_enabled: false, identity_hash: None },
2689 rx,
2690 Box::new(cbs),
2691 );
2692 let info = make_interface_info(1);
2693 driver.engine.register_interface(info);
2694 let (writer, _sent) = MockWriter::new();
2695 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2696
2697 let identity = Identity::new(&mut OsRng);
2698 let announce_raw = build_announce_packet(&identity);
2699 let dest_hash = rns_core::destination::destination_hash(
2700 "test", &["app"], Some(identity.hash()),
2701 );
2702
2703 tx.send(Event::Frame { interface_id: InterfaceId(1), data: announce_raw }).unwrap();
2704
2705 let (resp_tx, resp_rx) = mpsc::channel();
2707 tx.send(Event::Query(QueryRequest::RecallIdentity { dest_hash }, resp_tx)).unwrap();
2708
2709 let (resp_tx2, resp_rx2) = mpsc::channel();
2711 tx.send(Event::Query(QueryRequest::RecallIdentity { dest_hash: [0xFF; 16] }, resp_tx2)).unwrap();
2712
2713 tx.send(Event::Shutdown).unwrap();
2714 driver.run();
2715
2716 match resp_rx.recv().unwrap() {
2717 QueryResponse::RecallIdentity(Some(recalled)) => {
2718 assert_eq!(recalled.dest_hash.0, dest_hash);
2719 assert_eq!(recalled.identity_hash.0, *identity.hash());
2720 assert_eq!(recalled.public_key, identity.get_public_key().unwrap());
2721 assert_eq!(recalled.hops, 1);
2722 }
2723 other => panic!("expected RecallIdentity(Some(..)), got {:?}", other),
2724 }
2725
2726 match resp_rx2.recv().unwrap() {
2727 QueryResponse::RecallIdentity(None) => {}
2728 other => panic!("expected RecallIdentity(None), got {:?}", other),
2729 }
2730 }
2731
2732 #[test]
2733 fn request_path_sends_packet() {
2734 let (tx, rx) = event::channel();
2735 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2736 let mut driver = Driver::new(
2737 TransportConfig { transport_enabled: false, identity_hash: None },
2738 rx,
2739 Box::new(cbs),
2740 );
2741 let info = make_interface_info(1);
2742 driver.engine.register_interface(info);
2743 let (writer, sent) = MockWriter::new();
2744 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2745
2746 tx.send(Event::RequestPath { dest_hash: [0xAA; 16] }).unwrap();
2748 tx.send(Event::Shutdown).unwrap();
2749 driver.run();
2750
2751 let sent_packets = sent.lock().unwrap();
2753 assert!(!sent_packets.is_empty(), "Path request should be sent on wire");
2754
2755 let raw = &sent_packets[0];
2757 let flags = rns_core::packet::PacketFlags::unpack(raw[0] & 0x7F);
2758 assert_eq!(flags.packet_type, constants::PACKET_TYPE_DATA);
2759 assert_eq!(flags.destination_type, constants::DESTINATION_PLAIN);
2760 assert_eq!(flags.transport_type, constants::TRANSPORT_BROADCAST);
2761 }
2762
2763 #[test]
2764 fn request_path_includes_transport_id() {
2765 let (tx, rx) = event::channel();
2766 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2767 let mut driver = Driver::new(
2768 TransportConfig { transport_enabled: true, identity_hash: Some([0xBB; 16]) },
2769 rx,
2770 Box::new(cbs),
2771 );
2772 let info = make_interface_info(1);
2773 driver.engine.register_interface(info);
2774 let (writer, sent) = MockWriter::new();
2775 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2776
2777 tx.send(Event::RequestPath { dest_hash: [0xAA; 16] }).unwrap();
2778 tx.send(Event::Shutdown).unwrap();
2779 driver.run();
2780
2781 let sent_packets = sent.lock().unwrap();
2782 assert!(!sent_packets.is_empty());
2783
2784 let raw = &sent_packets[0];
2786 if let Ok(packet) = RawPacket::unpack(raw) {
2787 assert_eq!(packet.data.len(), 48, "Path request data should be 48 bytes with transport_id");
2789 assert_eq!(&packet.data[..16], &[0xAA; 16], "First 16 bytes should be dest_hash");
2790 assert_eq!(&packet.data[16..32], &[0xBB; 16], "Next 16 bytes should be transport_id");
2791 } else {
2792 panic!("Could not unpack sent packet");
2793 }
2794 }
2795
2796 #[test]
2797 fn path_request_dest_registered() {
2798 let (tx, rx) = event::channel();
2799 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2800 let driver = Driver::new(
2801 TransportConfig { transport_enabled: false, identity_hash: None },
2802 rx,
2803 Box::new(cbs),
2804 );
2805
2806 let expected_dest = rns_core::destination::destination_hash(
2808 "rnstransport", &["path", "request"], None,
2809 );
2810 assert_eq!(driver.path_request_dest, expected_dest);
2811
2812 drop(tx);
2813 }
2814
2815 #[test]
2820 fn register_proof_strategy_event() {
2821 let (tx, rx) = event::channel();
2822 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2823 let mut driver = Driver::new(
2824 TransportConfig { transport_enabled: false, identity_hash: None },
2825 rx,
2826 Box::new(cbs),
2827 );
2828
2829 let dest = [0xAA; 16];
2830 let identity = Identity::new(&mut OsRng);
2831 let prv_key = identity.get_private_key().unwrap();
2832
2833 tx.send(Event::RegisterProofStrategy {
2834 dest_hash: dest,
2835 strategy: rns_core::types::ProofStrategy::ProveAll,
2836 signing_key: Some(prv_key),
2837 }).unwrap();
2838 tx.send(Event::Shutdown).unwrap();
2839 driver.run();
2840
2841 assert!(driver.proof_strategies.contains_key(&dest));
2842 let (strategy, ref id_opt) = driver.proof_strategies[&dest];
2843 assert_eq!(strategy, rns_core::types::ProofStrategy::ProveAll);
2844 assert!(id_opt.is_some());
2845 }
2846
2847 #[test]
2848 fn register_proof_strategy_prove_none_no_identity() {
2849 let (tx, rx) = event::channel();
2850 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2851 let mut driver = Driver::new(
2852 TransportConfig { transport_enabled: false, identity_hash: None },
2853 rx,
2854 Box::new(cbs),
2855 );
2856
2857 let dest = [0xBB; 16];
2858 tx.send(Event::RegisterProofStrategy {
2859 dest_hash: dest,
2860 strategy: rns_core::types::ProofStrategy::ProveNone,
2861 signing_key: None,
2862 }).unwrap();
2863 tx.send(Event::Shutdown).unwrap();
2864 driver.run();
2865
2866 assert!(driver.proof_strategies.contains_key(&dest));
2867 let (strategy, ref id_opt) = driver.proof_strategies[&dest];
2868 assert_eq!(strategy, rns_core::types::ProofStrategy::ProveNone);
2869 assert!(id_opt.is_none());
2870 }
2871
2872 #[test]
2873 fn send_outbound_tracks_sent_packets() {
2874 let (tx, rx) = event::channel();
2875 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2876 let mut driver = Driver::new(
2877 TransportConfig { transport_enabled: false, identity_hash: None },
2878 rx,
2879 Box::new(cbs),
2880 );
2881 let info = make_interface_info(1);
2882 driver.engine.register_interface(info);
2883 let (writer, _sent) = MockWriter::new();
2884 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2885
2886 let dest = [0xCC; 16];
2888 let flags = PacketFlags {
2889 header_type: constants::HEADER_1,
2890 context_flag: constants::FLAG_UNSET,
2891 transport_type: constants::TRANSPORT_BROADCAST,
2892 destination_type: constants::DESTINATION_PLAIN,
2893 packet_type: constants::PACKET_TYPE_DATA,
2894 };
2895 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, b"test data").unwrap();
2896 let expected_hash = packet.packet_hash;
2897
2898 tx.send(Event::SendOutbound {
2899 raw: packet.raw,
2900 dest_type: constants::DESTINATION_PLAIN,
2901 attached_interface: None,
2902 }).unwrap();
2903 tx.send(Event::Shutdown).unwrap();
2904 driver.run();
2905
2906 assert!(driver.sent_packets.contains_key(&expected_hash));
2908 let (tracked_dest, _sent_time) = &driver.sent_packets[&expected_hash];
2909 assert_eq!(tracked_dest, &dest);
2910 }
2911
2912 #[test]
2913 fn prove_all_generates_proof_on_delivery() {
2914 let (tx, rx) = event::channel();
2915 let (cbs, _, _, deliveries, _, _) = MockCallbacks::new();
2916 let mut driver = Driver::new(
2917 TransportConfig { transport_enabled: false, identity_hash: None },
2918 rx,
2919 Box::new(cbs),
2920 );
2921 let info = make_interface_info(1);
2922 driver.engine.register_interface(info);
2923 let (writer, sent) = MockWriter::new();
2924 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2925
2926 let dest = [0xDD; 16];
2928 let identity = Identity::new(&mut OsRng);
2929 let prv_key = identity.get_private_key().unwrap();
2930 driver.engine.register_destination(dest, constants::DESTINATION_SINGLE);
2931 driver.proof_strategies.insert(dest, (
2932 rns_core::types::ProofStrategy::ProveAll,
2933 Some(Identity::from_private_key(&prv_key)),
2934 ));
2935
2936 let flags = PacketFlags {
2938 header_type: constants::HEADER_1,
2939 context_flag: constants::FLAG_UNSET,
2940 transport_type: constants::TRANSPORT_BROADCAST,
2941 destination_type: constants::DESTINATION_SINGLE,
2942 packet_type: constants::PACKET_TYPE_DATA,
2943 };
2944 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, b"hello").unwrap();
2945
2946 tx.send(Event::Frame { interface_id: InterfaceId(1), data: packet.raw }).unwrap();
2947 tx.send(Event::Shutdown).unwrap();
2948 driver.run();
2949
2950 assert_eq!(deliveries.lock().unwrap().len(), 1);
2952
2953 let sent_packets = sent.lock().unwrap();
2955 let has_proof = sent_packets.iter().any(|raw| {
2957 let flags = PacketFlags::unpack(raw[0] & 0x7F);
2958 flags.packet_type == constants::PACKET_TYPE_PROOF
2959 });
2960 assert!(has_proof, "ProveAll should generate a proof packet: sent {} packets", sent_packets.len());
2961 }
2962
2963 #[test]
2964 fn prove_none_does_not_generate_proof() {
2965 let (tx, rx) = event::channel();
2966 let (cbs, _, _, deliveries, _, _) = MockCallbacks::new();
2967 let mut driver = Driver::new(
2968 TransportConfig { transport_enabled: false, identity_hash: None },
2969 rx,
2970 Box::new(cbs),
2971 );
2972 let info = make_interface_info(1);
2973 driver.engine.register_interface(info);
2974 let (writer, sent) = MockWriter::new();
2975 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2976
2977 let dest = [0xDD; 16];
2979 driver.engine.register_destination(dest, constants::DESTINATION_SINGLE);
2980 driver.proof_strategies.insert(dest, (
2981 rns_core::types::ProofStrategy::ProveNone,
2982 None,
2983 ));
2984
2985 let flags = PacketFlags {
2987 header_type: constants::HEADER_1,
2988 context_flag: constants::FLAG_UNSET,
2989 transport_type: constants::TRANSPORT_BROADCAST,
2990 destination_type: constants::DESTINATION_SINGLE,
2991 packet_type: constants::PACKET_TYPE_DATA,
2992 };
2993 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, b"hello").unwrap();
2994
2995 tx.send(Event::Frame { interface_id: InterfaceId(1), data: packet.raw }).unwrap();
2996 tx.send(Event::Shutdown).unwrap();
2997 driver.run();
2998
2999 assert_eq!(deliveries.lock().unwrap().len(), 1);
3001
3002 let sent_packets = sent.lock().unwrap();
3004 let has_proof = sent_packets.iter().any(|raw| {
3005 let flags = PacketFlags::unpack(raw[0] & 0x7F);
3006 flags.packet_type == constants::PACKET_TYPE_PROOF
3007 });
3008 assert!(!has_proof, "ProveNone should not generate a proof packet");
3009 }
3010
3011 #[test]
3012 fn no_proof_strategy_does_not_generate_proof() {
3013 let (tx, rx) = event::channel();
3014 let (cbs, _, _, deliveries, _, _) = MockCallbacks::new();
3015 let mut driver = Driver::new(
3016 TransportConfig { transport_enabled: false, identity_hash: None },
3017 rx,
3018 Box::new(cbs),
3019 );
3020 let info = make_interface_info(1);
3021 driver.engine.register_interface(info);
3022 let (writer, sent) = MockWriter::new();
3023 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
3024
3025 let dest = [0xDD; 16];
3027 driver.engine.register_destination(dest, constants::DESTINATION_SINGLE);
3028
3029 let flags = PacketFlags {
3030 header_type: constants::HEADER_1,
3031 context_flag: constants::FLAG_UNSET,
3032 transport_type: constants::TRANSPORT_BROADCAST,
3033 destination_type: constants::DESTINATION_SINGLE,
3034 packet_type: constants::PACKET_TYPE_DATA,
3035 };
3036 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, b"hello").unwrap();
3037
3038 tx.send(Event::Frame { interface_id: InterfaceId(1), data: packet.raw }).unwrap();
3039 tx.send(Event::Shutdown).unwrap();
3040 driver.run();
3041
3042 assert_eq!(deliveries.lock().unwrap().len(), 1);
3043
3044 let sent_packets = sent.lock().unwrap();
3045 let has_proof = sent_packets.iter().any(|raw| {
3046 let flags = PacketFlags::unpack(raw[0] & 0x7F);
3047 flags.packet_type == constants::PACKET_TYPE_PROOF
3048 });
3049 assert!(!has_proof, "No proof strategy means no proof generated");
3050 }
3051
3052 #[test]
3053 fn prove_app_calls_callback() {
3054 let (tx, rx) = event::channel();
3055 let proof_requested = Arc::new(Mutex::new(Vec::new()));
3056 let deliveries = Arc::new(Mutex::new(Vec::new()));
3057 let cbs = MockCallbacks {
3058 announces: Arc::new(Mutex::new(Vec::new())),
3059 paths: Arc::new(Mutex::new(Vec::new())),
3060 deliveries: deliveries.clone(),
3061 iface_ups: Arc::new(Mutex::new(Vec::new())),
3062 iface_downs: Arc::new(Mutex::new(Vec::new())),
3063 link_established: Arc::new(Mutex::new(Vec::new())),
3064 link_closed: Arc::new(Mutex::new(Vec::new())),
3065 remote_identified: Arc::new(Mutex::new(Vec::new())),
3066 resources_received: Arc::new(Mutex::new(Vec::new())),
3067 resource_completed: Arc::new(Mutex::new(Vec::new())),
3068 resource_failed: Arc::new(Mutex::new(Vec::new())),
3069 channel_messages: Arc::new(Mutex::new(Vec::new())),
3070 link_data: Arc::new(Mutex::new(Vec::new())),
3071 responses: Arc::new(Mutex::new(Vec::new())),
3072 proofs: Arc::new(Mutex::new(Vec::new())),
3073 proof_requested: proof_requested.clone(),
3074 };
3075
3076 let mut driver = Driver::new(
3077 TransportConfig { transport_enabled: false, identity_hash: None },
3078 rx,
3079 Box::new(cbs),
3080 );
3081 let info = make_interface_info(1);
3082 driver.engine.register_interface(info);
3083 let (writer, sent) = MockWriter::new();
3084 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
3085
3086 let dest = [0xDD; 16];
3088 let identity = Identity::new(&mut OsRng);
3089 let prv_key = identity.get_private_key().unwrap();
3090 driver.engine.register_destination(dest, constants::DESTINATION_SINGLE);
3091 driver.proof_strategies.insert(dest, (
3092 rns_core::types::ProofStrategy::ProveApp,
3093 Some(Identity::from_private_key(&prv_key)),
3094 ));
3095
3096 let flags = PacketFlags {
3097 header_type: constants::HEADER_1,
3098 context_flag: constants::FLAG_UNSET,
3099 transport_type: constants::TRANSPORT_BROADCAST,
3100 destination_type: constants::DESTINATION_SINGLE,
3101 packet_type: constants::PACKET_TYPE_DATA,
3102 };
3103 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, b"app test").unwrap();
3104
3105 tx.send(Event::Frame { interface_id: InterfaceId(1), data: packet.raw }).unwrap();
3106 tx.send(Event::Shutdown).unwrap();
3107 driver.run();
3108
3109 let prs = proof_requested.lock().unwrap();
3111 assert_eq!(prs.len(), 1);
3112 assert_eq!(prs[0].0, DestHash(dest));
3113
3114 let sent_packets = sent.lock().unwrap();
3116 let has_proof = sent_packets.iter().any(|raw| {
3117 let flags = PacketFlags::unpack(raw[0] & 0x7F);
3118 flags.packet_type == constants::PACKET_TYPE_PROOF
3119 });
3120 assert!(has_proof, "ProveApp (callback returns true) should generate a proof");
3121 }
3122
3123 #[test]
3124 fn inbound_proof_fires_callback() {
3125 let (tx, rx) = event::channel();
3126 let proofs = Arc::new(Mutex::new(Vec::new()));
3127 let cbs = MockCallbacks {
3128 announces: Arc::new(Mutex::new(Vec::new())),
3129 paths: Arc::new(Mutex::new(Vec::new())),
3130 deliveries: Arc::new(Mutex::new(Vec::new())),
3131 iface_ups: Arc::new(Mutex::new(Vec::new())),
3132 iface_downs: Arc::new(Mutex::new(Vec::new())),
3133 link_established: Arc::new(Mutex::new(Vec::new())),
3134 link_closed: Arc::new(Mutex::new(Vec::new())),
3135 remote_identified: Arc::new(Mutex::new(Vec::new())),
3136 resources_received: Arc::new(Mutex::new(Vec::new())),
3137 resource_completed: Arc::new(Mutex::new(Vec::new())),
3138 resource_failed: Arc::new(Mutex::new(Vec::new())),
3139 channel_messages: Arc::new(Mutex::new(Vec::new())),
3140 link_data: Arc::new(Mutex::new(Vec::new())),
3141 responses: Arc::new(Mutex::new(Vec::new())),
3142 proofs: proofs.clone(),
3143 proof_requested: Arc::new(Mutex::new(Vec::new())),
3144 };
3145
3146 let mut driver = Driver::new(
3147 TransportConfig { transport_enabled: false, identity_hash: None },
3148 rx,
3149 Box::new(cbs),
3150 );
3151 let info = make_interface_info(1);
3152 driver.engine.register_interface(info);
3153 let (writer, _sent) = MockWriter::new();
3154 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
3155
3156 let dest = [0xEE; 16];
3158 driver.engine.register_destination(dest, constants::DESTINATION_SINGLE);
3159
3160 let tracked_hash = [0x42u8; 32];
3162 let sent_time = time::now() - 0.5; driver.sent_packets.insert(tracked_hash, (dest, sent_time));
3164
3165 let mut proof_data = Vec::new();
3167 proof_data.extend_from_slice(&tracked_hash);
3168 proof_data.extend_from_slice(&[0xAA; 64]); let flags = PacketFlags {
3171 header_type: constants::HEADER_1,
3172 context_flag: constants::FLAG_UNSET,
3173 transport_type: constants::TRANSPORT_BROADCAST,
3174 destination_type: constants::DESTINATION_SINGLE,
3175 packet_type: constants::PACKET_TYPE_PROOF,
3176 };
3177 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, &proof_data).unwrap();
3178
3179 tx.send(Event::Frame { interface_id: InterfaceId(1), data: packet.raw }).unwrap();
3180 tx.send(Event::Shutdown).unwrap();
3181 driver.run();
3182
3183 let proof_list = proofs.lock().unwrap();
3185 assert_eq!(proof_list.len(), 1);
3186 assert_eq!(proof_list[0].0, DestHash(dest));
3187 assert_eq!(proof_list[0].1, PacketHash(tracked_hash));
3188 assert!(proof_list[0].2 >= 0.4, "RTT should be approximately 0.5s, got {}", proof_list[0].2);
3189
3190 assert!(!driver.sent_packets.contains_key(&tracked_hash));
3192 }
3193
3194 #[test]
3195 fn inbound_proof_for_unknown_packet_is_ignored() {
3196 let (tx, rx) = event::channel();
3197 let proofs = Arc::new(Mutex::new(Vec::new()));
3198 let cbs = MockCallbacks {
3199 announces: Arc::new(Mutex::new(Vec::new())),
3200 paths: Arc::new(Mutex::new(Vec::new())),
3201 deliveries: Arc::new(Mutex::new(Vec::new())),
3202 iface_ups: Arc::new(Mutex::new(Vec::new())),
3203 iface_downs: Arc::new(Mutex::new(Vec::new())),
3204 link_established: Arc::new(Mutex::new(Vec::new())),
3205 link_closed: Arc::new(Mutex::new(Vec::new())),
3206 remote_identified: Arc::new(Mutex::new(Vec::new())),
3207 resources_received: Arc::new(Mutex::new(Vec::new())),
3208 resource_completed: Arc::new(Mutex::new(Vec::new())),
3209 resource_failed: Arc::new(Mutex::new(Vec::new())),
3210 channel_messages: Arc::new(Mutex::new(Vec::new())),
3211 link_data: Arc::new(Mutex::new(Vec::new())),
3212 responses: Arc::new(Mutex::new(Vec::new())),
3213 proofs: proofs.clone(),
3214 proof_requested: Arc::new(Mutex::new(Vec::new())),
3215 };
3216
3217 let mut driver = Driver::new(
3218 TransportConfig { transport_enabled: false, identity_hash: None },
3219 rx,
3220 Box::new(cbs),
3221 );
3222 let info = make_interface_info(1);
3223 driver.engine.register_interface(info);
3224 let (writer, _sent) = MockWriter::new();
3225 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
3226
3227 let dest = [0xEE; 16];
3228 driver.engine.register_destination(dest, constants::DESTINATION_SINGLE);
3229
3230 let unknown_hash = [0xFF; 32];
3232 let mut proof_data = Vec::new();
3233 proof_data.extend_from_slice(&unknown_hash);
3234 proof_data.extend_from_slice(&[0xAA; 64]);
3235
3236 let flags = PacketFlags {
3237 header_type: constants::HEADER_1,
3238 context_flag: constants::FLAG_UNSET,
3239 transport_type: constants::TRANSPORT_BROADCAST,
3240 destination_type: constants::DESTINATION_SINGLE,
3241 packet_type: constants::PACKET_TYPE_PROOF,
3242 };
3243 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, &proof_data).unwrap();
3244
3245 tx.send(Event::Frame { interface_id: InterfaceId(1), data: packet.raw }).unwrap();
3246 tx.send(Event::Shutdown).unwrap();
3247 driver.run();
3248
3249 assert!(proofs.lock().unwrap().is_empty());
3251 }
3252
3253 #[test]
3254 fn inbound_proof_with_valid_signature_fires_callback() {
3255 let (tx, rx) = event::channel();
3257 let proofs = Arc::new(Mutex::new(Vec::new()));
3258 let cbs = MockCallbacks {
3259 announces: Arc::new(Mutex::new(Vec::new())),
3260 paths: Arc::new(Mutex::new(Vec::new())),
3261 deliveries: Arc::new(Mutex::new(Vec::new())),
3262 iface_ups: Arc::new(Mutex::new(Vec::new())),
3263 iface_downs: Arc::new(Mutex::new(Vec::new())),
3264 link_established: Arc::new(Mutex::new(Vec::new())),
3265 link_closed: Arc::new(Mutex::new(Vec::new())),
3266 remote_identified: Arc::new(Mutex::new(Vec::new())),
3267 resources_received: Arc::new(Mutex::new(Vec::new())),
3268 resource_completed: Arc::new(Mutex::new(Vec::new())),
3269 resource_failed: Arc::new(Mutex::new(Vec::new())),
3270 channel_messages: Arc::new(Mutex::new(Vec::new())),
3271 link_data: Arc::new(Mutex::new(Vec::new())),
3272 responses: Arc::new(Mutex::new(Vec::new())),
3273 proofs: proofs.clone(),
3274 proof_requested: Arc::new(Mutex::new(Vec::new())),
3275 };
3276
3277 let mut driver = Driver::new(
3278 TransportConfig { transport_enabled: false, identity_hash: None },
3279 rx,
3280 Box::new(cbs),
3281 );
3282 let info = make_interface_info(1);
3283 driver.engine.register_interface(info);
3284 let (writer, _sent) = MockWriter::new();
3285 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
3286
3287 let dest = [0xEE; 16];
3288 driver.engine.register_destination(dest, constants::DESTINATION_SINGLE);
3289
3290 let identity = Identity::new(&mut OsRng);
3292 let pub_key = identity.get_public_key();
3293 driver.known_destinations.insert(dest, crate::destination::AnnouncedIdentity {
3294 dest_hash: DestHash(dest),
3295 identity_hash: IdentityHash(*identity.hash()),
3296 public_key: pub_key.unwrap(),
3297 app_data: None,
3298 hops: 0,
3299 received_at: time::now(),
3300 });
3301
3302 let tracked_hash = [0x42u8; 32];
3304 let sent_time = time::now() - 0.5;
3305 driver.sent_packets.insert(tracked_hash, (dest, sent_time));
3306
3307 let signature = identity.sign(&tracked_hash).unwrap();
3308 let mut proof_data = Vec::new();
3309 proof_data.extend_from_slice(&tracked_hash);
3310 proof_data.extend_from_slice(&signature);
3311
3312 let flags = PacketFlags {
3313 header_type: constants::HEADER_1,
3314 context_flag: constants::FLAG_UNSET,
3315 transport_type: constants::TRANSPORT_BROADCAST,
3316 destination_type: constants::DESTINATION_SINGLE,
3317 packet_type: constants::PACKET_TYPE_PROOF,
3318 };
3319 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, &proof_data).unwrap();
3320
3321 tx.send(Event::Frame { interface_id: InterfaceId(1), data: packet.raw }).unwrap();
3322 tx.send(Event::Shutdown).unwrap();
3323 driver.run();
3324
3325 let proof_list = proofs.lock().unwrap();
3327 assert_eq!(proof_list.len(), 1);
3328 assert_eq!(proof_list[0].0, DestHash(dest));
3329 assert_eq!(proof_list[0].1, PacketHash(tracked_hash));
3330 }
3331
3332 #[test]
3333 fn inbound_proof_with_invalid_signature_rejected() {
3334 let (tx, rx) = event::channel();
3336 let proofs = Arc::new(Mutex::new(Vec::new()));
3337 let cbs = MockCallbacks {
3338 announces: Arc::new(Mutex::new(Vec::new())),
3339 paths: Arc::new(Mutex::new(Vec::new())),
3340 deliveries: Arc::new(Mutex::new(Vec::new())),
3341 iface_ups: Arc::new(Mutex::new(Vec::new())),
3342 iface_downs: Arc::new(Mutex::new(Vec::new())),
3343 link_established: Arc::new(Mutex::new(Vec::new())),
3344 link_closed: Arc::new(Mutex::new(Vec::new())),
3345 remote_identified: Arc::new(Mutex::new(Vec::new())),
3346 resources_received: Arc::new(Mutex::new(Vec::new())),
3347 resource_completed: Arc::new(Mutex::new(Vec::new())),
3348 resource_failed: Arc::new(Mutex::new(Vec::new())),
3349 channel_messages: Arc::new(Mutex::new(Vec::new())),
3350 link_data: Arc::new(Mutex::new(Vec::new())),
3351 responses: Arc::new(Mutex::new(Vec::new())),
3352 proofs: proofs.clone(),
3353 proof_requested: Arc::new(Mutex::new(Vec::new())),
3354 };
3355
3356 let mut driver = Driver::new(
3357 TransportConfig { transport_enabled: false, identity_hash: None },
3358 rx,
3359 Box::new(cbs),
3360 );
3361 let info = make_interface_info(1);
3362 driver.engine.register_interface(info);
3363 let (writer, _sent) = MockWriter::new();
3364 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
3365
3366 let dest = [0xEE; 16];
3367 driver.engine.register_destination(dest, constants::DESTINATION_SINGLE);
3368
3369 let identity = Identity::new(&mut OsRng);
3371 let pub_key = identity.get_public_key();
3372 driver.known_destinations.insert(dest, crate::destination::AnnouncedIdentity {
3373 dest_hash: DestHash(dest),
3374 identity_hash: IdentityHash(*identity.hash()),
3375 public_key: pub_key.unwrap(),
3376 app_data: None,
3377 hops: 0,
3378 received_at: time::now(),
3379 });
3380
3381 let tracked_hash = [0x42u8; 32];
3383 let sent_time = time::now() - 0.5;
3384 driver.sent_packets.insert(tracked_hash, (dest, sent_time));
3385
3386 let mut proof_data = Vec::new();
3388 proof_data.extend_from_slice(&tracked_hash);
3389 proof_data.extend_from_slice(&[0xAA; 64]);
3390
3391 let flags = PacketFlags {
3392 header_type: constants::HEADER_1,
3393 context_flag: constants::FLAG_UNSET,
3394 transport_type: constants::TRANSPORT_BROADCAST,
3395 destination_type: constants::DESTINATION_SINGLE,
3396 packet_type: constants::PACKET_TYPE_PROOF,
3397 };
3398 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, &proof_data).unwrap();
3399
3400 tx.send(Event::Frame { interface_id: InterfaceId(1), data: packet.raw }).unwrap();
3401 tx.send(Event::Shutdown).unwrap();
3402 driver.run();
3403
3404 assert!(proofs.lock().unwrap().is_empty());
3406 }
3407
3408 #[test]
3409 fn proof_data_is_valid_explicit_proof() {
3410 let (tx, rx) = event::channel();
3412 let (cbs, _, _, _, _, _) = MockCallbacks::new();
3413 let mut driver = Driver::new(
3414 TransportConfig { transport_enabled: false, identity_hash: None },
3415 rx,
3416 Box::new(cbs),
3417 );
3418 let info = make_interface_info(1);
3419 driver.engine.register_interface(info);
3420 let (writer, sent) = MockWriter::new();
3421 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
3422
3423 let dest = [0xDD; 16];
3424 let identity = Identity::new(&mut OsRng);
3425 let prv_key = identity.get_private_key().unwrap();
3426 driver.engine.register_destination(dest, constants::DESTINATION_SINGLE);
3427 driver.proof_strategies.insert(dest, (
3428 rns_core::types::ProofStrategy::ProveAll,
3429 Some(Identity::from_private_key(&prv_key)),
3430 ));
3431
3432 let flags = PacketFlags {
3433 header_type: constants::HEADER_1,
3434 context_flag: constants::FLAG_UNSET,
3435 transport_type: constants::TRANSPORT_BROADCAST,
3436 destination_type: constants::DESTINATION_SINGLE,
3437 packet_type: constants::PACKET_TYPE_DATA,
3438 };
3439 let data_packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, b"verify me").unwrap();
3440 let data_packet_hash = data_packet.packet_hash;
3441
3442 tx.send(Event::Frame { interface_id: InterfaceId(1), data: data_packet.raw }).unwrap();
3443 tx.send(Event::Shutdown).unwrap();
3444 driver.run();
3445
3446 let sent_packets = sent.lock().unwrap();
3448 let proof_raw = sent_packets.iter().find(|raw| {
3449 let f = PacketFlags::unpack(raw[0] & 0x7F);
3450 f.packet_type == constants::PACKET_TYPE_PROOF
3451 });
3452 assert!(proof_raw.is_some(), "Should have sent a proof");
3453
3454 let proof_packet = RawPacket::unpack(proof_raw.unwrap()).unwrap();
3455 assert_eq!(proof_packet.data.len(), 96, "Explicit proof should be 96 bytes");
3457
3458 let result = rns_core::receipt::validate_proof(
3460 &proof_packet.data,
3461 &data_packet_hash,
3462 &Identity::from_private_key(&prv_key), );
3464 assert_eq!(result, rns_core::receipt::ProofResult::Valid);
3465 }
3466
3467 #[test]
3468 fn query_local_destinations_empty() {
3469 let (tx, rx) = event::channel();
3470 let (cbs, _, _, _, _, _) = MockCallbacks::new();
3471 let driver_config = TransportConfig { transport_enabled: false, identity_hash: None };
3472 let mut driver = Driver::new(driver_config, rx, Box::new(cbs));
3473
3474 let (resp_tx, resp_rx) = mpsc::channel();
3475 tx.send(Event::Query(QueryRequest::LocalDestinations, resp_tx)).unwrap();
3476 tx.send(Event::Shutdown).unwrap();
3477 driver.run();
3478
3479 match resp_rx.recv().unwrap() {
3480 QueryResponse::LocalDestinations(entries) => {
3481 assert_eq!(entries.len(), 2);
3483 for entry in &entries {
3484 assert_eq!(entry.dest_type, rns_core::constants::DESTINATION_PLAIN);
3485 }
3486 }
3487 other => panic!("expected LocalDestinations, got {:?}", other),
3488 }
3489 }
3490
3491 #[test]
3492 fn query_local_destinations_with_registered() {
3493 let (tx, rx) = event::channel();
3494 let (cbs, _, _, _, _, _) = MockCallbacks::new();
3495 let driver_config = TransportConfig { transport_enabled: false, identity_hash: None };
3496 let mut driver = Driver::new(driver_config, rx, Box::new(cbs));
3497
3498 let dest_hash = [0xAA; 16];
3499 tx.send(Event::RegisterDestination {
3500 dest_hash,
3501 dest_type: rns_core::constants::DESTINATION_SINGLE,
3502 }).unwrap();
3503
3504 let (resp_tx, resp_rx) = mpsc::channel();
3505 tx.send(Event::Query(QueryRequest::LocalDestinations, resp_tx)).unwrap();
3506 tx.send(Event::Shutdown).unwrap();
3507 driver.run();
3508
3509 match resp_rx.recv().unwrap() {
3510 QueryResponse::LocalDestinations(entries) => {
3511 assert_eq!(entries.len(), 3);
3513 assert!(entries.iter().any(|e| e.hash == dest_hash
3514 && e.dest_type == rns_core::constants::DESTINATION_SINGLE));
3515 }
3516 other => panic!("expected LocalDestinations, got {:?}", other),
3517 }
3518 }
3519
3520 #[test]
3521 fn query_local_destinations_tracks_link_dest() {
3522 let (tx, rx) = event::channel();
3523 let (cbs, _, _, _, _, _) = MockCallbacks::new();
3524 let driver_config = TransportConfig { transport_enabled: false, identity_hash: None };
3525 let mut driver = Driver::new(driver_config, rx, Box::new(cbs));
3526
3527 let dest_hash = [0xBB; 16];
3528 tx.send(Event::RegisterLinkDestination {
3529 dest_hash,
3530 sig_prv_bytes: [0x11; 32],
3531 sig_pub_bytes: [0x22; 32],
3532 }).unwrap();
3533
3534 let (resp_tx, resp_rx) = mpsc::channel();
3535 tx.send(Event::Query(QueryRequest::LocalDestinations, resp_tx)).unwrap();
3536 tx.send(Event::Shutdown).unwrap();
3537 driver.run();
3538
3539 match resp_rx.recv().unwrap() {
3540 QueryResponse::LocalDestinations(entries) => {
3541 assert_eq!(entries.len(), 3);
3543 assert!(entries.iter().any(|e| e.hash == dest_hash
3544 && e.dest_type == rns_core::constants::DESTINATION_SINGLE));
3545 }
3546 other => panic!("expected LocalDestinations, got {:?}", other),
3547 }
3548 }
3549
3550 #[test]
3551 fn query_links_empty() {
3552 let (tx, rx) = event::channel();
3553 let (cbs, _, _, _, _, _) = MockCallbacks::new();
3554 let driver_config = TransportConfig { transport_enabled: false, identity_hash: None };
3555 let mut driver = Driver::new(driver_config, rx, Box::new(cbs));
3556
3557 let (resp_tx, resp_rx) = mpsc::channel();
3558 tx.send(Event::Query(QueryRequest::Links, resp_tx)).unwrap();
3559 tx.send(Event::Shutdown).unwrap();
3560 driver.run();
3561
3562 match resp_rx.recv().unwrap() {
3563 QueryResponse::Links(entries) => {
3564 assert!(entries.is_empty());
3565 }
3566 other => panic!("expected Links, got {:?}", other),
3567 }
3568 }
3569
3570 #[test]
3571 fn query_resources_empty() {
3572 let (tx, rx) = event::channel();
3573 let (cbs, _, _, _, _, _) = MockCallbacks::new();
3574 let driver_config = TransportConfig { transport_enabled: false, identity_hash: None };
3575 let mut driver = Driver::new(driver_config, rx, Box::new(cbs));
3576
3577 let (resp_tx, resp_rx) = mpsc::channel();
3578 tx.send(Event::Query(QueryRequest::Resources, resp_tx)).unwrap();
3579 tx.send(Event::Shutdown).unwrap();
3580 driver.run();
3581
3582 match resp_rx.recv().unwrap() {
3583 QueryResponse::Resources(entries) => {
3584 assert!(entries.is_empty());
3585 }
3586 other => panic!("expected Resources, got {:?}", other),
3587 }
3588 }
3589
3590 #[test]
3591 fn infer_interface_type_from_name() {
3592 assert_eq!(
3593 super::infer_interface_type("TCPServerInterface/Client-1234"),
3594 "TCPServerClientInterface"
3595 );
3596 assert_eq!(
3597 super::infer_interface_type("BackboneInterface/5"),
3598 "BackboneInterface"
3599 );
3600 assert_eq!(
3601 super::infer_interface_type("LocalInterface"),
3602 "LocalServerClientInterface"
3603 );
3604 assert_eq!(
3605 super::infer_interface_type("MyAutoGroup:fe80::1"),
3606 "AutoInterface"
3607 );
3608 }
3609}