use std::{collections::HashMap, time::Instant};
use crate::{
hash::{AddressHash, Hash},
packet::{DestinationType, Header, HeaderType, Packet, PacketType},
};
pub struct PathEntry {
pub timestamp: Instant,
pub received_from: AddressHash,
pub hops: u8,
pub iface: AddressHash,
pub packet_hash: Hash,
}
pub struct PathTable {
map: HashMap<AddressHash, PathEntry>,
}
impl PathTable {
pub fn new() -> Self {
Self {
map: HashMap::new(),
}
}
pub fn next_hop_iface(&self, destination: &AddressHash) -> Option<AddressHash> {
self.map.get(destination).map(|entry| entry.iface)
}
pub fn next_hop(&self, destination: &AddressHash) -> Option<AddressHash> {
self.map.get(destination).map(|entry| entry.received_from)
}
pub fn handle_packet(&mut self, original_packet: &Packet) -> (Packet, Option<AddressHash>) {
if original_packet.header.header_type == HeaderType::Type2 {
return (*original_packet, None);
}
if original_packet.header.packet_type == PacketType::Announce {
return (*original_packet, None);
}
if original_packet.header.destination_type == DestinationType::Plain
|| original_packet.header.destination_type == DestinationType::Group
{
return (*original_packet, None);
}
let entry = match self.map.get(&original_packet.destination) {
Some(entry) => entry,
None => return (*original_packet, None),
};
(
Packet {
header: Header {
ifac_flag: todo!(),
header_type: HeaderType::Type2,
propagation_type: original_packet.header.propagation_type,
destination_type: original_packet.header.destination_type,
packet_type: original_packet.header.packet_type,
hops: original_packet.header.hops,
},
ifac: original_packet.ifac,
destination: original_packet.destination,
transport: Some(entry.received_from),
context: original_packet.context,
data: original_packet.data,
},
Some(entry.iface),
)
}
}