Skip to main content

rns_core/transport/
outbound_engine.rs

1use super::*;
2
3impl TransportEngine {
4    /// Route an outbound packet.
5    pub fn handle_outbound(
6        &mut self,
7        packet: &RawPacket,
8        dest_type: u8,
9        attached_interface: Option<InterfaceId>,
10        now: f64,
11    ) -> Vec<TransportAction> {
12        if packet.hops >= constants::PATHFINDER_M {
13            return Vec::new();
14        }
15
16        let actions = route_outbound_with_options(
17            &self.path_table,
18            &self.interfaces,
19            &self.local_destinations,
20            packet,
21            dest_type,
22            attached_interface,
23            OutboundRouteOptions {
24                identity_hash: self.config.identity_hash,
25                local_hops_delta: self.config.local_hops_delta,
26            },
27        );
28
29        // Add to packet hashlist for outbound packets
30        self.packet_hashlist.add(packet.packet_hash);
31
32        // Gate announces with hops > 0 through the bandwidth queue
33        if packet.flags.packet_type == constants::PACKET_TYPE_ANNOUNCE && packet.hops > 0 {
34            self.gate_announce_actions(actions, &packet.destination_hash, packet.hops, now)
35        } else {
36            actions
37        }
38    }
39
40    /// Gate announce SendOnInterface actions through per-interface bandwidth queues.
41    fn gate_announce_actions(
42        &mut self,
43        actions: Vec<TransportAction>,
44        dest_hash: &[u8; 16],
45        hops: u8,
46        now: f64,
47    ) -> Vec<TransportAction> {
48        let mut result = Vec::new();
49        for action in actions {
50            match action {
51                TransportAction::SendOnInterface { interface, raw } => {
52                    let (bitrate, airtime_profile, announce_cap) =
53                        if let Some(info) = self.interfaces.get(&interface) {
54                            (info.bitrate, info.airtime_profile, info.announce_cap)
55                        } else {
56                            (None, None, constants::ANNOUNCE_CAP)
57                        };
58                    if let Some(send_action) = self.announce_queues.gate_announce(
59                        interface,
60                        raw,
61                        *dest_hash,
62                        hops,
63                        now,
64                        now,
65                        bitrate,
66                        airtime_profile,
67                        announce_cap,
68                    ) {
69                        result.push(send_action);
70                    }
71                    // If None, it was queued — no action emitted now
72                }
73                other => result.push(other),
74            }
75        }
76        result
77    }
78}