use std::{sync::Arc, time::Instant};
use scion_sdk_utils::task_handler::CancelTaskSet;
use sciparse::identifier::isd_asn::IsdAsn;
use snap_tun::server::SnapTunAuthorization;
use tokio::net::UdpSocket;
use crate::{
dispatcher::Dispatcher,
tunnel_gateway::{
dispatcher::TunnelGatewayDispatcherReceiver, gateway::TunnelGateway,
metrics::TunnelGatewayMetrics,
},
};
pub mod dispatcher;
pub mod gateway;
pub mod metrics;
pub(crate) mod packet_policy;
pub mod state;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ObservedPacketDirection {
Ingress,
Egress,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ObservedPacketMeta {
pub src_ia: IsdAsn,
pub dst_ia: IsdAsn,
pub packet_len: usize,
pub direction: ObservedPacketDirection,
}
pub trait TunnelGatewayObserver<S>: Send + Sync {
fn observe_packet(&self, now: Instant, session_data: &S, packet: ObservedPacketMeta);
}
#[derive(Debug, Default)]
pub struct NoopTunnelGatewayObserver;
impl<S> TunnelGatewayObserver<S> for NoopTunnelGatewayObserver {
fn observe_packet(&self, _now: Instant, _session_data: &S, _packet: ObservedPacketMeta) {}
}
pub fn start_tunnel_gateway<A, D, O>(
tasks: &mut CancelTaskSet,
socket: UdpSocket,
authz: Arc<A>,
dispatcher: Arc<D>,
observer: Arc<O>,
tun_dispatcher_rx: TunnelGatewayDispatcherReceiver,
server_static_secret: x25519_dalek::StaticSecret,
metrics: TunnelGatewayMetrics,
) where
A: SnapTunAuthorization + 'static,
D: Dispatcher + 'static,
O: TunnelGatewayObserver<A::SessionData> + ?Sized + 'static,
{
let tun_gateway = TunnelGateway::new(
socket,
server_static_secret,
authz,
dispatcher,
observer,
tun_dispatcher_rx,
metrics,
);
let token = tasks.cancellation_token();
tasks.spawn_cancellable_task(async move {
tun_gateway.start_server(token).await;
Ok(())
});
}