use scion_proto::{address::IsdAsn, packet::ScionPacketRaw, wire_encoding::WireDecode};
use sciparse::{core::view::View, packet::view::ScionPacketView};
use snap_dataplane::dispatcher::Dispatcher;
use crate::{
network::{scion::routing::ScionNetworkTime, simulator::NetworkSimulator},
state::SharedPocketScionState,
};
pub(crate) struct AsNetSimDispatcher {
local_as: IsdAsn,
app_state: SharedPocketScionState,
}
impl AsNetSimDispatcher {
pub(crate) fn new(local_as: IsdAsn, app_state: SharedPocketScionState) -> Self {
Self {
local_as,
app_state,
}
}
}
impl Dispatcher for AsNetSimDispatcher {
fn try_dispatch(&self, packet: &ScionPacketView) {
let packet = match ScionPacketRaw::decode(&mut packet.as_bytes()) {
Ok(p) => p,
Err(e) => {
tracing::debug!(error=%e, "AsNetSimDispatcher: failed to decode ScionPacketView");
return;
}
};
let network_time = ScionNetworkTime::now();
self.app_state
.dispatch_to_network_sim(self.local_as, 0, network_time, packet);
}
}
pub(crate) struct NetSimDispatcher {
app_state: SharedPocketScionState,
}
impl NetSimDispatcher {
pub(crate) fn new(app_state: SharedPocketScionState) -> Self {
Self { app_state }
}
}
impl Dispatcher for NetSimDispatcher {
fn try_dispatch(&self, packet: &ScionPacketView) {
let packet = match ScionPacketRaw::decode(&mut packet.as_bytes()) {
Ok(p) => p,
Err(e) => {
tracing::debug!(error=%e, "NetSimDispatcher: failed to decode ScionPacketView");
return;
}
};
let network_time = ScionNetworkTime::now();
self.app_state.dispatch_to_network_sim(
packet.headers.address.ia.source,
0,
network_time,
packet,
);
}
}
impl SharedPocketScionState {
pub fn dispatch_to_network_sim(
&self,
local_as: IsdAsn,
local_interface: u16,
now: ScionNetworkTime,
packet: ScionPacketRaw,
) {
let state_guard = self.system_state.read().unwrap();
NetworkSimulator::new(
&state_guard.sim_receivers,
&state_guard.extern_as_handlers,
state_guard.topology.as_ref(),
)
.dispatch(local_as, local_interface, now, packet);
}
}