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. A link resource part is
30        // not hashed: its context bypasses deduplication.
31        if !packet.is_link_resource_part() {
32            self.packet_hashlist.add(packet.packet_hash);
33        }
34
35        // Gate announces with hops > 0 through the bandwidth queue
36        if packet.flags.packet_type == constants::PACKET_TYPE_ANNOUNCE && packet.hops > 0 {
37            self.gate_announce_actions(actions, &packet.destination_hash, packet.hops, now)
38        } else {
39            actions
40        }
41    }
42
43    /// Gate announce SendOnInterface actions through per-interface bandwidth queues.
44    fn gate_announce_actions(
45        &mut self,
46        actions: Vec<TransportAction>,
47        dest_hash: &[u8; 16],
48        hops: u8,
49        now: f64,
50    ) -> Vec<TransportAction> {
51        let mut result = Vec::new();
52        for action in actions {
53            match action {
54                TransportAction::SendOnInterface { interface, raw } => {
55                    let (bitrate, airtime_profile, announce_cap) =
56                        if let Some(info) = self.interfaces.get(&interface) {
57                            (info.bitrate, info.airtime_profile, info.announce_cap)
58                        } else {
59                            (None, None, constants::ANNOUNCE_CAP)
60                        };
61                    if let Some(send_action) = self.announce_queues.gate_announce(
62                        interface,
63                        raw,
64                        *dest_hash,
65                        hops,
66                        now,
67                        now,
68                        bitrate,
69                        airtime_profile,
70                        announce_cap,
71                    ) {
72                        result.push(send_action);
73                    }
74                    // If None, it was queued — no action emitted now
75                }
76                other => result.push(other),
77            }
78        }
79        result
80    }
81}