From 6e0dc256b0c4a1d13749b72f18d9298a911f7b22 Mon Sep 17 00:00:00 2001 From: Paul Lecuq Date: Wed, 1 Nov 2023 17:20:03 +0100 Subject: [PATCH] feat: updated dependencies / rework * updated dependencies * reworked inotify instance handling * reworked fw module --- Cargo.lock | 84 +++++++++++++++++++---------------------------- Cargo.toml | 16 ++++----- src/config.rs | 30 +++++++++-------- src/fw.rs | 39 ++++++++++++---------- src/ip.rs | 2 +- src/ipblc.rs | 50 +++++++++++++++------------- src/monitoring.rs | 1 - src/websocket.rs | 12 +++---- 8 files changed, 112 insertions(+), 122 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 52ceae9..a8e9070 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -122,6 +122,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + [[package]] name = "block-buffer" version = "0.10.4" @@ -537,7 +543,7 @@ dependencies = [ [[package]] name = "ipblc" -version = "1.2.2" +version = "1.3.0" dependencies = [ "chrono", "clap", @@ -569,9 +575,9 @@ checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" dependencies = [ "wasm-bindgen", ] @@ -610,15 +616,6 @@ version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" -[[package]] -name = "memoffset" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" -dependencies = [ - "autocfg", -] - [[package]] name = "mime" version = "0.3.17" @@ -672,7 +669,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9201688bd0bc571dfa4c21ce0a525480c8b782776cf88e12571fa89108dd920" dependencies = [ - "bitflags", + "bitflags 1.3.2", "err-derive", "log", "nftnl-sys", @@ -691,15 +688,13 @@ dependencies = [ [[package]] name = "nix" -version = "0.26.4" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags", + "bitflags 2.4.1", "cfg-if", "libc", - "memoffset", - "pin-utils", ] [[package]] @@ -879,7 +874,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1057,7 +1052,7 @@ version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -1096,9 +1091,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", @@ -1224,7 +1219,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "system-configuration-sys", ] @@ -1361,9 +1356,9 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "tungstenite" -version = "0.19.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15fba1a6d6bb030745759a9a2a588bfe8490fc8b4751a277db3a0be1c9ebbf67" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" dependencies = [ "byteorder", "bytes", @@ -1378,7 +1373,6 @@ dependencies = [ "thiserror", "url", "utf-8", - "webpki", ] [[package]] @@ -1466,9 +1460,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1476,9 +1470,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" dependencies = [ "bumpalo", "log", @@ -1491,9 +1485,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" dependencies = [ "cfg-if", "js-sys", @@ -1503,9 +1497,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1513,9 +1507,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", @@ -1526,30 +1520,20 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" dependencies = [ "js-sys", "wasm-bindgen", ] -[[package]] -name = "webpki" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "webpki-roots" version = "0.25.2" diff --git a/Cargo.toml b/Cargo.toml index 591f006..4903e20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ipblc" -version = "1.2.2" +version = "1.3.0" edition = "2021" authors = ["PaulBSD "] description = "ipblc is a tool that search and send attacking ip addresses to ipbl" @@ -10,19 +10,19 @@ repository = "https://git.paulbsd.com/paulbsd/ipblc" [dependencies] chrono = { version = "0.4", features = ["serde"] } -clap = { version = "4.2", features = ["string"] } +clap = { version = "4.4", features = ["string"] } git-version = "0.3" -ipnet = "2.7" +ipnet = "2.9" lazy_static = "1.4" mnl = "0.2" nftnl = "0.6" -nix = "0.26" -regex = "1.8" -reqwest = { version = "0.11", default-features = false, features = ["json","rustls-tls"] } +nix = { version = "0.27", features = ["hostname", "inotify"] } +regex = "1.10" +reqwest = { version = "0.11", default-features = false, features = ["json", "rustls-tls"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -tokio = { version = "1.28", features = ["full", "sync"] } -tungstenite = { version = "0.19", features = ["handshake","rustls-tls-native-roots"] } +tokio = { version = "1.33", features = ["full", "sync"] } +tungstenite = { version = "0.20", features = ["handshake", "rustls-tls-native-roots"] } ## to optimize binary size (slow compile time) #[profile.release] diff --git a/src/config.rs b/src/config.rs index 1a76101..8cbc299 100644 --- a/src/config.rs +++ b/src/config.rs @@ -6,7 +6,7 @@ use chrono::Duration; use clap::{Arg, ArgAction, ArgMatches, Command}; use git_version::git_version; use ipnet::IpNet; -use nix::sys::inotify::{AddWatchFlags, InitFlags, Inotify, WatchDescriptor}; +use nix::sys::inotify::{AddWatchFlags, Inotify, WatchDescriptor}; use regex::Regex; use reqwest::{Client, Error as ReqError, Response}; use serde::{Deserialize, Serialize}; @@ -20,13 +20,12 @@ const WSSUBSCRIPTION: &str = "ipbl"; const CONFIG_RETRY: u64 = 1; const WEB_CLIENT_TIMEOUT: i64 = 5; -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct Context { pub blocklist: HashMap, pub cfg: Config, pub discovery: Discovery, pub flags: Flags, - pub instance: Box, pub sas: HashMap, pub hashwd: HashMap, } @@ -48,7 +47,7 @@ pub struct Flags { } impl Context { - pub async fn new() -> Self { + pub async fn new(inotify: &Inotify) -> Self { // Get flags let argp: ArgMatches = Context::argparse(); let debug: bool = argp.get_one::("debug").unwrap().to_owned(); @@ -63,13 +62,12 @@ impl Context { urls: HashMap::new(), }, sas: HashMap::new(), - instance: Box::new(Inotify::init(InitFlags::empty()).unwrap()), blocklist: HashMap::new(), hashwd: HashMap::new(), }; print!("Loading config ... "); - ctx.load().await.unwrap(); + ctx.load(&inotify).await.unwrap(); ctx } @@ -113,7 +111,7 @@ impl Context { Ok(data) } - pub async fn load(&mut self) -> Result<(), Box> { + pub async fn load(&mut self, inotify: &Inotify) -> Result<(), Box> { if cfg!(test) { return Ok(()); } @@ -137,7 +135,7 @@ impl Context { if last_in_err { println!("creating sas"); } - self.create_sas().await?; + self.create_sas(&inotify).await?; if last_in_err { println!("created sas"); } @@ -153,9 +151,9 @@ impl Context { res } - pub async fn get_blocklist_toblock(&mut self) -> Vec { + pub async fn get_blocklist_toblock(&self) -> Vec { let mut res: Vec = vec![]; - for (_, block) in self.blocklist.iter_mut() { + for (_, block) in self.blocklist.iter() { match self.cfg.sets.get(&block.ipdata.src) { Some(set) => { if block.tryfail >= set.tryfail { @@ -228,15 +226,17 @@ impl Context { removed } - pub async fn create_sas(&mut self) -> Result<(), Box> { + pub async fn create_sas( + &mut self, + inotify: &Inotify, + ) -> Result<(), Box> { for (src, set) in self.cfg.sets.iter() { let p = Path::new(set.path.as_str()); if p.is_dir() { let wd = match self.hashwd.get(&set.path.to_string()) { Some(wd) => *wd, None => { - let res = self - .instance + let res = inotify .add_watch(set.path.as_str(), AddWatchFlags::IN_MODIFY) .unwrap(); self.hashwd.insert(set.path.to_string(), res); @@ -559,10 +559,12 @@ impl Hash for Set { mod test { use super::*; use crate::ip::*; + use nix::sys::inotify::InitFlags; use Context; pub async fn prepare_test_data() -> Context { - let mut ctx = Context::new().await; + let inotify = Inotify::init(InitFlags::empty()).unwrap(); + let mut ctx = Context::new(&inotify).await; let now: DateTime = Local::now().trunc_subsecs(0); ctx.blocklist = HashMap::new(); diff --git a/src/fw.rs b/src/fw.rs index 647f3a6..8eba965 100644 --- a/src/fw.rs +++ b/src/fw.rs @@ -8,31 +8,35 @@ use std::{ net::{Ipv4Addr, Ipv6Addr}, }; -pub fn fwinit(t: isize) -> (Batch, Table) { +pub enum FwTableType { + IPv4, + IPv6, +} + +pub fn fwglobalinit<'a>() -> ((Batch, Table), (Batch, Table)) { + let (batch4, table4) = fwinit(FwTableType::IPv4); + let (batch6, table6) = fwinit(FwTableType::IPv6); + ((batch4, table4), (batch6, table6)) +} + +fn fwinit(t: FwTableType) -> (Batch, Table) { let table_name: String; let table: Table; match t { - 4 => { - table_name = format!("{PKG_NAME}{t}"); - table = Table::new( - &CString::new(format!("{table_name}")).unwrap(), - ProtoFamily::Ipv4, - ); - } - 6 => { - table_name = format!("{PKG_NAME}{t}"); - table = Table::new( - &CString::new(format!("{table_name}")).unwrap(), - ProtoFamily::Ipv6, - ); - } - _ => { + FwTableType::IPv4 => { table_name = format!("{PKG_NAME}4"); table = Table::new( &CString::new(format!("{table_name}")).unwrap(), ProtoFamily::Ipv4, ); } + FwTableType::IPv6 => { + table_name = format!("{PKG_NAME}6"); + table = Table::new( + &CString::new(format!("{table_name}")).unwrap(), + ProtoFamily::Ipv6, + ); + } } let mut batch = Batch::new(); @@ -48,8 +52,7 @@ pub fn fwblock( ret: &mut Vec, fwlen: &mut usize, ) -> std::result::Result<(), Error> { - let (mut batch4, table4) = fwinit(4); - let (mut batch6, table6) = fwinit(6); + let ((mut batch4, table4), (mut batch6, table6)) = fwglobalinit(); // build chain for ipv4 let mut chain4 = Chain::new(&CString::new(PKG_NAME).unwrap(), &table4); diff --git a/src/ip.rs b/src/ip.rs index 5ced4d3..b35c61a 100644 --- a/src/ip.rs +++ b/src/ip.rs @@ -174,7 +174,7 @@ fn parse_date(input: regex::Captures) -> DateTime { match Local.with_ymd_and_hms(ymd[0] as i32, ymd[1], ymd[2], hms[0], hms[1], hms[2]) { LocalResult::Single(s) => s, LocalResult::Ambiguous(a, _b) => a, - LocalResult::None => Local::now(), + LocalResult::None => Local::now().trunc_subsecs(0), }; date } diff --git a/src/ipblc.rs b/src/ipblc.rs index e9ca0d9..d2cf688 100644 --- a/src/ipblc.rs +++ b/src/ipblc.rs @@ -1,5 +1,5 @@ use crate::config::{Context, GIT_VERSION}; -use crate::fw::{fwblock, fwinit}; +use crate::fw::{fwblock, fwglobalinit}; use crate::ip::{filter, IpData, IpEvent}; use crate::ipevent; use crate::monitoring::apiserver; @@ -10,7 +10,7 @@ use crate::websocket::{send_to_ipbl_websocket, websocketpubsub, websocketreqrep} use chrono::prelude::*; use chrono::prelude::{DateTime, Local}; use chrono::Duration; -use nix::sys::inotify::InotifyEvent; +use nix::sys::inotify::{InitFlags, Inotify, InotifyEvent}; use std::collections::HashMap; use std::sync::Arc; use tokio::sync::mpsc::{channel, Receiver, Sender}; @@ -22,16 +22,17 @@ const WS_CHAN_SIZE: usize = 64; const LOOP_MAX_WAIT: u64 = 5; pub async fn run() { - let globalctx = Context::new().await; + let inotify = Inotify::init(InitFlags::empty()).unwrap(); + let globalctx = Context::new(&inotify).await; let ctxarc = Arc::new(RwLock::new(globalctx)); + let mut fwlen: usize = 0; let pkgversion = format!("{}@{}", env!("CARGO_PKG_VERSION"), GIT_VERSION); let mut last_cfg_reload: DateTime = Local::now().trunc_subsecs(0); println!("Launching {}, version {}", PKG_NAME, pkgversion); - fwinit(4); - fwinit(6); + fwglobalinit(); let ctxapi = Arc::clone(&ctxarc); apiserver(&ctxapi).await.unwrap(); @@ -49,7 +50,9 @@ pub async fn run() { let mut wssocketrr = websocketreqrep(&ctxwsrr).await; // init file watcher - let mut blrx = watchfiles(&ctxarc).await; + let inoarc = Arc::new(RwLock::new(inotify)); + let inoclone = Arc::clone(&inoarc); + let mut blrx = watchfiles(inoclone).await; let ctxclone = Arc::clone(&ctxarc); let ipeventclone = Arc::clone(&ipeventtxarc); @@ -68,7 +71,7 @@ pub async fn run() { let (toblock,server); { - let mut ctx = ctxclone.write().await; + let ctx = ctxclone.read().await; toblock = ctx.get_blocklist_toblock().await; server = ctx.flags.server.clone(); } @@ -117,15 +120,21 @@ pub async fn run() { } let ctxclone = Arc::clone(&ctxarc); - handle_cfg_reload(&ctxclone, &mut last_cfg_reload).await; + let inoclone = Arc::clone(&inoarc); + handle_cfg_reload(&ctxclone, &mut last_cfg_reload, inoclone).await; } } -async fn handle_cfg_reload(ctxclone: &Arc>, last_cfg_reload: &mut DateTime) { +async fn handle_cfg_reload( + ctxclone: &Arc>, + last_cfg_reload: &mut DateTime, + inoarc: Arc>, +) { let now_cfg_reload = Local::now().trunc_subsecs(0); if (now_cfg_reload - *last_cfg_reload) > Duration::seconds(LOOP_MAX_WAIT as i64) { let mut ctx = ctxclone.write().await; - match ctx.load().await { + let inotify = inoarc.read().await; + match ctx.load(&inotify).await { Ok(_) => { *last_cfg_reload = Local::now().trunc_subsecs(0); } @@ -137,9 +146,12 @@ async fn handle_cfg_reload(ctxclone: &Arc>, last_cfg_reload: &mu } async fn handle_fwblock(ctxclone: Arc>, ret: &mut Vec, fwlen: &mut usize) { - let toblock = { + { let mut ctx = ctxclone.write().await; ctx.gc_blocklist().await; + } + let toblock = { + let ctx = ctxclone.read().await; ctx.get_blocklist_toblock().await }; @@ -152,19 +164,11 @@ async fn handle_fwblock(ctxclone: Arc>, ret: &mut Vec, f }; } -async fn watchfiles(ctxarc: &Arc>) -> Receiver { +async fn watchfiles(inoarc: Arc>) -> Receiver { let (bltx, blrx): (Sender, Receiver) = channel(BL_CHAN_SIZE); - let ctxclone = Arc::clone(ctxarc); tokio::spawn(async move { loop { - let events; - let instance; - { - let ctx = ctxclone.read().await; - instance = ctx.instance.clone(); - } - - events = instance.read_events().unwrap(); + let events = inoarc.read().await.read_events().unwrap(); for inevent in events { let date: DateTime = Local::now().trunc_subsecs(0); @@ -201,7 +205,7 @@ async fn compare_files_changes( let sas; { let ctx = ctxarc.read().await; - sas = ctx.clone().sas; + sas = ctx.sas.clone(); sask = sas.keys(); tnets = ctx.cfg.build_trustnets(); } @@ -251,7 +255,7 @@ async fn compare_files_changes( } for ip in iplist { let ipe = ipevent!("add", "file", gethostname(true), ip); - let ipetx = ipeventtx.write().await; + let ipetx = ipeventtx.read().await; ipetx.send(ipe).await.unwrap(); } } diff --git a/src/monitoring.rs b/src/monitoring.rs index 90b5b10..456691a 100644 --- a/src/monitoring.rs +++ b/src/monitoring.rs @@ -22,7 +22,6 @@ pub async fn apiserver(ctxarc: &Arc>) -> io::Result<()> { tokio::spawn(async move { loop { - //apitx.send(String::from("")).await.unwrap(); match listener.accept().await { Ok((stream, _addr)) => { //let mut buf = [0; 1024]; diff --git a/src/websocket.rs b/src/websocket.rs index 596b3f3..95ed015 100644 --- a/src/websocket.rs +++ b/src/websocket.rs @@ -41,7 +41,7 @@ pub async fn websocketpubsub( tokio::spawn(async move { loop { let mut ws = websocket.write().await; - match ws.read_message() { + match ws.read() { Ok(msg) => { let tosend: IpEvent = match serde_json::from_str(msg.to_string().as_str()) { Ok(o) => o, @@ -52,7 +52,7 @@ pub async fn websocketpubsub( if tosend.ipdata.hostname != gethostname(true) || tosend.msgtype == "init".to_string() { - let txps = txpubsub.write().await; + let txps = txpubsub.read().await; txps.send(tosend).await.unwrap(); } } @@ -90,9 +90,7 @@ pub async fn websocketconnect<'a>( } println!("connected to {endpoint}"); let msg = json!({ "hostname": hostname }); - socket - .write_message(Message::Text(msg.to_string())) - .unwrap(); + socket.send(Message::Text(msg.to_string())).unwrap(); Ok(socket) } @@ -103,7 +101,7 @@ pub async fn send_to_ipbl_websocket( let msg = format!("{val}", val = serde_json::to_string(&ip).unwrap()); if ws.can_write() { - match ws.write_message(Message::Text(msg)) { + match ws.send(Message::Text(msg)) { Ok(_) => {} Err(e) => { println!("err send read: {e:?}"); @@ -115,7 +113,7 @@ pub async fn send_to_ipbl_websocket( }; if ws.can_read() { - match ws.read_message() { + match ws.read() { Ok(_) => {} Err(e) => { println!("err send read: {e:?}");