diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2025-05-17 14:58:32 +0200 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2025-05-18 14:58:32 +0200 |
commit | 97387d0f1c163b43975e7dfe67fc6bbc67482e31 (patch) | |
tree | 603ef9c4494af8b6fe6fad47dc2a687c856552ba | |
parent | 46ef266139d15981fe814c6760c8828ee867c45c (diff) |
rs-simple: added argh command line parser and "stable" flow table index
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
-rw-r--r-- | examples/rs-simple/Cargo.toml | 1 | ||||
-rw-r--r-- | examples/rs-simple/src/main.rs | 87 |
2 files changed, 63 insertions, 25 deletions
diff --git a/examples/rs-simple/Cargo.toml b/examples/rs-simple/Cargo.toml index b5e0eebb5..5afe25664 100644 --- a/examples/rs-simple/Cargo.toml +++ b/examples/rs-simple/Cargo.toml @@ -5,6 +5,7 @@ authors = ["Toni Uhlig <toni@impl.cc>"] edition = "2024" [dependencies] +argh = "0.1" bytes = "1" crossterm = "0.29.0" io = "0.0.2" diff --git a/examples/rs-simple/src/main.rs b/examples/rs-simple/src/main.rs index 5cfbded29..9efcb770a 100644 --- a/examples/rs-simple/src/main.rs +++ b/examples/rs-simple/src/main.rs @@ -1,3 +1,4 @@ +use argh::FromArgs; use bytes::BytesMut; use crossterm::{ cursor, @@ -29,6 +30,14 @@ use tui::{ widgets::{Block, Borders, List, ListItem, Row, Table, TableState}, }; +#[derive(FromArgs, Debug)] +/// Simple Rust nDPIsrvd Client Example +struct Args { + /// nDPIsrvd host(s) to connect to + #[argh(option)] + host: Vec<String>, +} + #[derive(Debug)] enum ParseError { Protocol(), @@ -326,15 +335,24 @@ impl PartialEq for DaemonKey { #[tokio::main] async fn main() { - let server_address = "127.0.0.1:7000"; + let args: Args = argh::from_env(); + if args.host.len() == 0 { + eprintln!("At least one --host required"); + return; + } - let mut stream = match TcpStream::connect(server_address).await { - Ok(stream) => stream, - Err(e) => { - eprintln!("Connection to {} failed: {}", server_address, e); - return; + let mut connections: Vec<TcpStream> = Vec::new(); + for host in args.host { + match TcpStream::connect(host.clone()).await { + Ok(stream) => { + connections.push(stream); + } + Err(e) => { + eprintln!("Fehler bei Verbindung zu {}: {}", host, e); + } } - }; + } + if let Err(e) = terminal::enable_raw_mode() { eprintln!("Could not enable terminal raw mode: {}", e); return; @@ -351,7 +369,6 @@ async fn main() { let backend = CrosstermBackend::new(stdout); let mut terminal = Terminal::new(backend); - let mut buffer = BytesMut::with_capacity(33792usize); let (tx, mut rx): (mpsc::Sender<String>, mpsc::Receiver<String>) = mpsc::channel(1024); let data = Arc::new(Mutex::new(Stats::default())); let data_tx = Arc::clone(&data); @@ -379,36 +396,50 @@ async fn main() { } } }); - tokio::spawn(async move { - loop { - let n = match stream.read_buf(&mut buffer).await { - Ok(len) => len, - Err(_) => { - continue; // Versuche es erneut, wenn ein Fehler auftritt + + for mut stream in connections { + let cloned_tx = tx.clone(); + tokio::spawn(async move { + let mut buffer = BytesMut::with_capacity(33792usize); + + loop { + let n = match stream.read_buf(&mut buffer).await { + Ok(len) => len, + Err(_) => { + continue; // Versuche es erneut, wenn ein Fehler auftritt + } + }; + if n == 0 { + break; } - }; - if n == 0 { - break; - } - while let Some(message) = parse_message(&mut buffer) { - match tx.send(message).await { - Ok(_) => (), - Err(_) => return + while let Some(message) = parse_message(&mut buffer) { + match cloned_tx.send(message).await { + Ok(_) => (), + Err(_) => return + } } } - } - }); + }); + } let mut table_state = TableState::default(); + let mut old_selected: Option<FlowKey> = None; loop { let flows: Vec<(FlowKey, (FlowExpiration, FlowValue))> = flow_cache_rx.iter().map(|(k, v)| (k.as_ref().clone(), v.clone())).collect(); let mut table_selected = match table_state.selected() { - Some(table_index) => { + Some(mut table_index) => { if flows.len() > 0 && table_index >= flows.len() { flows.len() - 1 } else { + if let Some(ref old_flow_key_selected) = old_selected { + if let Some(old_index) = flows.iter().position(|x| x.0 == *old_flow_key_selected) { + if old_index != table_index { + table_index = old_index; + } + } + } table_index } } @@ -424,12 +455,14 @@ async fn main() { i if i == 0 => flows.len() - 1, i => i - 1, }; + old_selected = Some(flows.get(table_selected).unwrap().0.clone()); }, Some(KeyCode::Down) => { table_selected = match table_selected { i if flows.len() == 0 || i >= flows.len() - 1 => 0, i => i + 1, }; + old_selected = Some(flows.get(table_selected).unwrap().0.clone()); }, Some(KeyCode::PageUp) => { table_selected = match table_selected { @@ -438,6 +471,7 @@ async fn main() { i if i < 25 => 0, i => i - 25, }; + old_selected = Some(flows.get(table_selected).unwrap().0.clone()); }, Some(KeyCode::PageDown) => { table_selected = match table_selected { @@ -445,15 +479,18 @@ async fn main() { i if flows.len() < 25 || i >= flows.len() - 25 => flows.len() - 1, i => i + 25, }; + old_selected = Some(flows.get(table_selected).unwrap().0.clone()); }, Some(KeyCode::Home) => { table_selected = 0; + old_selected = Some(flows.get(table_selected).unwrap().0.clone()); }, Some(KeyCode::End) => { table_selected = match table_selected { _ if flows.len() == 0 => 0, _ => flows.len() - 1, }; + old_selected = Some(flows.get(table_selected).unwrap().0.clone()); }, Some(_) => (), None => () |