use crate::layer::{self, FnHandler};
use crate::managed::Slice;
use crate::wire::{ip as ip, udp, Payload, PayloadMut};
use super::{Recv, Send};
use super::packet::{Controller, Packet, RawPacket};
pub struct Endpoint<'a> {
ports: Slice<'a, u16>,
filter_ports: bool,
}
pub struct Receiver<'a, 'e, H> {
endpoint: UdpEndpoint<'a, 'e>,
handler: H,
}
pub struct Sender<'a, 'e, H> {
_endpoint: UdpEndpoint<'a, 'e>,
handler: H,
}
struct UdpEndpoint<'a, 'e> {
inner: &'a Endpoint<'e>,
}
impl<'a> Endpoint<'a> {
pub fn new<A>(ports: A) -> Self
where A: Into<Slice<'a, u16>>,
{
Endpoint {
ports: ports.into(),
filter_ports: true,
}
}
pub fn new_unfiltered() -> Self {
Endpoint {
ports: Slice::empty(),
filter_ports: false,
}
}
pub fn recv<H>(&mut self, handler: H) -> Receiver<'_, 'a, H> {
Receiver { endpoint: self.get_mut(), handler, }
}
pub fn recv_with<H>(&mut self, handler: H) -> Receiver<'_, 'a, FnHandler<H>> {
self.recv(FnHandler(handler))
}
pub fn send<H>(&mut self, handler: H) -> Sender<'_, 'a, H> {
Sender { _endpoint: self.get_mut(), handler, }
}
pub fn send_with<H>(&mut self, handler: H) -> Sender<'_, 'a, FnHandler<H>> {
self.send(FnHandler(handler))
}
pub fn filter_ports(&mut self, filter_ports: bool) {
self.filter_ports = filter_ports;
}
fn accepts(&self, port: u16) -> bool {
!self.filter_ports || self.ports.as_slice().contains(&port)
}
fn get_mut(&mut self) -> UdpEndpoint<'_, 'a> {
UdpEndpoint {
inner: self,
}
}
}
impl<P, H> layer::ip::Recv<P> for Receiver<'_, '_, H>
where
P: Payload,
H: Recv<P>,
{
fn receive(&mut self, layer::ip::InPacket { control, packet }: layer::ip::InPacket<P>) {
let capabilities = control.info().capabilities();
let checksum = capabilities.udp().rx_checksum(packet.repr());
let packet = match packet.repr().protocol() {
ip::Protocol::Udp => {
match udp::Packet::new_checked(packet, checksum) {
Ok(packet) => packet,
Err(_) => return,
}
},
_ => return,
};
if !self.endpoint.inner.accepts(packet.repr().dst_port) {
return
}
let control = Controller { inner: control };
let packet = Packet { control, packet };
self.handler.receive(packet);
}
}
impl<P, H> layer::ip::Send<P> for Sender<'_, '_, H>
where
P: Payload + PayloadMut,
H: Send<P>,
{
fn send<'a>(&mut self, packet: layer::ip::RawPacket<'a, P>) {
let layer::ip::RawPacket { control, payload } = packet;
let control = Controller { inner: control };
let packet = RawPacket { control, payload };
self.handler.send(packet)
}
}
impl<P: Payload, F> Recv<P> for FnHandler<F>
where F: FnMut(Packet<P>)
{
fn receive(&mut self, frame: Packet<P>) {
self.0(frame)
}
}
impl<P: Payload, F> Send<P> for FnHandler<F>
where F: FnMut(RawPacket<P>)
{
fn send(&mut self, frame: RawPacket<P>) {
self.0(frame)
}
}