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, _dest_hash: rns_core::types::DestHash, _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 if link_actions.is_empty() {
896 if let Ok(packet) = RawPacket::unpack(&raw) {
900 if packet.flags.packet_type == rns_core::constants::PACKET_TYPE_PROOF {
901 self.handle_inbound_proof(destination_hash, &packet.data, &packet_hash);
902 continue;
903 }
904 }
905 self.maybe_generate_proof(destination_hash, &packet_hash);
906 self.callbacks.on_local_delivery(
907 rns_core::types::DestHash(destination_hash),
908 raw,
909 rns_core::types::PacketHash(packet_hash),
910 );
911 } else {
912 self.dispatch_link_actions(link_actions);
913 }
914 } else {
915 if let Ok(packet) = RawPacket::unpack(&raw) {
917 if packet.flags.packet_type == rns_core::constants::PACKET_TYPE_PROOF {
918 self.handle_inbound_proof(destination_hash, &packet.data, &packet_hash);
919 continue;
920 }
921 }
922
923 self.maybe_generate_proof(destination_hash, &packet_hash);
925
926 self.callbacks
927 .on_local_delivery(
928 rns_core::types::DestHash(destination_hash),
929 raw,
930 rns_core::types::PacketHash(packet_hash),
931 );
932 }
933 }
934 TransportAction::AnnounceReceived {
935 destination_hash,
936 identity_hash,
937 public_key,
938 app_data,
939 hops,
940 receiving_interface,
941 ..
942 } => {
943 if let Some(entry) = self.interfaces.get_mut(&receiving_interface) {
944 entry.stats.record_incoming_announce(time::now());
945 }
946 let announced = crate::destination::AnnouncedIdentity {
948 dest_hash: rns_core::types::DestHash(destination_hash),
949 identity_hash: rns_core::types::IdentityHash(identity_hash),
950 public_key,
951 app_data: app_data.clone(),
952 hops,
953 received_at: time::now(),
954 };
955 self.known_destinations.insert(destination_hash, announced.clone());
956 self.callbacks.on_announce(announced);
957 }
958 TransportAction::PathUpdated {
959 destination_hash,
960 hops,
961 ..
962 } => {
963 self.callbacks.on_path_updated(rns_core::types::DestHash(destination_hash), hops);
964 }
965 TransportAction::ForwardToLocalClients { raw, exclude } => {
966 for entry in self.interfaces.values_mut() {
967 if entry.online
968 && entry.info.is_local_client
969 && Some(entry.id) != exclude
970 {
971 let data = if let Some(ref ifac_state) = entry.ifac {
972 ifac::mask_outbound(&raw, ifac_state)
973 } else {
974 raw.clone()
975 };
976 entry.stats.txb += data.len() as u64;
977 entry.stats.tx_packets += 1;
978 if let Err(e) = entry.writer.send_frame(&data) {
979 log::warn!("[{}] forward to local client failed: {}", entry.info.id.0, e);
980 }
981 }
982 }
983 }
984 TransportAction::ForwardPlainBroadcast { raw, to_local, exclude } => {
985 for entry in self.interfaces.values_mut() {
986 if entry.online
987 && entry.info.is_local_client == to_local
988 && Some(entry.id) != exclude
989 {
990 let data = if let Some(ref ifac_state) = entry.ifac {
991 ifac::mask_outbound(&raw, ifac_state)
992 } else {
993 raw.clone()
994 };
995 entry.stats.txb += data.len() as u64;
996 entry.stats.tx_packets += 1;
997 if let Err(e) = entry.writer.send_frame(&data) {
998 log::warn!("[{}] forward plain broadcast failed: {}", entry.info.id.0, e);
999 }
1000 }
1001 }
1002 }
1003 TransportAction::CacheAnnounce { packet_hash, raw } => {
1004 if let Some(ref cache) = self.announce_cache {
1005 if let Err(e) = cache.store(&packet_hash, &raw, None) {
1006 log::warn!("Failed to cache announce: {}", e);
1007 }
1008 }
1009 }
1010 TransportAction::TunnelSynthesize { interface, data, dest_hash } => {
1011 let flags = rns_core::packet::PacketFlags {
1013 header_type: rns_core::constants::HEADER_1,
1014 context_flag: rns_core::constants::FLAG_UNSET,
1015 transport_type: rns_core::constants::TRANSPORT_BROADCAST,
1016 destination_type: rns_core::constants::DESTINATION_PLAIN,
1017 packet_type: rns_core::constants::PACKET_TYPE_DATA,
1018 };
1019 if let Ok(packet) = rns_core::packet::RawPacket::pack(
1020 flags, 0, &dest_hash, None,
1021 rns_core::constants::CONTEXT_NONE, &data,
1022 ) {
1023 if let Some(entry) = self.interfaces.get_mut(&interface) {
1024 if entry.online {
1025 let raw = if let Some(ref ifac_state) = entry.ifac {
1026 ifac::mask_outbound(&packet.raw, ifac_state)
1027 } else {
1028 packet.raw
1029 };
1030 entry.stats.txb += raw.len() as u64;
1031 entry.stats.tx_packets += 1;
1032 if let Err(e) = entry.writer.send_frame(&raw) {
1033 log::warn!("[{}] tunnel synthesize send failed: {}", entry.info.id.0, e);
1034 }
1035 }
1036 }
1037 }
1038 }
1039 TransportAction::TunnelEstablished { tunnel_id, interface } => {
1040 log::info!("Tunnel established: {:02x?} on interface {}", &tunnel_id[..4], interface.0);
1041 }
1042 }
1043 }
1044 }
1045
1046 fn dispatch_link_actions(&mut self, actions: Vec<LinkManagerAction>) {
1048 for action in actions {
1049 match action {
1050 LinkManagerAction::SendPacket { raw, dest_type, attached_interface } => {
1051 match RawPacket::unpack(&raw) {
1053 Ok(packet) => {
1054 let transport_actions = self.engine.handle_outbound(
1055 &packet,
1056 dest_type,
1057 attached_interface,
1058 time::now(),
1059 );
1060 self.dispatch_all(transport_actions);
1061 }
1062 Err(e) => {
1063 log::warn!("LinkManager SendPacket: failed to unpack: {:?}", e);
1064 }
1065 }
1066 }
1067 LinkManagerAction::LinkEstablished { link_id, dest_hash, rtt, is_initiator } => {
1068 log::info!(
1069 "Link established: {:02x?} rtt={:.3}s initiator={}",
1070 &link_id[..4], rtt, is_initiator,
1071 );
1072 self.callbacks.on_link_established(
1073 rns_core::types::LinkId(link_id),
1074 rns_core::types::DestHash(dest_hash),
1075 rtt,
1076 is_initiator,
1077 );
1078 }
1079 LinkManagerAction::LinkClosed { link_id, reason } => {
1080 log::info!("Link closed: {:02x?} reason={:?}", &link_id[..4], reason);
1081 self.callbacks.on_link_closed(rns_core::types::LinkId(link_id), reason);
1082 }
1083 LinkManagerAction::RemoteIdentified { link_id, identity_hash, public_key } => {
1084 log::debug!(
1085 "Remote identified on link {:02x?}: {:02x?}",
1086 &link_id[..4], &identity_hash[..4],
1087 );
1088 self.callbacks.on_remote_identified(
1089 rns_core::types::LinkId(link_id),
1090 rns_core::types::IdentityHash(identity_hash),
1091 public_key,
1092 );
1093 }
1094 LinkManagerAction::RegisterLinkDest { link_id } => {
1095 self.engine.register_destination(link_id, rns_core::constants::DESTINATION_LINK);
1097 }
1098 LinkManagerAction::DeregisterLinkDest { link_id } => {
1099 self.engine.deregister_destination(&link_id);
1100 }
1101 LinkManagerAction::ManagementRequest {
1102 link_id, path_hash, data, request_id, remote_identity,
1103 } => {
1104 self.handle_management_request(
1105 link_id, path_hash, data, request_id, remote_identity,
1106 );
1107 }
1108 LinkManagerAction::ResourceReceived { link_id, data, metadata } => {
1109 self.callbacks.on_resource_received(rns_core::types::LinkId(link_id), data, metadata);
1110 }
1111 LinkManagerAction::ResourceCompleted { link_id } => {
1112 self.callbacks.on_resource_completed(rns_core::types::LinkId(link_id));
1113 }
1114 LinkManagerAction::ResourceFailed { link_id, error } => {
1115 log::debug!("Resource failed on link {:02x?}: {}", &link_id[..4], error);
1116 self.callbacks.on_resource_failed(rns_core::types::LinkId(link_id), error);
1117 }
1118 LinkManagerAction::ResourceProgress { link_id, received, total } => {
1119 self.callbacks.on_resource_progress(rns_core::types::LinkId(link_id), received, total);
1120 }
1121 LinkManagerAction::ResourceAcceptQuery { link_id, resource_hash, transfer_size, has_metadata } => {
1122 let accept = self.callbacks.on_resource_accept_query(
1123 rns_core::types::LinkId(link_id), resource_hash.clone(), transfer_size, has_metadata,
1124 );
1125 let accept_actions = self.link_manager.accept_resource(
1126 &link_id, &resource_hash, accept, &mut self.rng,
1127 );
1128 self.dispatch_link_actions(accept_actions);
1130 }
1131 LinkManagerAction::ChannelMessageReceived { link_id, msgtype, payload } => {
1132 self.callbacks.on_channel_message(rns_core::types::LinkId(link_id), msgtype, payload);
1133 }
1134 LinkManagerAction::LinkDataReceived { link_id, context, data } => {
1135 self.callbacks.on_link_data(rns_core::types::LinkId(link_id), context, data);
1136 }
1137 LinkManagerAction::ResponseReceived { link_id, request_id, data } => {
1138 self.callbacks.on_response(rns_core::types::LinkId(link_id), request_id, data);
1139 }
1140 }
1141 }
1142 }
1143
1144 const MANAGEMENT_ANNOUNCE_INTERVAL: f64 = 300.0;
1146
1147 const MANAGEMENT_ANNOUNCE_DELAY: f64 = 5.0;
1149
1150 fn tick_management_announces(&mut self, now: f64) {
1152 if self.transport_identity.is_none() {
1153 return;
1154 }
1155
1156 let uptime = now - self.started;
1157
1158 if !self.initial_announce_sent {
1160 if uptime < Self::MANAGEMENT_ANNOUNCE_DELAY {
1161 return;
1162 }
1163 self.initial_announce_sent = true;
1164 self.emit_management_announces(now);
1165 return;
1166 }
1167
1168 if now - self.last_management_announce >= Self::MANAGEMENT_ANNOUNCE_INTERVAL {
1170 self.emit_management_announces(now);
1171 }
1172 }
1173
1174 fn emit_management_announces(&mut self, now: f64) {
1176 use crate::management;
1177
1178 self.last_management_announce = now;
1179
1180 let identity = match self.transport_identity {
1181 Some(ref id) => id,
1182 None => return,
1183 };
1184
1185 let mgmt_raw = if self.management_config.enable_remote_management {
1187 management::build_management_announce(identity, &mut self.rng)
1188 } else {
1189 None
1190 };
1191
1192 let bh_raw = if self.management_config.publish_blackhole {
1193 management::build_blackhole_announce(identity, &mut self.rng)
1194 } else {
1195 None
1196 };
1197
1198 if let Some(raw) = mgmt_raw {
1199 if let Ok(packet) = RawPacket::unpack(&raw) {
1200 let actions = self.engine.handle_outbound(
1201 &packet,
1202 rns_core::constants::DESTINATION_SINGLE,
1203 None,
1204 now,
1205 );
1206 self.dispatch_all(actions);
1207 log::debug!("Emitted management destination announce");
1208 }
1209 }
1210
1211 if let Some(raw) = bh_raw {
1212 if let Ok(packet) = RawPacket::unpack(&raw) {
1213 let actions = self.engine.handle_outbound(
1214 &packet,
1215 rns_core::constants::DESTINATION_SINGLE,
1216 None,
1217 now,
1218 );
1219 self.dispatch_all(actions);
1220 log::debug!("Emitted blackhole info announce");
1221 }
1222 }
1223 }
1224
1225 fn handle_management_request(
1227 &mut self,
1228 link_id: [u8; 16],
1229 path_hash: [u8; 16],
1230 data: Vec<u8>,
1231 request_id: [u8; 16],
1232 remote_identity: Option<([u8; 16], [u8; 64])>,
1233 ) {
1234 use crate::management;
1235
1236 let is_restricted = path_hash == management::status_path_hash()
1238 || path_hash == management::path_path_hash();
1239
1240 if is_restricted && !self.management_config.remote_management_allowed.is_empty() {
1241 match remote_identity {
1242 Some((identity_hash, _)) => {
1243 if !self.management_config.remote_management_allowed.contains(&identity_hash) {
1244 log::debug!("Management request denied: identity not in allowed list");
1245 return;
1246 }
1247 }
1248 None => {
1249 log::debug!("Management request denied: peer not identified");
1250 return;
1251 }
1252 }
1253 }
1254
1255 let response_data = if path_hash == management::status_path_hash() {
1256 management::handle_status_request(&data, &self.engine, &self.interfaces, self.started)
1257 } else if path_hash == management::path_path_hash() {
1258 management::handle_path_request(&data, &self.engine)
1259 } else if path_hash == management::list_path_hash() {
1260 management::handle_blackhole_list_request(&self.engine)
1261 } else {
1262 log::warn!("Unknown management path_hash: {:02x?}", &path_hash[..4]);
1263 None
1264 };
1265
1266 if let Some(response) = response_data {
1267 let actions = self.link_manager.send_management_response(
1268 &link_id, &request_id, &response, &mut self.rng,
1269 );
1270 self.dispatch_link_actions(actions);
1271 }
1272 }
1273}
1274
1275#[cfg(test)]
1276mod tests {
1277 use super::*;
1278 use crate::event;
1279 use crate::interface::Writer;
1280 use rns_core::announce::AnnounceData;
1281 use rns_core::constants;
1282 use rns_core::packet::PacketFlags;
1283 use rns_core::transport::types::InterfaceInfo;
1284 use rns_crypto::identity::Identity;
1285 use std::io;
1286 use std::sync::mpsc;
1287 use std::sync::{Arc, Mutex};
1288
1289 struct MockWriter {
1290 sent: Arc<Mutex<Vec<Vec<u8>>>>,
1291 }
1292
1293 impl MockWriter {
1294 fn new() -> (Self, Arc<Mutex<Vec<Vec<u8>>>>) {
1295 let sent = Arc::new(Mutex::new(Vec::new()));
1296 (MockWriter { sent: sent.clone() }, sent)
1297 }
1298 }
1299
1300 impl Writer for MockWriter {
1301 fn send_frame(&mut self, data: &[u8]) -> io::Result<()> {
1302 self.sent.lock().unwrap().push(data.to_vec());
1303 Ok(())
1304 }
1305 }
1306
1307 use rns_core::types::{DestHash, IdentityHash, LinkId as TypedLinkId, PacketHash};
1308
1309 struct MockCallbacks {
1310 announces: Arc<Mutex<Vec<(DestHash, u8)>>>,
1311 paths: Arc<Mutex<Vec<(DestHash, u8)>>>,
1312 deliveries: Arc<Mutex<Vec<DestHash>>>,
1313 iface_ups: Arc<Mutex<Vec<InterfaceId>>>,
1314 iface_downs: Arc<Mutex<Vec<InterfaceId>>>,
1315 link_established: Arc<Mutex<Vec<(TypedLinkId, f64, bool)>>>,
1316 link_closed: Arc<Mutex<Vec<TypedLinkId>>>,
1317 remote_identified: Arc<Mutex<Vec<(TypedLinkId, IdentityHash)>>>,
1318 resources_received: Arc<Mutex<Vec<(TypedLinkId, Vec<u8>)>>>,
1319 resource_completed: Arc<Mutex<Vec<TypedLinkId>>>,
1320 resource_failed: Arc<Mutex<Vec<(TypedLinkId, String)>>>,
1321 channel_messages: Arc<Mutex<Vec<(TypedLinkId, u16, Vec<u8>)>>>,
1322 link_data: Arc<Mutex<Vec<(TypedLinkId, u8, Vec<u8>)>>>,
1323 responses: Arc<Mutex<Vec<(TypedLinkId, [u8; 16], Vec<u8>)>>>,
1324 proofs: Arc<Mutex<Vec<(DestHash, PacketHash, f64)>>>,
1325 proof_requested: Arc<Mutex<Vec<(DestHash, PacketHash)>>>,
1326 }
1327
1328 impl MockCallbacks {
1329 fn new() -> (
1330 Self,
1331 Arc<Mutex<Vec<(DestHash, u8)>>>,
1332 Arc<Mutex<Vec<(DestHash, u8)>>>,
1333 Arc<Mutex<Vec<DestHash>>>,
1334 Arc<Mutex<Vec<InterfaceId>>>,
1335 Arc<Mutex<Vec<InterfaceId>>>,
1336 ) {
1337 let announces = Arc::new(Mutex::new(Vec::new()));
1338 let paths = Arc::new(Mutex::new(Vec::new()));
1339 let deliveries = Arc::new(Mutex::new(Vec::new()));
1340 let iface_ups = Arc::new(Mutex::new(Vec::new()));
1341 let iface_downs = Arc::new(Mutex::new(Vec::new()));
1342 (
1343 MockCallbacks {
1344 announces: announces.clone(),
1345 paths: paths.clone(),
1346 deliveries: deliveries.clone(),
1347 iface_ups: iface_ups.clone(),
1348 iface_downs: iface_downs.clone(),
1349 link_established: Arc::new(Mutex::new(Vec::new())),
1350 link_closed: Arc::new(Mutex::new(Vec::new())),
1351 remote_identified: Arc::new(Mutex::new(Vec::new())),
1352 resources_received: Arc::new(Mutex::new(Vec::new())),
1353 resource_completed: Arc::new(Mutex::new(Vec::new())),
1354 resource_failed: Arc::new(Mutex::new(Vec::new())),
1355 channel_messages: Arc::new(Mutex::new(Vec::new())),
1356 link_data: Arc::new(Mutex::new(Vec::new())),
1357 responses: Arc::new(Mutex::new(Vec::new())),
1358 proofs: Arc::new(Mutex::new(Vec::new())),
1359 proof_requested: Arc::new(Mutex::new(Vec::new())),
1360 },
1361 announces,
1362 paths,
1363 deliveries,
1364 iface_ups,
1365 iface_downs,
1366 )
1367 }
1368
1369 fn with_link_tracking() -> (
1370 Self,
1371 Arc<Mutex<Vec<(TypedLinkId, f64, bool)>>>,
1372 Arc<Mutex<Vec<TypedLinkId>>>,
1373 Arc<Mutex<Vec<(TypedLinkId, IdentityHash)>>>,
1374 ) {
1375 let link_established = Arc::new(Mutex::new(Vec::new()));
1376 let link_closed = Arc::new(Mutex::new(Vec::new()));
1377 let remote_identified = Arc::new(Mutex::new(Vec::new()));
1378 (
1379 MockCallbacks {
1380 announces: Arc::new(Mutex::new(Vec::new())),
1381 paths: Arc::new(Mutex::new(Vec::new())),
1382 deliveries: Arc::new(Mutex::new(Vec::new())),
1383 iface_ups: Arc::new(Mutex::new(Vec::new())),
1384 iface_downs: Arc::new(Mutex::new(Vec::new())),
1385 link_established: link_established.clone(),
1386 link_closed: link_closed.clone(),
1387 remote_identified: remote_identified.clone(),
1388 resources_received: Arc::new(Mutex::new(Vec::new())),
1389 resource_completed: Arc::new(Mutex::new(Vec::new())),
1390 resource_failed: Arc::new(Mutex::new(Vec::new())),
1391 channel_messages: Arc::new(Mutex::new(Vec::new())),
1392 link_data: Arc::new(Mutex::new(Vec::new())),
1393 responses: Arc::new(Mutex::new(Vec::new())),
1394 proofs: Arc::new(Mutex::new(Vec::new())),
1395 proof_requested: Arc::new(Mutex::new(Vec::new())),
1396 },
1397 link_established,
1398 link_closed,
1399 remote_identified,
1400 )
1401 }
1402 }
1403
1404 impl Callbacks for MockCallbacks {
1405 fn on_announce(&mut self, announced: crate::destination::AnnouncedIdentity) {
1406 self.announces.lock().unwrap().push((announced.dest_hash, announced.hops));
1407 }
1408
1409 fn on_path_updated(&mut self, dest_hash: DestHash, hops: u8) {
1410 self.paths.lock().unwrap().push((dest_hash, hops));
1411 }
1412
1413 fn on_local_delivery(&mut self, dest_hash: DestHash, _raw: Vec<u8>, _packet_hash: PacketHash) {
1414 self.deliveries.lock().unwrap().push(dest_hash);
1415 }
1416
1417 fn on_interface_up(&mut self, id: InterfaceId) {
1418 self.iface_ups.lock().unwrap().push(id);
1419 }
1420
1421 fn on_interface_down(&mut self, id: InterfaceId) {
1422 self.iface_downs.lock().unwrap().push(id);
1423 }
1424
1425 fn on_link_established(&mut self, link_id: TypedLinkId, _dest_hash: DestHash, rtt: f64, is_initiator: bool) {
1426 self.link_established.lock().unwrap().push((link_id, rtt, is_initiator));
1427 }
1428
1429 fn on_link_closed(&mut self, link_id: TypedLinkId, _reason: Option<rns_core::link::TeardownReason>) {
1430 self.link_closed.lock().unwrap().push(link_id);
1431 }
1432
1433 fn on_remote_identified(&mut self, link_id: TypedLinkId, identity_hash: IdentityHash, _public_key: [u8; 64]) {
1434 self.remote_identified.lock().unwrap().push((link_id, identity_hash));
1435 }
1436
1437 fn on_resource_received(&mut self, link_id: TypedLinkId, data: Vec<u8>, _metadata: Option<Vec<u8>>) {
1438 self.resources_received.lock().unwrap().push((link_id, data));
1439 }
1440
1441 fn on_resource_completed(&mut self, link_id: TypedLinkId) {
1442 self.resource_completed.lock().unwrap().push(link_id);
1443 }
1444
1445 fn on_resource_failed(&mut self, link_id: TypedLinkId, error: String) {
1446 self.resource_failed.lock().unwrap().push((link_id, error));
1447 }
1448
1449 fn on_channel_message(&mut self, link_id: TypedLinkId, msgtype: u16, payload: Vec<u8>) {
1450 self.channel_messages.lock().unwrap().push((link_id, msgtype, payload));
1451 }
1452
1453 fn on_link_data(&mut self, link_id: TypedLinkId, context: u8, data: Vec<u8>) {
1454 self.link_data.lock().unwrap().push((link_id, context, data));
1455 }
1456
1457 fn on_response(&mut self, link_id: TypedLinkId, request_id: [u8; 16], data: Vec<u8>) {
1458 self.responses.lock().unwrap().push((link_id, request_id, data));
1459 }
1460
1461 fn on_proof(&mut self, dest_hash: DestHash, packet_hash: PacketHash, rtt: f64) {
1462 self.proofs.lock().unwrap().push((dest_hash, packet_hash, rtt));
1463 }
1464
1465 fn on_proof_requested(&mut self, dest_hash: DestHash, packet_hash: PacketHash) -> bool {
1466 self.proof_requested.lock().unwrap().push((dest_hash, packet_hash));
1467 true
1468 }
1469 }
1470
1471 fn make_interface_info(id: u64) -> InterfaceInfo {
1472 InterfaceInfo {
1473 id: InterfaceId(id),
1474 name: format!("test-{}", id),
1475 mode: constants::MODE_FULL,
1476 out_capable: true,
1477 in_capable: true,
1478 bitrate: None,
1479 announce_rate_target: None,
1480 announce_rate_grace: 0,
1481 announce_rate_penalty: 0.0,
1482 announce_cap: rns_core::constants::ANNOUNCE_CAP,
1483 is_local_client: false,
1484 wants_tunnel: false,
1485 tunnel_id: None,
1486 }
1487 }
1488
1489 fn make_entry(id: u64, writer: Box<dyn Writer>, online: bool) -> InterfaceEntry {
1490 InterfaceEntry {
1491 id: InterfaceId(id),
1492 info: make_interface_info(id),
1493 writer,
1494 online,
1495 dynamic: false,
1496 ifac: None,
1497 stats: InterfaceStats::default(),
1498 interface_type: String::new(),
1499 }
1500 }
1501
1502 fn build_announce_packet(identity: &Identity) -> Vec<u8> {
1504 let dest_hash = rns_core::destination::destination_hash(
1505 "test",
1506 &["app"],
1507 Some(identity.hash()),
1508 );
1509 let name_hash = rns_core::destination::name_hash("test", &["app"]);
1510 let random_hash = [0x42u8; 10];
1511
1512 let (announce_data, _has_ratchet) = AnnounceData::pack(
1513 identity,
1514 &dest_hash,
1515 &name_hash,
1516 &random_hash,
1517 None,
1518 None,
1519 )
1520 .unwrap();
1521
1522 let flags = PacketFlags {
1523 header_type: constants::HEADER_1,
1524 context_flag: constants::FLAG_UNSET,
1525 transport_type: constants::TRANSPORT_BROADCAST,
1526 destination_type: constants::DESTINATION_SINGLE,
1527 packet_type: constants::PACKET_TYPE_ANNOUNCE,
1528 };
1529
1530 let packet = RawPacket::pack(flags, 0, &dest_hash, None, constants::CONTEXT_NONE, &announce_data).unwrap();
1531 packet.raw
1532 }
1533
1534 #[test]
1535 fn process_inbound_frame() {
1536 let (tx, rx) = event::channel();
1537 let (cbs, announces, _, _, _, _) = MockCallbacks::new();
1538 let mut driver = Driver::new(
1539 TransportConfig { transport_enabled: false, identity_hash: None },
1540 rx,
1541 Box::new(cbs),
1542 );
1543 let info = make_interface_info(1);
1544 driver.engine.register_interface(info.clone());
1545 let (writer, _sent) = MockWriter::new();
1546 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
1547
1548 let identity = Identity::new(&mut OsRng);
1549 let announce_raw = build_announce_packet(&identity);
1550
1551 tx.send(Event::Frame { interface_id: InterfaceId(1), data: announce_raw }).unwrap();
1553 tx.send(Event::Shutdown).unwrap();
1554 driver.run();
1555
1556 assert_eq!(announces.lock().unwrap().len(), 1);
1557 }
1558
1559 #[test]
1560 fn dispatch_send() {
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 let (writer, sent) = MockWriter::new();
1569 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
1570
1571 driver.dispatch_all(vec![TransportAction::SendOnInterface {
1572 interface: InterfaceId(1),
1573 raw: vec![0x01, 0x02, 0x03],
1574 }]);
1575
1576 assert_eq!(sent.lock().unwrap().len(), 1);
1577 assert_eq!(sent.lock().unwrap()[0], vec![0x01, 0x02, 0x03]);
1578
1579 drop(tx);
1580 }
1581
1582 #[test]
1583 fn dispatch_broadcast() {
1584 let (tx, rx) = event::channel();
1585 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1586 let mut driver = Driver::new(
1587 TransportConfig { transport_enabled: false, identity_hash: None },
1588 rx,
1589 Box::new(cbs),
1590 );
1591
1592 let (w1, sent1) = MockWriter::new();
1593 let (w2, sent2) = MockWriter::new();
1594 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(w1), true));
1595 driver.interfaces.insert(InterfaceId(2), make_entry(2, Box::new(w2), true));
1596
1597 driver.dispatch_all(vec![TransportAction::BroadcastOnAllInterfaces {
1598 raw: vec![0xAA],
1599 exclude: None,
1600 }]);
1601
1602 assert_eq!(sent1.lock().unwrap().len(), 1);
1603 assert_eq!(sent2.lock().unwrap().len(), 1);
1604
1605 drop(tx);
1606 }
1607
1608 #[test]
1609 fn dispatch_broadcast_exclude() {
1610 let (tx, rx) = event::channel();
1611 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1612 let mut driver = Driver::new(
1613 TransportConfig { transport_enabled: false, identity_hash: None },
1614 rx,
1615 Box::new(cbs),
1616 );
1617
1618 let (w1, sent1) = MockWriter::new();
1619 let (w2, sent2) = MockWriter::new();
1620 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(w1), true));
1621 driver.interfaces.insert(InterfaceId(2), make_entry(2, Box::new(w2), true));
1622
1623 driver.dispatch_all(vec![TransportAction::BroadcastOnAllInterfaces {
1624 raw: vec![0xBB],
1625 exclude: Some(InterfaceId(1)),
1626 }]);
1627
1628 assert_eq!(sent1.lock().unwrap().len(), 0); assert_eq!(sent2.lock().unwrap().len(), 1);
1630
1631 drop(tx);
1632 }
1633
1634 #[test]
1635 fn tick_event() {
1636 let (tx, rx) = event::channel();
1637 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1638 let mut driver = Driver::new(
1639 TransportConfig { transport_enabled: true, identity_hash: Some([0x42; 16]) },
1640 rx,
1641 Box::new(cbs),
1642 );
1643 let info = make_interface_info(1);
1644 driver.engine.register_interface(info.clone());
1645 let (writer, _sent) = MockWriter::new();
1646 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
1647
1648 tx.send(Event::Tick).unwrap();
1650 tx.send(Event::Shutdown).unwrap();
1651 driver.run();
1652 }
1654
1655 #[test]
1656 fn shutdown_event() {
1657 let (tx, rx) = event::channel();
1658 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1659 let mut driver = Driver::new(
1660 TransportConfig { transport_enabled: false, identity_hash: None },
1661 rx,
1662 Box::new(cbs),
1663 );
1664
1665 tx.send(Event::Shutdown).unwrap();
1666 driver.run(); }
1668
1669 #[test]
1670 fn announce_callback() {
1671 let (tx, rx) = event::channel();
1672 let (cbs, announces, paths, _, _, _) = MockCallbacks::new();
1673 let mut driver = Driver::new(
1674 TransportConfig { transport_enabled: false, identity_hash: None },
1675 rx,
1676 Box::new(cbs),
1677 );
1678 let info = make_interface_info(1);
1679 driver.engine.register_interface(info.clone());
1680 let (writer, _sent) = MockWriter::new();
1681 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
1682
1683 let identity = Identity::new(&mut OsRng);
1684 let announce_raw = build_announce_packet(&identity);
1685
1686 tx.send(Event::Frame { interface_id: InterfaceId(1), data: announce_raw }).unwrap();
1687 tx.send(Event::Shutdown).unwrap();
1688 driver.run();
1689
1690 let ann = announces.lock().unwrap();
1691 assert_eq!(ann.len(), 1);
1692 assert_eq!(ann[0].1, 1);
1694
1695 let p = paths.lock().unwrap();
1696 assert_eq!(p.len(), 1);
1697 }
1698
1699 #[test]
1700 fn dispatch_skips_offline_interface() {
1701 let (tx, rx) = event::channel();
1702 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1703 let mut driver = Driver::new(
1704 TransportConfig { transport_enabled: false, identity_hash: None },
1705 rx,
1706 Box::new(cbs),
1707 );
1708
1709 let (w1, sent1) = MockWriter::new();
1710 let (w2, sent2) = MockWriter::new();
1711 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(w1), false)); driver.interfaces.insert(InterfaceId(2), make_entry(2, Box::new(w2), true));
1713
1714 driver.dispatch_all(vec![TransportAction::SendOnInterface {
1716 interface: InterfaceId(1),
1717 raw: vec![0x01],
1718 }]);
1719 assert_eq!(sent1.lock().unwrap().len(), 0);
1720
1721 driver.dispatch_all(vec![TransportAction::BroadcastOnAllInterfaces {
1723 raw: vec![0x02],
1724 exclude: None,
1725 }]);
1726 assert_eq!(sent1.lock().unwrap().len(), 0); assert_eq!(sent2.lock().unwrap().len(), 1);
1728
1729 drop(tx);
1730 }
1731
1732 #[test]
1733 fn interface_up_refreshes_writer() {
1734 let (tx, rx) = event::channel();
1735 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1736 let mut driver = Driver::new(
1737 TransportConfig { transport_enabled: false, identity_hash: None },
1738 rx,
1739 Box::new(cbs),
1740 );
1741
1742 let (w_old, sent_old) = MockWriter::new();
1743 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(w_old), false));
1744
1745 let (w_new, sent_new) = MockWriter::new();
1747 tx.send(Event::InterfaceUp(InterfaceId(1), Some(Box::new(w_new)), None)).unwrap();
1748 tx.send(Event::Shutdown).unwrap();
1749 driver.run();
1750
1751 assert!(driver.interfaces[&InterfaceId(1)].online);
1753
1754 driver.dispatch_all(vec![TransportAction::SendOnInterface {
1756 interface: InterfaceId(1),
1757 raw: vec![0xFF],
1758 }]);
1759
1760 assert_eq!(sent_old.lock().unwrap().len(), 0);
1762 assert_eq!(sent_new.lock().unwrap().len(), 1);
1764 assert_eq!(sent_new.lock().unwrap()[0], vec![0xFF]);
1765
1766 drop(tx);
1767 }
1768
1769 #[test]
1770 fn dynamic_interface_register() {
1771 let (tx, rx) = event::channel();
1772 let (cbs, _, _, _, iface_ups, _) = MockCallbacks::new();
1773 let mut driver = Driver::new(
1774 TransportConfig { transport_enabled: false, identity_hash: None },
1775 rx,
1776 Box::new(cbs),
1777 );
1778
1779 let info = make_interface_info(100);
1780 let (writer, sent) = MockWriter::new();
1781
1782 tx.send(Event::InterfaceUp(
1784 InterfaceId(100),
1785 Some(Box::new(writer)),
1786 Some(info),
1787 ))
1788 .unwrap();
1789 tx.send(Event::Shutdown).unwrap();
1790 driver.run();
1791
1792 assert!(driver.interfaces.contains_key(&InterfaceId(100)));
1794 assert!(driver.interfaces[&InterfaceId(100)].online);
1795 assert!(driver.interfaces[&InterfaceId(100)].dynamic);
1796
1797 assert_eq!(iface_ups.lock().unwrap().len(), 1);
1799 assert_eq!(iface_ups.lock().unwrap()[0], InterfaceId(100));
1800
1801 driver.dispatch_all(vec![TransportAction::SendOnInterface {
1803 interface: InterfaceId(100),
1804 raw: vec![0x42],
1805 }]);
1806 assert_eq!(sent.lock().unwrap().len(), 1);
1807
1808 drop(tx);
1809 }
1810
1811 #[test]
1812 fn dynamic_interface_deregister() {
1813 let (tx, rx) = event::channel();
1814 let (cbs, _, _, _, _, iface_downs) = MockCallbacks::new();
1815 let mut driver = Driver::new(
1816 TransportConfig { transport_enabled: false, identity_hash: None },
1817 rx,
1818 Box::new(cbs),
1819 );
1820
1821 let info = make_interface_info(200);
1823 driver.engine.register_interface(info.clone());
1824 let (writer, _sent) = MockWriter::new();
1825 driver.interfaces.insert(InterfaceId(200), InterfaceEntry {
1826 id: InterfaceId(200),
1827 info,
1828 writer: Box::new(writer),
1829 online: true,
1830 dynamic: true,
1831 ifac: None,
1832 stats: InterfaceStats::default(),
1833 interface_type: String::new(),
1834 });
1835
1836 tx.send(Event::InterfaceDown(InterfaceId(200))).unwrap();
1838 tx.send(Event::Shutdown).unwrap();
1839 driver.run();
1840
1841 assert!(!driver.interfaces.contains_key(&InterfaceId(200)));
1842 assert_eq!(iface_downs.lock().unwrap().len(), 1);
1843 assert_eq!(iface_downs.lock().unwrap()[0], InterfaceId(200));
1844 }
1845
1846 #[test]
1847 fn interface_callbacks_fire() {
1848 let (tx, rx) = event::channel();
1849 let (cbs, _, _, _, iface_ups, iface_downs) = MockCallbacks::new();
1850 let mut driver = Driver::new(
1851 TransportConfig { transport_enabled: false, identity_hash: None },
1852 rx,
1853 Box::new(cbs),
1854 );
1855
1856 let (writer, _) = MockWriter::new();
1858 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), false));
1859
1860 tx.send(Event::InterfaceUp(InterfaceId(1), None, None)).unwrap();
1861 tx.send(Event::InterfaceDown(InterfaceId(1))).unwrap();
1862 tx.send(Event::Shutdown).unwrap();
1863 driver.run();
1864
1865 assert_eq!(iface_ups.lock().unwrap().len(), 1);
1866 assert_eq!(iface_downs.lock().unwrap().len(), 1);
1867 assert!(driver.interfaces.contains_key(&InterfaceId(1)));
1869 assert!(!driver.interfaces[&InterfaceId(1)].online);
1870 }
1871
1872 #[test]
1877 fn frame_updates_rx_stats() {
1878 let (tx, rx) = event::channel();
1879 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1880 let mut driver = Driver::new(
1881 TransportConfig { transport_enabled: false, identity_hash: None },
1882 rx,
1883 Box::new(cbs),
1884 );
1885 let info = make_interface_info(1);
1886 driver.engine.register_interface(info.clone());
1887 let (writer, _sent) = MockWriter::new();
1888 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
1889
1890 let identity = Identity::new(&mut OsRng);
1891 let announce_raw = build_announce_packet(&identity);
1892 let announce_len = announce_raw.len() as u64;
1893
1894 tx.send(Event::Frame { interface_id: InterfaceId(1), data: announce_raw }).unwrap();
1895 tx.send(Event::Shutdown).unwrap();
1896 driver.run();
1897
1898 let stats = &driver.interfaces[&InterfaceId(1)].stats;
1899 assert_eq!(stats.rxb, announce_len);
1900 assert_eq!(stats.rx_packets, 1);
1901 }
1902
1903 #[test]
1904 fn send_updates_tx_stats() {
1905 let (tx, rx) = event::channel();
1906 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1907 let mut driver = Driver::new(
1908 TransportConfig { transport_enabled: false, identity_hash: None },
1909 rx,
1910 Box::new(cbs),
1911 );
1912 let (writer, _sent) = MockWriter::new();
1913 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
1914
1915 driver.dispatch_all(vec![TransportAction::SendOnInterface {
1916 interface: InterfaceId(1),
1917 raw: vec![0x01, 0x02, 0x03],
1918 }]);
1919
1920 let stats = &driver.interfaces[&InterfaceId(1)].stats;
1921 assert_eq!(stats.txb, 3);
1922 assert_eq!(stats.tx_packets, 1);
1923
1924 drop(tx);
1925 }
1926
1927 #[test]
1928 fn broadcast_updates_tx_stats() {
1929 let (tx, rx) = event::channel();
1930 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1931 let mut driver = Driver::new(
1932 TransportConfig { transport_enabled: false, identity_hash: None },
1933 rx,
1934 Box::new(cbs),
1935 );
1936 let (w1, _s1) = MockWriter::new();
1937 let (w2, _s2) = MockWriter::new();
1938 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(w1), true));
1939 driver.interfaces.insert(InterfaceId(2), make_entry(2, Box::new(w2), true));
1940
1941 driver.dispatch_all(vec![TransportAction::BroadcastOnAllInterfaces {
1942 raw: vec![0xAA, 0xBB],
1943 exclude: None,
1944 }]);
1945
1946 assert_eq!(driver.interfaces[&InterfaceId(1)].stats.txb, 2);
1948 assert_eq!(driver.interfaces[&InterfaceId(1)].stats.tx_packets, 1);
1949 assert_eq!(driver.interfaces[&InterfaceId(2)].stats.txb, 2);
1950 assert_eq!(driver.interfaces[&InterfaceId(2)].stats.tx_packets, 1);
1951
1952 drop(tx);
1953 }
1954
1955 #[test]
1956 fn query_interface_stats() {
1957 let (tx, rx) = event::channel();
1958 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1959 let mut driver = Driver::new(
1960 TransportConfig { transport_enabled: true, identity_hash: Some([0x42; 16]) },
1961 rx,
1962 Box::new(cbs),
1963 );
1964 let (writer, _sent) = MockWriter::new();
1965 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
1966
1967 let (resp_tx, resp_rx) = mpsc::channel();
1968 tx.send(Event::Query(QueryRequest::InterfaceStats, resp_tx)).unwrap();
1969 tx.send(Event::Shutdown).unwrap();
1970 driver.run();
1971
1972 let resp = resp_rx.recv().unwrap();
1973 match resp {
1974 QueryResponse::InterfaceStats(stats) => {
1975 assert_eq!(stats.interfaces.len(), 1);
1976 assert_eq!(stats.interfaces[0].name, "test-1");
1977 assert!(stats.interfaces[0].status);
1978 assert_eq!(stats.transport_id, Some([0x42; 16]));
1979 assert!(stats.transport_enabled);
1980 }
1981 _ => panic!("unexpected response"),
1982 }
1983 }
1984
1985 #[test]
1986 fn query_path_table() {
1987 let (tx, rx) = event::channel();
1988 let (cbs, _, _, _, _, _) = MockCallbacks::new();
1989 let mut driver = Driver::new(
1990 TransportConfig { transport_enabled: false, identity_hash: None },
1991 rx,
1992 Box::new(cbs),
1993 );
1994 let info = make_interface_info(1);
1995 driver.engine.register_interface(info);
1996 let (writer, _sent) = MockWriter::new();
1997 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
1998
1999 let identity = Identity::new(&mut OsRng);
2001 let announce_raw = build_announce_packet(&identity);
2002 tx.send(Event::Frame { interface_id: InterfaceId(1), data: announce_raw }).unwrap();
2003
2004 let (resp_tx, resp_rx) = mpsc::channel();
2005 tx.send(Event::Query(QueryRequest::PathTable { max_hops: None }, resp_tx)).unwrap();
2006 tx.send(Event::Shutdown).unwrap();
2007 driver.run();
2008
2009 let resp = resp_rx.recv().unwrap();
2010 match resp {
2011 QueryResponse::PathTable(entries) => {
2012 assert_eq!(entries.len(), 1);
2013 assert_eq!(entries[0].hops, 1);
2014 }
2015 _ => panic!("unexpected response"),
2016 }
2017 }
2018
2019 #[test]
2020 fn query_drop_path() {
2021 let (tx, rx) = event::channel();
2022 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2023 let mut driver = Driver::new(
2024 TransportConfig { transport_enabled: false, identity_hash: None },
2025 rx,
2026 Box::new(cbs),
2027 );
2028 let info = make_interface_info(1);
2029 driver.engine.register_interface(info);
2030 let (writer, _sent) = MockWriter::new();
2031 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2032
2033 let identity = Identity::new(&mut OsRng);
2035 let announce_raw = build_announce_packet(&identity);
2036 let dest_hash = rns_core::destination::destination_hash(
2037 "test", &["app"], Some(identity.hash()),
2038 );
2039
2040 tx.send(Event::Frame { interface_id: InterfaceId(1), data: announce_raw }).unwrap();
2041
2042 let (resp_tx, resp_rx) = mpsc::channel();
2043 tx.send(Event::Query(QueryRequest::DropPath { dest_hash }, resp_tx)).unwrap();
2044 tx.send(Event::Shutdown).unwrap();
2045 driver.run();
2046
2047 let resp = resp_rx.recv().unwrap();
2048 match resp {
2049 QueryResponse::DropPath(dropped) => {
2050 assert!(dropped);
2051 }
2052 _ => panic!("unexpected response"),
2053 }
2054 }
2055
2056 #[test]
2057 fn send_outbound_event() {
2058 let (tx, rx) = event::channel();
2059 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2060 let mut driver = Driver::new(
2061 TransportConfig { transport_enabled: false, identity_hash: None },
2062 rx,
2063 Box::new(cbs),
2064 );
2065 let (writer, sent) = MockWriter::new();
2066 let info = make_interface_info(1);
2067 driver.engine.register_interface(info);
2068 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2069
2070 let dest = [0xAA; 16];
2072 let flags = PacketFlags {
2073 header_type: constants::HEADER_1,
2074 context_flag: constants::FLAG_UNSET,
2075 transport_type: constants::TRANSPORT_BROADCAST,
2076 destination_type: constants::DESTINATION_PLAIN,
2077 packet_type: constants::PACKET_TYPE_DATA,
2078 };
2079 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, b"hello").unwrap();
2080
2081 tx.send(Event::SendOutbound {
2082 raw: packet.raw,
2083 dest_type: constants::DESTINATION_PLAIN,
2084 attached_interface: None,
2085 }).unwrap();
2086 tx.send(Event::Shutdown).unwrap();
2087 driver.run();
2088
2089 assert_eq!(sent.lock().unwrap().len(), 1);
2091 }
2092
2093 #[test]
2094 fn register_destination_and_deliver() {
2095 let (tx, rx) = event::channel();
2096 let (cbs, _, _, deliveries, _, _) = MockCallbacks::new();
2097 let mut driver = Driver::new(
2098 TransportConfig { transport_enabled: false, identity_hash: None },
2099 rx,
2100 Box::new(cbs),
2101 );
2102 let info = make_interface_info(1);
2103 driver.engine.register_interface(info);
2104 let (writer, _sent) = MockWriter::new();
2105 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2106
2107 let dest = [0xBB; 16];
2108
2109 tx.send(Event::RegisterDestination {
2111 dest_hash: dest,
2112 dest_type: constants::DESTINATION_SINGLE,
2113 }).unwrap();
2114
2115 let flags = PacketFlags {
2116 header_type: constants::HEADER_1,
2117 context_flag: constants::FLAG_UNSET,
2118 transport_type: constants::TRANSPORT_BROADCAST,
2119 destination_type: constants::DESTINATION_SINGLE,
2120 packet_type: constants::PACKET_TYPE_DATA,
2121 };
2122 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, b"data").unwrap();
2123 tx.send(Event::Frame { interface_id: InterfaceId(1), data: packet.raw }).unwrap();
2124 tx.send(Event::Shutdown).unwrap();
2125 driver.run();
2126
2127 assert_eq!(deliveries.lock().unwrap().len(), 1);
2128 assert_eq!(deliveries.lock().unwrap()[0], DestHash(dest));
2129 }
2130
2131 #[test]
2132 fn query_transport_identity() {
2133 let (tx, rx) = event::channel();
2134 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2135 let mut driver = Driver::new(
2136 TransportConfig { transport_enabled: true, identity_hash: Some([0xAA; 16]) },
2137 rx,
2138 Box::new(cbs),
2139 );
2140
2141 let (resp_tx, resp_rx) = mpsc::channel();
2142 tx.send(Event::Query(QueryRequest::TransportIdentity, resp_tx)).unwrap();
2143 tx.send(Event::Shutdown).unwrap();
2144 driver.run();
2145
2146 match resp_rx.recv().unwrap() {
2147 QueryResponse::TransportIdentity(Some(hash)) => {
2148 assert_eq!(hash, [0xAA; 16]);
2149 }
2150 _ => panic!("unexpected response"),
2151 }
2152 }
2153
2154 #[test]
2155 fn query_link_count() {
2156 let (tx, rx) = event::channel();
2157 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2158 let mut driver = Driver::new(
2159 TransportConfig { transport_enabled: false, identity_hash: None },
2160 rx,
2161 Box::new(cbs),
2162 );
2163
2164 let (resp_tx, resp_rx) = mpsc::channel();
2165 tx.send(Event::Query(QueryRequest::LinkCount, resp_tx)).unwrap();
2166 tx.send(Event::Shutdown).unwrap();
2167 driver.run();
2168
2169 match resp_rx.recv().unwrap() {
2170 QueryResponse::LinkCount(count) => assert_eq!(count, 0),
2171 _ => panic!("unexpected response"),
2172 }
2173 }
2174
2175 #[test]
2176 fn query_rate_table() {
2177 let (tx, rx) = event::channel();
2178 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2179 let mut driver = Driver::new(
2180 TransportConfig { transport_enabled: false, identity_hash: None },
2181 rx,
2182 Box::new(cbs),
2183 );
2184
2185 let (resp_tx, resp_rx) = mpsc::channel();
2186 tx.send(Event::Query(QueryRequest::RateTable, resp_tx)).unwrap();
2187 tx.send(Event::Shutdown).unwrap();
2188 driver.run();
2189
2190 match resp_rx.recv().unwrap() {
2191 QueryResponse::RateTable(entries) => assert!(entries.is_empty()),
2192 _ => panic!("unexpected response"),
2193 }
2194 }
2195
2196 #[test]
2197 fn query_next_hop() {
2198 let (tx, rx) = event::channel();
2199 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2200 let mut driver = Driver::new(
2201 TransportConfig { transport_enabled: false, identity_hash: None },
2202 rx,
2203 Box::new(cbs),
2204 );
2205
2206 let dest = [0xBB; 16];
2207 let (resp_tx, resp_rx) = mpsc::channel();
2208 tx.send(Event::Query(QueryRequest::NextHop { dest_hash: dest }, resp_tx)).unwrap();
2209 tx.send(Event::Shutdown).unwrap();
2210 driver.run();
2211
2212 match resp_rx.recv().unwrap() {
2213 QueryResponse::NextHop(None) => {}
2214 _ => panic!("unexpected response"),
2215 }
2216 }
2217
2218 #[test]
2219 fn query_next_hop_if_name() {
2220 let (tx, rx) = event::channel();
2221 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2222 let mut driver = Driver::new(
2223 TransportConfig { transport_enabled: false, identity_hash: None },
2224 rx,
2225 Box::new(cbs),
2226 );
2227
2228 let dest = [0xCC; 16];
2229 let (resp_tx, resp_rx) = mpsc::channel();
2230 tx.send(Event::Query(QueryRequest::NextHopIfName { dest_hash: dest }, resp_tx)).unwrap();
2231 tx.send(Event::Shutdown).unwrap();
2232 driver.run();
2233
2234 match resp_rx.recv().unwrap() {
2235 QueryResponse::NextHopIfName(None) => {}
2236 _ => panic!("unexpected response"),
2237 }
2238 }
2239
2240 #[test]
2241 fn query_drop_all_via() {
2242 let (tx, rx) = event::channel();
2243 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2244 let mut driver = Driver::new(
2245 TransportConfig { transport_enabled: false, identity_hash: None },
2246 rx,
2247 Box::new(cbs),
2248 );
2249
2250 let transport = [0xDD; 16];
2251 let (resp_tx, resp_rx) = mpsc::channel();
2252 tx.send(Event::Query(
2253 QueryRequest::DropAllVia { transport_hash: transport },
2254 resp_tx,
2255 )).unwrap();
2256 tx.send(Event::Shutdown).unwrap();
2257 driver.run();
2258
2259 match resp_rx.recv().unwrap() {
2260 QueryResponse::DropAllVia(count) => assert_eq!(count, 0),
2261 _ => panic!("unexpected response"),
2262 }
2263 }
2264
2265 #[test]
2266 fn query_drop_announce_queues() {
2267 let (tx, rx) = event::channel();
2268 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2269 let mut driver = Driver::new(
2270 TransportConfig { transport_enabled: false, identity_hash: None },
2271 rx,
2272 Box::new(cbs),
2273 );
2274
2275 let (resp_tx, resp_rx) = mpsc::channel();
2276 tx.send(Event::Query(QueryRequest::DropAnnounceQueues, resp_tx)).unwrap();
2277 tx.send(Event::Shutdown).unwrap();
2278 driver.run();
2279
2280 match resp_rx.recv().unwrap() {
2281 QueryResponse::DropAnnounceQueues => {}
2282 _ => panic!("unexpected response"),
2283 }
2284 }
2285
2286 #[test]
2291 fn register_link_dest_event() {
2292 let (tx, rx) = event::channel();
2293 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2294 let mut driver = Driver::new(
2295 TransportConfig { transport_enabled: false, identity_hash: None },
2296 rx,
2297 Box::new(cbs),
2298 );
2299 let info = make_interface_info(1);
2300 driver.engine.register_interface(info);
2301 let (writer, _sent) = MockWriter::new();
2302 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2303
2304 let mut rng = OsRng;
2305 let sig_prv = rns_crypto::ed25519::Ed25519PrivateKey::generate(&mut rng);
2306 let sig_pub_bytes = sig_prv.public_key().public_bytes();
2307 let sig_prv_bytes = sig_prv.private_bytes();
2308 let dest_hash = [0xDD; 16];
2309
2310 tx.send(Event::RegisterLinkDestination {
2311 dest_hash,
2312 sig_prv_bytes,
2313 sig_pub_bytes,
2314 }).unwrap();
2315 tx.send(Event::Shutdown).unwrap();
2316 driver.run();
2317
2318 assert!(driver.link_manager.is_link_destination(&dest_hash));
2320 }
2321
2322 #[test]
2323 fn create_link_event() {
2324 let (tx, rx) = event::channel();
2325 let (cbs, _link_established, _, _) = MockCallbacks::with_link_tracking();
2326 let mut driver = Driver::new(
2327 TransportConfig { transport_enabled: false, identity_hash: None },
2328 rx,
2329 Box::new(cbs),
2330 );
2331 let info = make_interface_info(1);
2332 driver.engine.register_interface(info);
2333 let (writer, _sent) = MockWriter::new();
2334 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2335
2336 let dest_hash = [0xDD; 16];
2337 let dummy_sig_pub = [0xAA; 32];
2338
2339 let (resp_tx, resp_rx) = mpsc::channel();
2340 tx.send(Event::CreateLink {
2341 dest_hash,
2342 dest_sig_pub_bytes: dummy_sig_pub,
2343 response_tx: resp_tx,
2344 }).unwrap();
2345 tx.send(Event::Shutdown).unwrap();
2346 driver.run();
2347
2348 let link_id = resp_rx.recv().unwrap();
2350 assert_ne!(link_id, [0u8; 16]);
2351
2352 assert_eq!(driver.link_manager.link_count(), 1);
2354
2355 }
2360
2361 #[test]
2362 fn deliver_local_routes_to_link_manager() {
2363 let (tx, rx) = event::channel();
2366 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2367 let mut driver = Driver::new(
2368 TransportConfig { transport_enabled: false, identity_hash: None },
2369 rx,
2370 Box::new(cbs),
2371 );
2372 let info = make_interface_info(1);
2373 driver.engine.register_interface(info);
2374 let (writer, _sent) = MockWriter::new();
2375 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2376
2377 let mut rng = OsRng;
2379 let sig_prv = rns_crypto::ed25519::Ed25519PrivateKey::generate(&mut rng);
2380 let sig_pub_bytes = sig_prv.public_key().public_bytes();
2381 let dest_hash = [0xEE; 16];
2382 driver.link_manager.register_link_destination(dest_hash, sig_prv, sig_pub_bytes);
2383
2384 assert!(driver.link_manager.is_link_destination(&dest_hash));
2388
2389 assert!(!driver.link_manager.is_link_destination(&[0xFF; 16]));
2391
2392 drop(tx);
2393 }
2394
2395 #[test]
2396 fn teardown_link_event() {
2397 let (tx, rx) = event::channel();
2398 let (cbs, _, link_closed, _) = MockCallbacks::with_link_tracking();
2399 let mut driver = Driver::new(
2400 TransportConfig { transport_enabled: false, identity_hash: None },
2401 rx,
2402 Box::new(cbs),
2403 );
2404 let info = make_interface_info(1);
2405 driver.engine.register_interface(info);
2406 let (writer, _sent) = MockWriter::new();
2407 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2408
2409 let (resp_tx, resp_rx) = mpsc::channel();
2411 tx.send(Event::CreateLink {
2412 dest_hash: [0xDD; 16],
2413 dest_sig_pub_bytes: [0xAA; 32],
2414 response_tx: resp_tx,
2415 }).unwrap();
2416 tx.send(Event::Shutdown).unwrap();
2421 driver.run();
2422
2423 let link_id = resp_rx.recv().unwrap();
2424 assert_ne!(link_id, [0u8; 16]);
2425 assert_eq!(driver.link_manager.link_count(), 1);
2426
2427 let teardown_actions = driver.link_manager.teardown_link(&link_id);
2429 driver.dispatch_link_actions(teardown_actions);
2430
2431 assert_eq!(link_closed.lock().unwrap().len(), 1);
2433 assert_eq!(link_closed.lock().unwrap()[0], TypedLinkId(link_id));
2434 }
2435
2436 #[test]
2437 fn link_count_includes_link_manager() {
2438 let (tx, rx) = event::channel();
2439 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2440 let mut driver = Driver::new(
2441 TransportConfig { transport_enabled: false, identity_hash: None },
2442 rx,
2443 Box::new(cbs),
2444 );
2445 let info = make_interface_info(1);
2446 driver.engine.register_interface(info);
2447 let (writer, _sent) = MockWriter::new();
2448 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2449
2450 let mut rng = OsRng;
2452 let dummy_sig = [0xAA; 32];
2453 driver.link_manager.create_link(&[0xDD; 16], &dummy_sig, 1, &mut rng);
2454
2455 let (resp_tx, resp_rx) = mpsc::channel();
2457 tx.send(Event::Query(QueryRequest::LinkCount, resp_tx)).unwrap();
2458 tx.send(Event::Shutdown).unwrap();
2459 driver.run();
2460
2461 match resp_rx.recv().unwrap() {
2462 QueryResponse::LinkCount(count) => assert_eq!(count, 1),
2463 _ => panic!("unexpected response"),
2464 }
2465 }
2466
2467 #[test]
2468 fn register_request_handler_event() {
2469 let (tx, rx) = event::channel();
2470 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2471 let mut driver = Driver::new(
2472 TransportConfig { transport_enabled: false, identity_hash: None },
2473 rx,
2474 Box::new(cbs),
2475 );
2476
2477 tx.send(Event::RegisterRequestHandler {
2478 path: "/status".to_string(),
2479 allowed_list: None,
2480 handler: Box::new(|_link_id, _path, _data, _remote| Some(b"OK".to_vec())),
2481 }).unwrap();
2482 tx.send(Event::Shutdown).unwrap();
2483 driver.run();
2484
2485 }
2488
2489 #[test]
2492 fn management_announces_emitted_after_delay() {
2493 let (tx, rx) = event::channel();
2494 let (cbs, announces, _, _, _, _) = MockCallbacks::new();
2495 let identity = Identity::new(&mut OsRng);
2496 let identity_hash = *identity.hash();
2497 let mut driver = Driver::new(
2498 TransportConfig { transport_enabled: true, identity_hash: Some(identity_hash) },
2499 rx,
2500 Box::new(cbs),
2501 );
2502
2503 let info = make_interface_info(1);
2505 driver.engine.register_interface(info.clone());
2506 let (writer, sent) = MockWriter::new();
2507 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2508
2509 driver.management_config.enable_remote_management = true;
2511 driver.transport_identity = Some(identity);
2512
2513 driver.started = time::now() - 10.0;
2515
2516 tx.send(Event::Tick).unwrap();
2518 tx.send(Event::Shutdown).unwrap();
2519 driver.run();
2520
2521 let sent_packets = sent.lock().unwrap();
2523 assert!(!sent_packets.is_empty(),
2524 "Management announce should be sent after startup delay");
2525 }
2526
2527 #[test]
2528 fn management_announces_not_emitted_when_disabled() {
2529 let (tx, rx) = event::channel();
2530 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2531 let identity = Identity::new(&mut OsRng);
2532 let identity_hash = *identity.hash();
2533 let mut driver = Driver::new(
2534 TransportConfig { transport_enabled: true, identity_hash: Some(identity_hash) },
2535 rx,
2536 Box::new(cbs),
2537 );
2538
2539 let info = make_interface_info(1);
2540 driver.engine.register_interface(info.clone());
2541 let (writer, sent) = MockWriter::new();
2542 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2543
2544 driver.transport_identity = Some(identity);
2546 driver.started = time::now() - 10.0;
2547
2548 tx.send(Event::Tick).unwrap();
2549 tx.send(Event::Shutdown).unwrap();
2550 driver.run();
2551
2552 let sent_packets = sent.lock().unwrap();
2554 assert!(sent_packets.is_empty(),
2555 "No announces should be sent when management is disabled");
2556 }
2557
2558 #[test]
2559 fn management_announces_not_emitted_before_delay() {
2560 let (tx, rx) = event::channel();
2561 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2562 let identity = Identity::new(&mut OsRng);
2563 let identity_hash = *identity.hash();
2564 let mut driver = Driver::new(
2565 TransportConfig { transport_enabled: true, identity_hash: Some(identity_hash) },
2566 rx,
2567 Box::new(cbs),
2568 );
2569
2570 let info = make_interface_info(1);
2571 driver.engine.register_interface(info.clone());
2572 let (writer, sent) = MockWriter::new();
2573 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2574
2575 driver.management_config.enable_remote_management = true;
2576 driver.transport_identity = Some(identity);
2577 driver.started = time::now();
2579
2580 tx.send(Event::Tick).unwrap();
2581 tx.send(Event::Shutdown).unwrap();
2582 driver.run();
2583
2584 let sent_packets = sent.lock().unwrap();
2585 assert!(sent_packets.is_empty(),
2586 "No announces before startup delay");
2587 }
2588
2589 #[test]
2594 fn announce_received_populates_known_destinations() {
2595 let (tx, rx) = event::channel();
2596 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2597 let mut driver = Driver::new(
2598 TransportConfig { transport_enabled: false, identity_hash: None },
2599 rx,
2600 Box::new(cbs),
2601 );
2602 let info = make_interface_info(1);
2603 driver.engine.register_interface(info);
2604 let (writer, _sent) = MockWriter::new();
2605 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2606
2607 let identity = Identity::new(&mut OsRng);
2608 let announce_raw = build_announce_packet(&identity);
2609
2610 let dest_hash = rns_core::destination::destination_hash(
2611 "test", &["app"], Some(identity.hash()),
2612 );
2613
2614 tx.send(Event::Frame { interface_id: InterfaceId(1), data: announce_raw }).unwrap();
2615 tx.send(Event::Shutdown).unwrap();
2616 driver.run();
2617
2618 assert!(driver.known_destinations.contains_key(&dest_hash));
2620 let recalled = &driver.known_destinations[&dest_hash];
2621 assert_eq!(recalled.dest_hash.0, dest_hash);
2622 assert_eq!(recalled.identity_hash.0, *identity.hash());
2623 assert_eq!(&recalled.public_key, &identity.get_public_key().unwrap());
2624 assert_eq!(recalled.hops, 1);
2625 }
2626
2627 #[test]
2628 fn query_has_path() {
2629 let (tx, rx) = event::channel();
2630 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2631 let mut driver = Driver::new(
2632 TransportConfig { transport_enabled: false, identity_hash: None },
2633 rx,
2634 Box::new(cbs),
2635 );
2636 let info = make_interface_info(1);
2637 driver.engine.register_interface(info);
2638 let (writer, _sent) = MockWriter::new();
2639 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2640
2641 let (resp_tx, resp_rx) = mpsc::channel();
2643 tx.send(Event::Query(QueryRequest::HasPath { dest_hash: [0xAA; 16] }, resp_tx)).unwrap();
2644
2645 let identity = Identity::new(&mut OsRng);
2647 let announce_raw = build_announce_packet(&identity);
2648 let dest_hash = rns_core::destination::destination_hash(
2649 "test", &["app"], Some(identity.hash()),
2650 );
2651 tx.send(Event::Frame { interface_id: InterfaceId(1), data: announce_raw }).unwrap();
2652
2653 let (resp_tx2, resp_rx2) = mpsc::channel();
2654 tx.send(Event::Query(QueryRequest::HasPath { dest_hash }, resp_tx2)).unwrap();
2655
2656 tx.send(Event::Shutdown).unwrap();
2657 driver.run();
2658
2659 match resp_rx.recv().unwrap() {
2661 QueryResponse::HasPath(false) => {}
2662 other => panic!("expected HasPath(false), got {:?}", other),
2663 }
2664
2665 match resp_rx2.recv().unwrap() {
2667 QueryResponse::HasPath(true) => {}
2668 other => panic!("expected HasPath(true), got {:?}", other),
2669 }
2670 }
2671
2672 #[test]
2673 fn query_hops_to() {
2674 let (tx, rx) = event::channel();
2675 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2676 let mut driver = Driver::new(
2677 TransportConfig { transport_enabled: false, identity_hash: None },
2678 rx,
2679 Box::new(cbs),
2680 );
2681 let info = make_interface_info(1);
2682 driver.engine.register_interface(info);
2683 let (writer, _sent) = MockWriter::new();
2684 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2685
2686 let identity = Identity::new(&mut OsRng);
2688 let announce_raw = build_announce_packet(&identity);
2689 let dest_hash = rns_core::destination::destination_hash(
2690 "test", &["app"], Some(identity.hash()),
2691 );
2692
2693 tx.send(Event::Frame { interface_id: InterfaceId(1), data: announce_raw }).unwrap();
2694
2695 let (resp_tx, resp_rx) = mpsc::channel();
2696 tx.send(Event::Query(QueryRequest::HopsTo { dest_hash }, resp_tx)).unwrap();
2697 tx.send(Event::Shutdown).unwrap();
2698 driver.run();
2699
2700 match resp_rx.recv().unwrap() {
2701 QueryResponse::HopsTo(Some(1)) => {}
2702 other => panic!("expected HopsTo(Some(1)), got {:?}", other),
2703 }
2704 }
2705
2706 #[test]
2707 fn query_recall_identity() {
2708 let (tx, rx) = event::channel();
2709 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2710 let mut driver = Driver::new(
2711 TransportConfig { transport_enabled: false, identity_hash: None },
2712 rx,
2713 Box::new(cbs),
2714 );
2715 let info = make_interface_info(1);
2716 driver.engine.register_interface(info);
2717 let (writer, _sent) = MockWriter::new();
2718 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2719
2720 let identity = Identity::new(&mut OsRng);
2721 let announce_raw = build_announce_packet(&identity);
2722 let dest_hash = rns_core::destination::destination_hash(
2723 "test", &["app"], Some(identity.hash()),
2724 );
2725
2726 tx.send(Event::Frame { interface_id: InterfaceId(1), data: announce_raw }).unwrap();
2727
2728 let (resp_tx, resp_rx) = mpsc::channel();
2730 tx.send(Event::Query(QueryRequest::RecallIdentity { dest_hash }, resp_tx)).unwrap();
2731
2732 let (resp_tx2, resp_rx2) = mpsc::channel();
2734 tx.send(Event::Query(QueryRequest::RecallIdentity { dest_hash: [0xFF; 16] }, resp_tx2)).unwrap();
2735
2736 tx.send(Event::Shutdown).unwrap();
2737 driver.run();
2738
2739 match resp_rx.recv().unwrap() {
2740 QueryResponse::RecallIdentity(Some(recalled)) => {
2741 assert_eq!(recalled.dest_hash.0, dest_hash);
2742 assert_eq!(recalled.identity_hash.0, *identity.hash());
2743 assert_eq!(recalled.public_key, identity.get_public_key().unwrap());
2744 assert_eq!(recalled.hops, 1);
2745 }
2746 other => panic!("expected RecallIdentity(Some(..)), got {:?}", other),
2747 }
2748
2749 match resp_rx2.recv().unwrap() {
2750 QueryResponse::RecallIdentity(None) => {}
2751 other => panic!("expected RecallIdentity(None), got {:?}", other),
2752 }
2753 }
2754
2755 #[test]
2756 fn request_path_sends_packet() {
2757 let (tx, rx) = event::channel();
2758 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2759 let mut driver = Driver::new(
2760 TransportConfig { transport_enabled: false, identity_hash: None },
2761 rx,
2762 Box::new(cbs),
2763 );
2764 let info = make_interface_info(1);
2765 driver.engine.register_interface(info);
2766 let (writer, sent) = MockWriter::new();
2767 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2768
2769 tx.send(Event::RequestPath { dest_hash: [0xAA; 16] }).unwrap();
2771 tx.send(Event::Shutdown).unwrap();
2772 driver.run();
2773
2774 let sent_packets = sent.lock().unwrap();
2776 assert!(!sent_packets.is_empty(), "Path request should be sent on wire");
2777
2778 let raw = &sent_packets[0];
2780 let flags = rns_core::packet::PacketFlags::unpack(raw[0] & 0x7F);
2781 assert_eq!(flags.packet_type, constants::PACKET_TYPE_DATA);
2782 assert_eq!(flags.destination_type, constants::DESTINATION_PLAIN);
2783 assert_eq!(flags.transport_type, constants::TRANSPORT_BROADCAST);
2784 }
2785
2786 #[test]
2787 fn request_path_includes_transport_id() {
2788 let (tx, rx) = event::channel();
2789 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2790 let mut driver = Driver::new(
2791 TransportConfig { transport_enabled: true, identity_hash: Some([0xBB; 16]) },
2792 rx,
2793 Box::new(cbs),
2794 );
2795 let info = make_interface_info(1);
2796 driver.engine.register_interface(info);
2797 let (writer, sent) = MockWriter::new();
2798 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2799
2800 tx.send(Event::RequestPath { dest_hash: [0xAA; 16] }).unwrap();
2801 tx.send(Event::Shutdown).unwrap();
2802 driver.run();
2803
2804 let sent_packets = sent.lock().unwrap();
2805 assert!(!sent_packets.is_empty());
2806
2807 let raw = &sent_packets[0];
2809 if let Ok(packet) = RawPacket::unpack(raw) {
2810 assert_eq!(packet.data.len(), 48, "Path request data should be 48 bytes with transport_id");
2812 assert_eq!(&packet.data[..16], &[0xAA; 16], "First 16 bytes should be dest_hash");
2813 assert_eq!(&packet.data[16..32], &[0xBB; 16], "Next 16 bytes should be transport_id");
2814 } else {
2815 panic!("Could not unpack sent packet");
2816 }
2817 }
2818
2819 #[test]
2820 fn path_request_dest_registered() {
2821 let (tx, rx) = event::channel();
2822 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2823 let driver = Driver::new(
2824 TransportConfig { transport_enabled: false, identity_hash: None },
2825 rx,
2826 Box::new(cbs),
2827 );
2828
2829 let expected_dest = rns_core::destination::destination_hash(
2831 "rnstransport", &["path", "request"], None,
2832 );
2833 assert_eq!(driver.path_request_dest, expected_dest);
2834
2835 drop(tx);
2836 }
2837
2838 #[test]
2843 fn register_proof_strategy_event() {
2844 let (tx, rx) = event::channel();
2845 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2846 let mut driver = Driver::new(
2847 TransportConfig { transport_enabled: false, identity_hash: None },
2848 rx,
2849 Box::new(cbs),
2850 );
2851
2852 let dest = [0xAA; 16];
2853 let identity = Identity::new(&mut OsRng);
2854 let prv_key = identity.get_private_key().unwrap();
2855
2856 tx.send(Event::RegisterProofStrategy {
2857 dest_hash: dest,
2858 strategy: rns_core::types::ProofStrategy::ProveAll,
2859 signing_key: Some(prv_key),
2860 }).unwrap();
2861 tx.send(Event::Shutdown).unwrap();
2862 driver.run();
2863
2864 assert!(driver.proof_strategies.contains_key(&dest));
2865 let (strategy, ref id_opt) = driver.proof_strategies[&dest];
2866 assert_eq!(strategy, rns_core::types::ProofStrategy::ProveAll);
2867 assert!(id_opt.is_some());
2868 }
2869
2870 #[test]
2871 fn register_proof_strategy_prove_none_no_identity() {
2872 let (tx, rx) = event::channel();
2873 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2874 let mut driver = Driver::new(
2875 TransportConfig { transport_enabled: false, identity_hash: None },
2876 rx,
2877 Box::new(cbs),
2878 );
2879
2880 let dest = [0xBB; 16];
2881 tx.send(Event::RegisterProofStrategy {
2882 dest_hash: dest,
2883 strategy: rns_core::types::ProofStrategy::ProveNone,
2884 signing_key: None,
2885 }).unwrap();
2886 tx.send(Event::Shutdown).unwrap();
2887 driver.run();
2888
2889 assert!(driver.proof_strategies.contains_key(&dest));
2890 let (strategy, ref id_opt) = driver.proof_strategies[&dest];
2891 assert_eq!(strategy, rns_core::types::ProofStrategy::ProveNone);
2892 assert!(id_opt.is_none());
2893 }
2894
2895 #[test]
2896 fn send_outbound_tracks_sent_packets() {
2897 let (tx, rx) = event::channel();
2898 let (cbs, _, _, _, _, _) = MockCallbacks::new();
2899 let mut driver = Driver::new(
2900 TransportConfig { transport_enabled: false, identity_hash: None },
2901 rx,
2902 Box::new(cbs),
2903 );
2904 let info = make_interface_info(1);
2905 driver.engine.register_interface(info);
2906 let (writer, _sent) = MockWriter::new();
2907 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2908
2909 let dest = [0xCC; 16];
2911 let flags = PacketFlags {
2912 header_type: constants::HEADER_1,
2913 context_flag: constants::FLAG_UNSET,
2914 transport_type: constants::TRANSPORT_BROADCAST,
2915 destination_type: constants::DESTINATION_PLAIN,
2916 packet_type: constants::PACKET_TYPE_DATA,
2917 };
2918 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, b"test data").unwrap();
2919 let expected_hash = packet.packet_hash;
2920
2921 tx.send(Event::SendOutbound {
2922 raw: packet.raw,
2923 dest_type: constants::DESTINATION_PLAIN,
2924 attached_interface: None,
2925 }).unwrap();
2926 tx.send(Event::Shutdown).unwrap();
2927 driver.run();
2928
2929 assert!(driver.sent_packets.contains_key(&expected_hash));
2931 let (tracked_dest, _sent_time) = &driver.sent_packets[&expected_hash];
2932 assert_eq!(tracked_dest, &dest);
2933 }
2934
2935 #[test]
2936 fn prove_all_generates_proof_on_delivery() {
2937 let (tx, rx) = event::channel();
2938 let (cbs, _, _, deliveries, _, _) = MockCallbacks::new();
2939 let mut driver = Driver::new(
2940 TransportConfig { transport_enabled: false, identity_hash: None },
2941 rx,
2942 Box::new(cbs),
2943 );
2944 let info = make_interface_info(1);
2945 driver.engine.register_interface(info);
2946 let (writer, sent) = MockWriter::new();
2947 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2948
2949 let dest = [0xDD; 16];
2951 let identity = Identity::new(&mut OsRng);
2952 let prv_key = identity.get_private_key().unwrap();
2953 driver.engine.register_destination(dest, constants::DESTINATION_SINGLE);
2954 driver.proof_strategies.insert(dest, (
2955 rns_core::types::ProofStrategy::ProveAll,
2956 Some(Identity::from_private_key(&prv_key)),
2957 ));
2958
2959 let flags = PacketFlags {
2961 header_type: constants::HEADER_1,
2962 context_flag: constants::FLAG_UNSET,
2963 transport_type: constants::TRANSPORT_BROADCAST,
2964 destination_type: constants::DESTINATION_SINGLE,
2965 packet_type: constants::PACKET_TYPE_DATA,
2966 };
2967 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, b"hello").unwrap();
2968
2969 tx.send(Event::Frame { interface_id: InterfaceId(1), data: packet.raw }).unwrap();
2970 tx.send(Event::Shutdown).unwrap();
2971 driver.run();
2972
2973 assert_eq!(deliveries.lock().unwrap().len(), 1);
2975
2976 let sent_packets = sent.lock().unwrap();
2978 let has_proof = sent_packets.iter().any(|raw| {
2980 let flags = PacketFlags::unpack(raw[0] & 0x7F);
2981 flags.packet_type == constants::PACKET_TYPE_PROOF
2982 });
2983 assert!(has_proof, "ProveAll should generate a proof packet: sent {} packets", sent_packets.len());
2984 }
2985
2986 #[test]
2987 fn prove_none_does_not_generate_proof() {
2988 let (tx, rx) = event::channel();
2989 let (cbs, _, _, deliveries, _, _) = MockCallbacks::new();
2990 let mut driver = Driver::new(
2991 TransportConfig { transport_enabled: false, identity_hash: None },
2992 rx,
2993 Box::new(cbs),
2994 );
2995 let info = make_interface_info(1);
2996 driver.engine.register_interface(info);
2997 let (writer, sent) = MockWriter::new();
2998 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
2999
3000 let dest = [0xDD; 16];
3002 driver.engine.register_destination(dest, constants::DESTINATION_SINGLE);
3003 driver.proof_strategies.insert(dest, (
3004 rns_core::types::ProofStrategy::ProveNone,
3005 None,
3006 ));
3007
3008 let flags = PacketFlags {
3010 header_type: constants::HEADER_1,
3011 context_flag: constants::FLAG_UNSET,
3012 transport_type: constants::TRANSPORT_BROADCAST,
3013 destination_type: constants::DESTINATION_SINGLE,
3014 packet_type: constants::PACKET_TYPE_DATA,
3015 };
3016 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, b"hello").unwrap();
3017
3018 tx.send(Event::Frame { interface_id: InterfaceId(1), data: packet.raw }).unwrap();
3019 tx.send(Event::Shutdown).unwrap();
3020 driver.run();
3021
3022 assert_eq!(deliveries.lock().unwrap().len(), 1);
3024
3025 let sent_packets = sent.lock().unwrap();
3027 let has_proof = sent_packets.iter().any(|raw| {
3028 let flags = PacketFlags::unpack(raw[0] & 0x7F);
3029 flags.packet_type == constants::PACKET_TYPE_PROOF
3030 });
3031 assert!(!has_proof, "ProveNone should not generate a proof packet");
3032 }
3033
3034 #[test]
3035 fn no_proof_strategy_does_not_generate_proof() {
3036 let (tx, rx) = event::channel();
3037 let (cbs, _, _, deliveries, _, _) = MockCallbacks::new();
3038 let mut driver = Driver::new(
3039 TransportConfig { transport_enabled: false, identity_hash: None },
3040 rx,
3041 Box::new(cbs),
3042 );
3043 let info = make_interface_info(1);
3044 driver.engine.register_interface(info);
3045 let (writer, sent) = MockWriter::new();
3046 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
3047
3048 let dest = [0xDD; 16];
3050 driver.engine.register_destination(dest, constants::DESTINATION_SINGLE);
3051
3052 let flags = PacketFlags {
3053 header_type: constants::HEADER_1,
3054 context_flag: constants::FLAG_UNSET,
3055 transport_type: constants::TRANSPORT_BROADCAST,
3056 destination_type: constants::DESTINATION_SINGLE,
3057 packet_type: constants::PACKET_TYPE_DATA,
3058 };
3059 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, b"hello").unwrap();
3060
3061 tx.send(Event::Frame { interface_id: InterfaceId(1), data: packet.raw }).unwrap();
3062 tx.send(Event::Shutdown).unwrap();
3063 driver.run();
3064
3065 assert_eq!(deliveries.lock().unwrap().len(), 1);
3066
3067 let sent_packets = sent.lock().unwrap();
3068 let has_proof = sent_packets.iter().any(|raw| {
3069 let flags = PacketFlags::unpack(raw[0] & 0x7F);
3070 flags.packet_type == constants::PACKET_TYPE_PROOF
3071 });
3072 assert!(!has_proof, "No proof strategy means no proof generated");
3073 }
3074
3075 #[test]
3076 fn prove_app_calls_callback() {
3077 let (tx, rx) = event::channel();
3078 let proof_requested = Arc::new(Mutex::new(Vec::new()));
3079 let deliveries = Arc::new(Mutex::new(Vec::new()));
3080 let cbs = MockCallbacks {
3081 announces: Arc::new(Mutex::new(Vec::new())),
3082 paths: Arc::new(Mutex::new(Vec::new())),
3083 deliveries: deliveries.clone(),
3084 iface_ups: Arc::new(Mutex::new(Vec::new())),
3085 iface_downs: Arc::new(Mutex::new(Vec::new())),
3086 link_established: Arc::new(Mutex::new(Vec::new())),
3087 link_closed: Arc::new(Mutex::new(Vec::new())),
3088 remote_identified: Arc::new(Mutex::new(Vec::new())),
3089 resources_received: Arc::new(Mutex::new(Vec::new())),
3090 resource_completed: Arc::new(Mutex::new(Vec::new())),
3091 resource_failed: Arc::new(Mutex::new(Vec::new())),
3092 channel_messages: Arc::new(Mutex::new(Vec::new())),
3093 link_data: Arc::new(Mutex::new(Vec::new())),
3094 responses: Arc::new(Mutex::new(Vec::new())),
3095 proofs: Arc::new(Mutex::new(Vec::new())),
3096 proof_requested: proof_requested.clone(),
3097 };
3098
3099 let mut driver = Driver::new(
3100 TransportConfig { transport_enabled: false, identity_hash: None },
3101 rx,
3102 Box::new(cbs),
3103 );
3104 let info = make_interface_info(1);
3105 driver.engine.register_interface(info);
3106 let (writer, sent) = MockWriter::new();
3107 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
3108
3109 let dest = [0xDD; 16];
3111 let identity = Identity::new(&mut OsRng);
3112 let prv_key = identity.get_private_key().unwrap();
3113 driver.engine.register_destination(dest, constants::DESTINATION_SINGLE);
3114 driver.proof_strategies.insert(dest, (
3115 rns_core::types::ProofStrategy::ProveApp,
3116 Some(Identity::from_private_key(&prv_key)),
3117 ));
3118
3119 let flags = PacketFlags {
3120 header_type: constants::HEADER_1,
3121 context_flag: constants::FLAG_UNSET,
3122 transport_type: constants::TRANSPORT_BROADCAST,
3123 destination_type: constants::DESTINATION_SINGLE,
3124 packet_type: constants::PACKET_TYPE_DATA,
3125 };
3126 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, b"app test").unwrap();
3127
3128 tx.send(Event::Frame { interface_id: InterfaceId(1), data: packet.raw }).unwrap();
3129 tx.send(Event::Shutdown).unwrap();
3130 driver.run();
3131
3132 let prs = proof_requested.lock().unwrap();
3134 assert_eq!(prs.len(), 1);
3135 assert_eq!(prs[0].0, DestHash(dest));
3136
3137 let sent_packets = sent.lock().unwrap();
3139 let has_proof = sent_packets.iter().any(|raw| {
3140 let flags = PacketFlags::unpack(raw[0] & 0x7F);
3141 flags.packet_type == constants::PACKET_TYPE_PROOF
3142 });
3143 assert!(has_proof, "ProveApp (callback returns true) should generate a proof");
3144 }
3145
3146 #[test]
3147 fn inbound_proof_fires_callback() {
3148 let (tx, rx) = event::channel();
3149 let proofs = Arc::new(Mutex::new(Vec::new()));
3150 let cbs = MockCallbacks {
3151 announces: Arc::new(Mutex::new(Vec::new())),
3152 paths: Arc::new(Mutex::new(Vec::new())),
3153 deliveries: Arc::new(Mutex::new(Vec::new())),
3154 iface_ups: Arc::new(Mutex::new(Vec::new())),
3155 iface_downs: Arc::new(Mutex::new(Vec::new())),
3156 link_established: Arc::new(Mutex::new(Vec::new())),
3157 link_closed: Arc::new(Mutex::new(Vec::new())),
3158 remote_identified: Arc::new(Mutex::new(Vec::new())),
3159 resources_received: Arc::new(Mutex::new(Vec::new())),
3160 resource_completed: Arc::new(Mutex::new(Vec::new())),
3161 resource_failed: Arc::new(Mutex::new(Vec::new())),
3162 channel_messages: Arc::new(Mutex::new(Vec::new())),
3163 link_data: Arc::new(Mutex::new(Vec::new())),
3164 responses: Arc::new(Mutex::new(Vec::new())),
3165 proofs: proofs.clone(),
3166 proof_requested: Arc::new(Mutex::new(Vec::new())),
3167 };
3168
3169 let mut driver = Driver::new(
3170 TransportConfig { transport_enabled: false, identity_hash: None },
3171 rx,
3172 Box::new(cbs),
3173 );
3174 let info = make_interface_info(1);
3175 driver.engine.register_interface(info);
3176 let (writer, _sent) = MockWriter::new();
3177 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
3178
3179 let dest = [0xEE; 16];
3181 driver.engine.register_destination(dest, constants::DESTINATION_SINGLE);
3182
3183 let tracked_hash = [0x42u8; 32];
3185 let sent_time = time::now() - 0.5; driver.sent_packets.insert(tracked_hash, (dest, sent_time));
3187
3188 let mut proof_data = Vec::new();
3190 proof_data.extend_from_slice(&tracked_hash);
3191 proof_data.extend_from_slice(&[0xAA; 64]); let flags = PacketFlags {
3194 header_type: constants::HEADER_1,
3195 context_flag: constants::FLAG_UNSET,
3196 transport_type: constants::TRANSPORT_BROADCAST,
3197 destination_type: constants::DESTINATION_SINGLE,
3198 packet_type: constants::PACKET_TYPE_PROOF,
3199 };
3200 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, &proof_data).unwrap();
3201
3202 tx.send(Event::Frame { interface_id: InterfaceId(1), data: packet.raw }).unwrap();
3203 tx.send(Event::Shutdown).unwrap();
3204 driver.run();
3205
3206 let proof_list = proofs.lock().unwrap();
3208 assert_eq!(proof_list.len(), 1);
3209 assert_eq!(proof_list[0].0, DestHash(dest));
3210 assert_eq!(proof_list[0].1, PacketHash(tracked_hash));
3211 assert!(proof_list[0].2 >= 0.4, "RTT should be approximately 0.5s, got {}", proof_list[0].2);
3212
3213 assert!(!driver.sent_packets.contains_key(&tracked_hash));
3215 }
3216
3217 #[test]
3218 fn inbound_proof_for_unknown_packet_is_ignored() {
3219 let (tx, rx) = event::channel();
3220 let proofs = Arc::new(Mutex::new(Vec::new()));
3221 let cbs = MockCallbacks {
3222 announces: Arc::new(Mutex::new(Vec::new())),
3223 paths: Arc::new(Mutex::new(Vec::new())),
3224 deliveries: Arc::new(Mutex::new(Vec::new())),
3225 iface_ups: Arc::new(Mutex::new(Vec::new())),
3226 iface_downs: Arc::new(Mutex::new(Vec::new())),
3227 link_established: Arc::new(Mutex::new(Vec::new())),
3228 link_closed: Arc::new(Mutex::new(Vec::new())),
3229 remote_identified: Arc::new(Mutex::new(Vec::new())),
3230 resources_received: Arc::new(Mutex::new(Vec::new())),
3231 resource_completed: Arc::new(Mutex::new(Vec::new())),
3232 resource_failed: Arc::new(Mutex::new(Vec::new())),
3233 channel_messages: Arc::new(Mutex::new(Vec::new())),
3234 link_data: Arc::new(Mutex::new(Vec::new())),
3235 responses: Arc::new(Mutex::new(Vec::new())),
3236 proofs: proofs.clone(),
3237 proof_requested: Arc::new(Mutex::new(Vec::new())),
3238 };
3239
3240 let mut driver = Driver::new(
3241 TransportConfig { transport_enabled: false, identity_hash: None },
3242 rx,
3243 Box::new(cbs),
3244 );
3245 let info = make_interface_info(1);
3246 driver.engine.register_interface(info);
3247 let (writer, _sent) = MockWriter::new();
3248 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
3249
3250 let dest = [0xEE; 16];
3251 driver.engine.register_destination(dest, constants::DESTINATION_SINGLE);
3252
3253 let unknown_hash = [0xFF; 32];
3255 let mut proof_data = Vec::new();
3256 proof_data.extend_from_slice(&unknown_hash);
3257 proof_data.extend_from_slice(&[0xAA; 64]);
3258
3259 let flags = PacketFlags {
3260 header_type: constants::HEADER_1,
3261 context_flag: constants::FLAG_UNSET,
3262 transport_type: constants::TRANSPORT_BROADCAST,
3263 destination_type: constants::DESTINATION_SINGLE,
3264 packet_type: constants::PACKET_TYPE_PROOF,
3265 };
3266 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, &proof_data).unwrap();
3267
3268 tx.send(Event::Frame { interface_id: InterfaceId(1), data: packet.raw }).unwrap();
3269 tx.send(Event::Shutdown).unwrap();
3270 driver.run();
3271
3272 assert!(proofs.lock().unwrap().is_empty());
3274 }
3275
3276 #[test]
3277 fn inbound_proof_with_valid_signature_fires_callback() {
3278 let (tx, rx) = event::channel();
3280 let proofs = Arc::new(Mutex::new(Vec::new()));
3281 let cbs = MockCallbacks {
3282 announces: Arc::new(Mutex::new(Vec::new())),
3283 paths: Arc::new(Mutex::new(Vec::new())),
3284 deliveries: Arc::new(Mutex::new(Vec::new())),
3285 iface_ups: Arc::new(Mutex::new(Vec::new())),
3286 iface_downs: Arc::new(Mutex::new(Vec::new())),
3287 link_established: Arc::new(Mutex::new(Vec::new())),
3288 link_closed: Arc::new(Mutex::new(Vec::new())),
3289 remote_identified: Arc::new(Mutex::new(Vec::new())),
3290 resources_received: Arc::new(Mutex::new(Vec::new())),
3291 resource_completed: Arc::new(Mutex::new(Vec::new())),
3292 resource_failed: Arc::new(Mutex::new(Vec::new())),
3293 channel_messages: Arc::new(Mutex::new(Vec::new())),
3294 link_data: Arc::new(Mutex::new(Vec::new())),
3295 responses: Arc::new(Mutex::new(Vec::new())),
3296 proofs: proofs.clone(),
3297 proof_requested: Arc::new(Mutex::new(Vec::new())),
3298 };
3299
3300 let mut driver = Driver::new(
3301 TransportConfig { transport_enabled: false, identity_hash: None },
3302 rx,
3303 Box::new(cbs),
3304 );
3305 let info = make_interface_info(1);
3306 driver.engine.register_interface(info);
3307 let (writer, _sent) = MockWriter::new();
3308 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
3309
3310 let dest = [0xEE; 16];
3311 driver.engine.register_destination(dest, constants::DESTINATION_SINGLE);
3312
3313 let identity = Identity::new(&mut OsRng);
3315 let pub_key = identity.get_public_key();
3316 driver.known_destinations.insert(dest, crate::destination::AnnouncedIdentity {
3317 dest_hash: DestHash(dest),
3318 identity_hash: IdentityHash(*identity.hash()),
3319 public_key: pub_key.unwrap(),
3320 app_data: None,
3321 hops: 0,
3322 received_at: time::now(),
3323 });
3324
3325 let tracked_hash = [0x42u8; 32];
3327 let sent_time = time::now() - 0.5;
3328 driver.sent_packets.insert(tracked_hash, (dest, sent_time));
3329
3330 let signature = identity.sign(&tracked_hash).unwrap();
3331 let mut proof_data = Vec::new();
3332 proof_data.extend_from_slice(&tracked_hash);
3333 proof_data.extend_from_slice(&signature);
3334
3335 let flags = PacketFlags {
3336 header_type: constants::HEADER_1,
3337 context_flag: constants::FLAG_UNSET,
3338 transport_type: constants::TRANSPORT_BROADCAST,
3339 destination_type: constants::DESTINATION_SINGLE,
3340 packet_type: constants::PACKET_TYPE_PROOF,
3341 };
3342 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, &proof_data).unwrap();
3343
3344 tx.send(Event::Frame { interface_id: InterfaceId(1), data: packet.raw }).unwrap();
3345 tx.send(Event::Shutdown).unwrap();
3346 driver.run();
3347
3348 let proof_list = proofs.lock().unwrap();
3350 assert_eq!(proof_list.len(), 1);
3351 assert_eq!(proof_list[0].0, DestHash(dest));
3352 assert_eq!(proof_list[0].1, PacketHash(tracked_hash));
3353 }
3354
3355 #[test]
3356 fn inbound_proof_with_invalid_signature_rejected() {
3357 let (tx, rx) = event::channel();
3359 let proofs = Arc::new(Mutex::new(Vec::new()));
3360 let cbs = MockCallbacks {
3361 announces: Arc::new(Mutex::new(Vec::new())),
3362 paths: Arc::new(Mutex::new(Vec::new())),
3363 deliveries: Arc::new(Mutex::new(Vec::new())),
3364 iface_ups: Arc::new(Mutex::new(Vec::new())),
3365 iface_downs: Arc::new(Mutex::new(Vec::new())),
3366 link_established: Arc::new(Mutex::new(Vec::new())),
3367 link_closed: Arc::new(Mutex::new(Vec::new())),
3368 remote_identified: Arc::new(Mutex::new(Vec::new())),
3369 resources_received: Arc::new(Mutex::new(Vec::new())),
3370 resource_completed: Arc::new(Mutex::new(Vec::new())),
3371 resource_failed: Arc::new(Mutex::new(Vec::new())),
3372 channel_messages: Arc::new(Mutex::new(Vec::new())),
3373 link_data: Arc::new(Mutex::new(Vec::new())),
3374 responses: Arc::new(Mutex::new(Vec::new())),
3375 proofs: proofs.clone(),
3376 proof_requested: Arc::new(Mutex::new(Vec::new())),
3377 };
3378
3379 let mut driver = Driver::new(
3380 TransportConfig { transport_enabled: false, identity_hash: None },
3381 rx,
3382 Box::new(cbs),
3383 );
3384 let info = make_interface_info(1);
3385 driver.engine.register_interface(info);
3386 let (writer, _sent) = MockWriter::new();
3387 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
3388
3389 let dest = [0xEE; 16];
3390 driver.engine.register_destination(dest, constants::DESTINATION_SINGLE);
3391
3392 let identity = Identity::new(&mut OsRng);
3394 let pub_key = identity.get_public_key();
3395 driver.known_destinations.insert(dest, crate::destination::AnnouncedIdentity {
3396 dest_hash: DestHash(dest),
3397 identity_hash: IdentityHash(*identity.hash()),
3398 public_key: pub_key.unwrap(),
3399 app_data: None,
3400 hops: 0,
3401 received_at: time::now(),
3402 });
3403
3404 let tracked_hash = [0x42u8; 32];
3406 let sent_time = time::now() - 0.5;
3407 driver.sent_packets.insert(tracked_hash, (dest, sent_time));
3408
3409 let mut proof_data = Vec::new();
3411 proof_data.extend_from_slice(&tracked_hash);
3412 proof_data.extend_from_slice(&[0xAA; 64]);
3413
3414 let flags = PacketFlags {
3415 header_type: constants::HEADER_1,
3416 context_flag: constants::FLAG_UNSET,
3417 transport_type: constants::TRANSPORT_BROADCAST,
3418 destination_type: constants::DESTINATION_SINGLE,
3419 packet_type: constants::PACKET_TYPE_PROOF,
3420 };
3421 let packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, &proof_data).unwrap();
3422
3423 tx.send(Event::Frame { interface_id: InterfaceId(1), data: packet.raw }).unwrap();
3424 tx.send(Event::Shutdown).unwrap();
3425 driver.run();
3426
3427 assert!(proofs.lock().unwrap().is_empty());
3429 }
3430
3431 #[test]
3432 fn proof_data_is_valid_explicit_proof() {
3433 let (tx, rx) = event::channel();
3435 let (cbs, _, _, _, _, _) = MockCallbacks::new();
3436 let mut driver = Driver::new(
3437 TransportConfig { transport_enabled: false, identity_hash: None },
3438 rx,
3439 Box::new(cbs),
3440 );
3441 let info = make_interface_info(1);
3442 driver.engine.register_interface(info);
3443 let (writer, sent) = MockWriter::new();
3444 driver.interfaces.insert(InterfaceId(1), make_entry(1, Box::new(writer), true));
3445
3446 let dest = [0xDD; 16];
3447 let identity = Identity::new(&mut OsRng);
3448 let prv_key = identity.get_private_key().unwrap();
3449 driver.engine.register_destination(dest, constants::DESTINATION_SINGLE);
3450 driver.proof_strategies.insert(dest, (
3451 rns_core::types::ProofStrategy::ProveAll,
3452 Some(Identity::from_private_key(&prv_key)),
3453 ));
3454
3455 let flags = PacketFlags {
3456 header_type: constants::HEADER_1,
3457 context_flag: constants::FLAG_UNSET,
3458 transport_type: constants::TRANSPORT_BROADCAST,
3459 destination_type: constants::DESTINATION_SINGLE,
3460 packet_type: constants::PACKET_TYPE_DATA,
3461 };
3462 let data_packet = RawPacket::pack(flags, 0, &dest, None, constants::CONTEXT_NONE, b"verify me").unwrap();
3463 let data_packet_hash = data_packet.packet_hash;
3464
3465 tx.send(Event::Frame { interface_id: InterfaceId(1), data: data_packet.raw }).unwrap();
3466 tx.send(Event::Shutdown).unwrap();
3467 driver.run();
3468
3469 let sent_packets = sent.lock().unwrap();
3471 let proof_raw = sent_packets.iter().find(|raw| {
3472 let f = PacketFlags::unpack(raw[0] & 0x7F);
3473 f.packet_type == constants::PACKET_TYPE_PROOF
3474 });
3475 assert!(proof_raw.is_some(), "Should have sent a proof");
3476
3477 let proof_packet = RawPacket::unpack(proof_raw.unwrap()).unwrap();
3478 assert_eq!(proof_packet.data.len(), 96, "Explicit proof should be 96 bytes");
3480
3481 let result = rns_core::receipt::validate_proof(
3483 &proof_packet.data,
3484 &data_packet_hash,
3485 &Identity::from_private_key(&prv_key), );
3487 assert_eq!(result, rns_core::receipt::ProofResult::Valid);
3488 }
3489
3490 #[test]
3491 fn query_local_destinations_empty() {
3492 let (tx, rx) = event::channel();
3493 let (cbs, _, _, _, _, _) = MockCallbacks::new();
3494 let driver_config = TransportConfig { transport_enabled: false, identity_hash: None };
3495 let mut driver = Driver::new(driver_config, rx, Box::new(cbs));
3496
3497 let (resp_tx, resp_rx) = mpsc::channel();
3498 tx.send(Event::Query(QueryRequest::LocalDestinations, resp_tx)).unwrap();
3499 tx.send(Event::Shutdown).unwrap();
3500 driver.run();
3501
3502 match resp_rx.recv().unwrap() {
3503 QueryResponse::LocalDestinations(entries) => {
3504 assert_eq!(entries.len(), 2);
3506 for entry in &entries {
3507 assert_eq!(entry.dest_type, rns_core::constants::DESTINATION_PLAIN);
3508 }
3509 }
3510 other => panic!("expected LocalDestinations, got {:?}", other),
3511 }
3512 }
3513
3514 #[test]
3515 fn query_local_destinations_with_registered() {
3516 let (tx, rx) = event::channel();
3517 let (cbs, _, _, _, _, _) = MockCallbacks::new();
3518 let driver_config = TransportConfig { transport_enabled: false, identity_hash: None };
3519 let mut driver = Driver::new(driver_config, rx, Box::new(cbs));
3520
3521 let dest_hash = [0xAA; 16];
3522 tx.send(Event::RegisterDestination {
3523 dest_hash,
3524 dest_type: rns_core::constants::DESTINATION_SINGLE,
3525 }).unwrap();
3526
3527 let (resp_tx, resp_rx) = mpsc::channel();
3528 tx.send(Event::Query(QueryRequest::LocalDestinations, resp_tx)).unwrap();
3529 tx.send(Event::Shutdown).unwrap();
3530 driver.run();
3531
3532 match resp_rx.recv().unwrap() {
3533 QueryResponse::LocalDestinations(entries) => {
3534 assert_eq!(entries.len(), 3);
3536 assert!(entries.iter().any(|e| e.hash == dest_hash
3537 && e.dest_type == rns_core::constants::DESTINATION_SINGLE));
3538 }
3539 other => panic!("expected LocalDestinations, got {:?}", other),
3540 }
3541 }
3542
3543 #[test]
3544 fn query_local_destinations_tracks_link_dest() {
3545 let (tx, rx) = event::channel();
3546 let (cbs, _, _, _, _, _) = MockCallbacks::new();
3547 let driver_config = TransportConfig { transport_enabled: false, identity_hash: None };
3548 let mut driver = Driver::new(driver_config, rx, Box::new(cbs));
3549
3550 let dest_hash = [0xBB; 16];
3551 tx.send(Event::RegisterLinkDestination {
3552 dest_hash,
3553 sig_prv_bytes: [0x11; 32],
3554 sig_pub_bytes: [0x22; 32],
3555 }).unwrap();
3556
3557 let (resp_tx, resp_rx) = mpsc::channel();
3558 tx.send(Event::Query(QueryRequest::LocalDestinations, resp_tx)).unwrap();
3559 tx.send(Event::Shutdown).unwrap();
3560 driver.run();
3561
3562 match resp_rx.recv().unwrap() {
3563 QueryResponse::LocalDestinations(entries) => {
3564 assert_eq!(entries.len(), 3);
3566 assert!(entries.iter().any(|e| e.hash == dest_hash
3567 && e.dest_type == rns_core::constants::DESTINATION_SINGLE));
3568 }
3569 other => panic!("expected LocalDestinations, got {:?}", other),
3570 }
3571 }
3572
3573 #[test]
3574 fn query_links_empty() {
3575 let (tx, rx) = event::channel();
3576 let (cbs, _, _, _, _, _) = MockCallbacks::new();
3577 let driver_config = TransportConfig { transport_enabled: false, identity_hash: None };
3578 let mut driver = Driver::new(driver_config, rx, Box::new(cbs));
3579
3580 let (resp_tx, resp_rx) = mpsc::channel();
3581 tx.send(Event::Query(QueryRequest::Links, resp_tx)).unwrap();
3582 tx.send(Event::Shutdown).unwrap();
3583 driver.run();
3584
3585 match resp_rx.recv().unwrap() {
3586 QueryResponse::Links(entries) => {
3587 assert!(entries.is_empty());
3588 }
3589 other => panic!("expected Links, got {:?}", other),
3590 }
3591 }
3592
3593 #[test]
3594 fn query_resources_empty() {
3595 let (tx, rx) = event::channel();
3596 let (cbs, _, _, _, _, _) = MockCallbacks::new();
3597 let driver_config = TransportConfig { transport_enabled: false, identity_hash: None };
3598 let mut driver = Driver::new(driver_config, rx, Box::new(cbs));
3599
3600 let (resp_tx, resp_rx) = mpsc::channel();
3601 tx.send(Event::Query(QueryRequest::Resources, resp_tx)).unwrap();
3602 tx.send(Event::Shutdown).unwrap();
3603 driver.run();
3604
3605 match resp_rx.recv().unwrap() {
3606 QueryResponse::Resources(entries) => {
3607 assert!(entries.is_empty());
3608 }
3609 other => panic!("expected Resources, got {:?}", other),
3610 }
3611 }
3612
3613 #[test]
3614 fn infer_interface_type_from_name() {
3615 assert_eq!(
3616 super::infer_interface_type("TCPServerInterface/Client-1234"),
3617 "TCPServerClientInterface"
3618 );
3619 assert_eq!(
3620 super::infer_interface_type("BackboneInterface/5"),
3621 "BackboneInterface"
3622 );
3623 assert_eq!(
3624 super::infer_interface_type("LocalInterface"),
3625 "LocalServerClientInterface"
3626 );
3627 assert_eq!(
3628 super::infer_interface_type("MyAutoGroup:fe80::1"),
3629 "AutoInterface"
3630 );
3631 }
3632}