use std::collections::BTreeMap; use serde::{Deserialize, Serialize}; use root::concepts::neighbour::Neighbour; use root::concepts::packet::Packet; use root::framework::RoutingSystem; use root::router::{DummyMAC, NoMACSystem, Router}; #[derive(Serialize, Deserialize)] pub struct VirtualSystem{ pub routers: Vec>, pub packets: BTreeMap>, i32)>>, } impl VirtualSystem{ pub fn create(nodes: &[&str], links: &[(i32, &str, &str, u16)]) -> VirtualSystem{ let routers: Vec> = nodes.iter().map(|id|{ let mut router = Router::new(id.to_string()); for (lid, a, b, metric) in links{ if a == id || b == id { let nid = { if a == id {b} else {a} }; router.links.insert(*lid, Neighbour{ addr: nid.to_string(), routes: Default::default(), metric: *metric, }); } } router }).collect(); VirtualSystem{ routers, packets: Default::default() } } pub fn update_edge(&mut self, edge_id: i32, metric: u16){ for router in &mut self.routers{ router.links.entry(edge_id).and_modify(|edge| { edge.metric = metric }); } } pub fn get_node(&mut self, node: &str) -> &mut Router{ self.routers.iter_mut().find(|r| r.address == node).unwrap() } pub fn get_next_hop(&self, cur: &str, src: &str) -> String{ let router = self.routers.iter().find(|r|r.address == cur).unwrap_or_else(|| panic!("No node {cur} found")); router.routes.get(src).unwrap_or_else(|| panic!("No route found to {src}")).next_hop.to_string() } pub fn get_metric_to(&self, cur: &str, src: &str) -> u16{ let router = self.routers.iter().find(|r|r.address == cur).unwrap_or_else(|| panic!("No node {cur} found")); router.routes.get(src).unwrap_or_else(|| panic!("No route found to {src}")).metric } pub fn get_seqno_to(&self, cur: &str, src: &str) -> u16{ let router = self.routers.iter().find(|r|r.address == cur).unwrap_or_else(|| panic!("No node {cur} found")); router.routes.get(src).unwrap_or_else(|| panic!("No route found to {src}")).source.data.seqno } pub fn flush_packets(&mut self){ for router in &mut self.routers{ for packet in router.outbound_packets.drain(..){ let link_packets = self.packets.entry(packet.dest).or_default(); link_packets.push((packet.packet, packet.link)); } } } pub fn tick(&mut self){ for (node, packets) in &mut self.packets{ if let Some(router) = self.routers.iter_mut().find(|x|x.address == *node){ for (packet, link) in packets{ if let Some(neigh_addr) = router.links.get(link).map(|x| x.addr.clone()){ router.handle_packet(packet, link, &neigh_addr).unwrap(); } } } } self.packets.clear(); for router in &mut self.routers{ router.full_update(); } self.flush_packets() } pub fn tick_n(&mut self, times: i32){ for _ in 0..times{ self.tick(); } } pub fn freeze(&mut self) -> String{ serde_json::to_string(&self).unwrap() } pub fn restore(state: String) -> VirtualSystem{ serde_json::from_str(&state).unwrap() } } impl RoutingSystem for VirtualSystem{ type NodeAddress = String; type Link = i32; type MACSystem = NoMACSystem; }