|
| 1 | +use crate::{network::NetworkError, FragmentAssembler, RoutingHandler}; |
| 2 | +use std::any::Any; |
| 3 | + |
| 4 | +use crossbeam_channel::{select_biased, Receiver}; |
| 5 | +use wg_internal::packet::{Packet, PacketType}; |
| 6 | + |
| 7 | +pub trait Processor { |
| 8 | + fn controller_recv(&self) -> &Receiver<Box<dyn Any>>; |
| 9 | + fn packet_recv(&self) -> &Receiver<Packet>; |
| 10 | + fn assembler(&mut self) -> &mut FragmentAssembler; |
| 11 | + fn routing_header(&mut self) -> &mut RoutingHandler; |
| 12 | + |
| 13 | + fn handle_msg(&mut self, msg: Vec<u8>); |
| 14 | + fn handle_command(&mut self, cmd: Box<dyn Any>); |
| 15 | + |
| 16 | + /// Handles a packet in a standard way |
| 17 | + /// # Errors |
| 18 | + /// returns an Errors if handling fails |
| 19 | + fn handle_packet(&mut self, pkt: Packet) -> Result<(), NetworkError> { |
| 20 | + let router = self.routing_header(); |
| 21 | + match pkt.pack_type { |
| 22 | + PacketType::MsgFragment(fragment) => { |
| 23 | + if let Some(msg) = self.assembler().add_fragment( |
| 24 | + fragment, |
| 25 | + pkt.session_id, |
| 26 | + pkt.routing_header.hops[0], |
| 27 | + ) { |
| 28 | + self.handle_msg(msg); |
| 29 | + } |
| 30 | + } |
| 31 | + PacketType::Ack(ack) => { |
| 32 | + router.handle_ack(&ack, pkt.session_id, pkt.routing_header.hops[0]); |
| 33 | + } |
| 34 | + PacketType::Nack(nack) => { |
| 35 | + router.handle_nack(&nack, pkt.session_id, pkt.routing_header.hops[0])?; |
| 36 | + } |
| 37 | + PacketType::FloodRequest(flood_request) => { |
| 38 | + router.handle_flood_request(flood_request, pkt.session_id)?; |
| 39 | + } |
| 40 | + PacketType::FloodResponse(flood_response) => { |
| 41 | + router.handle_flood_response(&flood_response); |
| 42 | + } |
| 43 | + } |
| 44 | + Ok(()) |
| 45 | + } |
| 46 | + |
| 47 | + fn run(&mut self) { |
| 48 | + loop { |
| 49 | + select_biased! { |
| 50 | + recv(self.controller_recv()) -> cmd => { |
| 51 | + if let Ok(cmd) = cmd { |
| 52 | + self.handle_command(cmd); |
| 53 | + } |
| 54 | + } |
| 55 | + |
| 56 | + recv(self.packet_recv()) -> pkt => { |
| 57 | + if let Ok(pkt) = pkt { |
| 58 | + match self.handle_packet(pkt) { |
| 59 | + Ok(()) => {}, |
| 60 | + Err(_) => return |
| 61 | + } |
| 62 | + } |
| 63 | + } |
| 64 | + } |
| 65 | + } |
| 66 | + } |
| 67 | +} |
0 commit comments