use super::*;
impl TransportEngine {
pub fn handle_outbound<B: crate::packet::PacketStorage>(
&mut self,
packet: &RawPacket<B>,
dest_type: u8,
attached_interface: Option<InterfaceId>,
now: f64,
) -> Vec<TransportAction> {
let mut actions = Vec::new();
self.handle_outbound_into(packet, dest_type, attached_interface, now, &mut actions);
actions
}
pub fn handle_outbound_into<B: crate::packet::PacketStorage>(
&mut self,
packet: &RawPacket<B>,
dest_type: u8,
attached_interface: Option<InterfaceId>,
now: f64,
actions: &mut Vec<TransportAction>,
) {
if packet.hops >= constants::PATHFINDER_M {
return;
}
let uses_path = packet.flags.packet_type != constants::PACKET_TYPE_ANNOUNCE
&& dest_type != constants::DESTINATION_PLAIN
&& dest_type != constants::DESTINATION_GROUP
&& !(dest_type == constants::DESTINATION_LINK && attached_interface.is_some());
if uses_path {
if let Some(path_set) = self.path_table.get_mut(&packet.destination_hash) {
if let Some(entry) = path_set.primary_mut() {
entry.used = now;
}
}
}
let start = actions.len();
route_outbound_into(
&self.path_table,
&self.interfaces,
&self.local_destinations,
packet,
dest_type,
attached_interface,
OutboundRouteOptions {
identity_hash: self.config.identity_hash,
local_hops_delta: self.config.local_hops_delta,
},
actions,
);
if !packet.is_unhashed_link_resource() {
self.packet_hashlist.add(packet.packet_hash);
}
if packet.flags.packet_type == constants::PACKET_TYPE_ANNOUNCE && packet.hops > 0 {
let routed: Vec<TransportAction> = actions.drain(start..).collect();
let gated =
self.gate_announce_actions(routed, &packet.destination_hash, packet.hops, now);
actions.extend(gated);
}
}
fn gate_announce_actions(
&mut self,
actions: Vec<TransportAction>,
dest_hash: &[u8; 16],
hops: u8,
now: f64,
) -> Vec<TransportAction> {
let mut result = Vec::new();
for action in actions {
match action {
TransportAction::SendOnInterface { interface, raw } => {
let (bitrate, airtime_profile, announce_cap) =
if let Some(info) = self.interfaces.get(&interface) {
(info.bitrate, info.airtime_profile, info.announce_cap)
} else {
(None, None, constants::ANNOUNCE_CAP)
};
if let Some(send_action) = self.announce_queues.gate_announce(
interface,
raw,
*dest_hash,
hops,
now,
now,
bitrate,
airtime_profile,
announce_cap,
) {
result.push(send_action);
}
}
other => result.push(other),
}
}
result
}
}