From 7943de01ed323edbbe39529dad60faf282ee11f4 Mon Sep 17 00:00:00 2001 From: Thomas SAZERAT Date: Fri, 15 Mar 2024 00:42:27 +0100 Subject: [PATCH] added two new fonctionalities: The possibility to blacklist ip address with port, and the possibility to forward a message from an ip to another. --- config.json | 4 +-- src/config.rs | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 24 +++++++++++---- 3 files changed, 103 insertions(+), 7 deletions(-) create mode 100644 src/config.rs diff --git a/config.json b/config.json index 6cdeef7..8b463d1 100644 --- a/config.json +++ b/config.json @@ -1,13 +1,13 @@ { "forwarding": [ { - "from": "127.0.0.1:12345", + "from": "127.0.0.1:58545", "to": "127.0.0.1:12346", "doReverse": true } ], "blacklist": [ "127.0.0.1:11111", - "127.0.0.1:58109" + "127.0.0.1:55527" ] } \ No newline at end of file diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..0857f22 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,82 @@ +use std::fs::File; +use std::io::Read; + +use serde::Deserialize; +use serde_json::Value; + +#[derive(Deserialize, Debug)] +pub struct Forwarding { + from: String, + to: String, + #[serde(rename = "doReverse")] + do_reverse: bool +} + +impl Forwarding { + pub fn new(from: String, to: String, do_reverse: bool) -> Forwarding { + return Forwarding{ + from, + to, + do_reverse + } + } +} + +#[derive(Deserialize)] +pub struct Config { + blacklist: Vec, + forwarding: Vec +} + +impl Config { + pub fn new(blacklist: Vec, forwarding: Vec) -> Config { + return Config { + blacklist, + forwarding + } + } + + pub fn from_json(file_name: String) -> Config { + let mut file = File::open(file_name).unwrap(); + let mut buf = String::new(); + file.read_to_string(&mut buf).expect("Error reading config file content."); + let json: Value = serde_json::from_str(&buf).expect("Error parsing config file"); + let object_data = json.as_object().unwrap(); + let blacklist = object_data.get("blacklist").unwrap().as_array().unwrap(); + let forwarding = object_data.get("forwarding").unwrap().as_array().unwrap(); + let str_blacklist = Self::convert_to_vec_string(blacklist); + let mut vec_forwarding = Vec::new(); + for json_forwarding in forwarding { + let object_forwarding = json_forwarding.as_object().unwrap(); + let from = object_forwarding.get("from").unwrap().as_str().unwrap(); + let to = object_forwarding.get("to").unwrap().as_str().unwrap(); + let do_reverse = object_forwarding.get("doReverse").unwrap().as_bool().unwrap(); + let forwarding_struct = Forwarding::new(from.to_string(), to.to_string(), do_reverse); + vec_forwarding.push(forwarding_struct); + } + Config::new(str_blacklist, vec_forwarding) + } + + fn convert_to_vec_string(vec: &Vec) -> Vec { + let mut str_vec = Vec::new(); + for value in vec { + str_vec.push(value.as_str().unwrap().to_string()); + } + str_vec + } + + pub fn addr_is_blacklisted(&self, addr: String) -> bool { + self.blacklist.contains(&addr) + } + + pub fn is_forwarded(&self, addr: String) -> Option { + for elem_forwarding in &self.forwarding { + if elem_forwarding.from == addr { + return Some(elem_forwarding.to.clone()) + } else if elem_forwarding.do_reverse && elem_forwarding.to == addr { + return Some(elem_forwarding.from.clone()) + } + } + None + } +} diff --git a/src/main.rs b/src/main.rs index 22c757b..4c0039d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,13 @@ +mod config; + use std::io::stdin; use std::net::UdpSocket; +use crate::config::Config; fn main() { + let config = Config::from_json("config.json".to_string()); let server_address: String = get_server_address(); - listen(&server_address); + listen(&server_address, &config); } fn get_server_address() -> String { @@ -13,7 +17,8 @@ fn get_server_address() -> String { return server_address.trim().to_string(); } -fn listen(server_address: &str) { +fn listen(server_address: &str, config: &Config) { + let serv_config = config; println!("listening on {}", server_address); let socket: UdpSocket = UdpSocket::bind(server_address).expect("Error while binding the socket."); @@ -21,8 +26,17 @@ fn listen(server_address: &str) { let mut message: String = String::new(); let mut buf: [u8; 1024] = [0; 1024]; let (num_bytes, src_addr) = socket.recv_from(&mut buf).expect("Error while receiving message"); - message.push_str(std::str::from_utf8(&buf[..num_bytes]).expect("Invalid UTF-8 data")); - - println!("{}:{}", src_addr.to_string(), message); + if !serv_config.addr_is_blacklisted(src_addr.to_string()) { + message.push_str(std::str::from_utf8(&buf[..num_bytes]).expect("Invalid UTF-8 data")); + match serv_config.is_forwarded(src_addr.to_string()) { + Some(v) => { + socket.send_to(message.as_bytes(), v).expect("Error forwarding message to another ip."); + }, + None => { + //Nothing to do :) + } + } + println!("{} say: {}", src_addr.to_string(), message); + } } }