From b2f4333b405f3ea744c19ccdaf16bc4bd208f026 Mon Sep 17 00:00:00 2001 From: "Marco Cadetg (aider)" Date: Sat, 10 May 2025 12:27:35 +0200 Subject: [PATCH] feat: Make packet processing continuous by default and add interval config --- src/app.rs | 12 ++++++++++-- src/config.rs | 8 ++++++++ src/main.rs | 14 ++++++++++++++ src/network/mod.rs | 41 ++++++----------------------------------- 4 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/app.rs b/src/app.rs index df16094..8174287 100644 --- a/src/app.rs +++ b/src/app.rs @@ -137,6 +137,8 @@ impl App { let connections_update_clone = Arc::clone(&connections_update); self.connections_data_shared = Some(connections_update_clone.clone()); // Store Arc for on_tick + let app_config = self.config.clone(); // Clone config to move into the thread + thread::spawn(move || -> Result<()> { loop { let mut monitor = monitor_clone.lock().unwrap(); @@ -159,10 +161,16 @@ impl App { let mut connections = connections_update_clone.lock().unwrap(); *connections = new_connections; - // Sleep to avoid high CPU usage + // Sleep to avoid high CPU usage, controlled by config drop(connections); drop(monitor); - thread::sleep(std::time::Duration::from_millis(250)); // Update data more frequently + + let sleep_duration_ms = if app_config.packet_processing_interval_ms == 0 { + 1 // Minimal sleep (1ms) to prevent 100% CPU usage on one core + } else { + app_config.packet_processing_interval_ms + }; + thread::sleep(std::time::Duration::from_millis(sleep_duration_ms)); } }); diff --git a/src/config.rs b/src/config.rs index 264933c..4dd38cf 100644 --- a/src/config.rs +++ b/src/config.rs @@ -17,6 +17,8 @@ pub struct Config { pub show_locations: bool, /// Filter out localhost (loopback) traffic pub filter_localhost: bool, + /// Interval in milliseconds for the packet processing loop's sleep. 0 means minimal sleep for continuous processing. + pub packet_processing_interval_ms: u64, /// Custom configuration file path pub config_path: Option, } @@ -30,6 +32,7 @@ impl Default for Config { refresh_interval: 1000, show_locations: true, filter_localhost: true, + packet_processing_interval_ms: 0, // Default to continuous processing (minimal sleep) config_path: None, } } @@ -92,6 +95,11 @@ impl Config { config.filter_localhost = false; } } + "packet_processing_interval_ms" => { + if let Ok(interval) = value.parse::() { + config.packet_processing_interval_ms = interval; + } + } _ => { // Ignore unknown keys } diff --git a/src/main.rs b/src/main.rs index 7a5e54f..d7bc686 100644 --- a/src/main.rs +++ b/src/main.rs @@ -49,6 +49,15 @@ fn main() -> Result<()> { .help("Interface language (en, fr, etc.)") .required(false), ) + .arg( + Arg::new("packet_processing_interval") + .short('P') + .long("packet-processing-interval") + .value_name("MILLISECONDS") + .help("Interval for packet processing loop sleep (ms). 0 for continuous.") + .value_parser(clap::value_parser!(u64)) + .required(false), + ) .get_matches(); // Initialize configuration @@ -68,6 +77,11 @@ fn main() -> Result<()> { info!("Using language: {}", language); } + if let Some(interval) = matches.get_one::("packet_processing_interval") { + config.packet_processing_interval_ms = *interval; + info!("Using packet processing interval: {}ms", interval); + } + // Initialize internationalization let i18n = i18n::I18n::new(&config.language)?; info!( diff --git a/src/network/mod.rs b/src/network/mod.rs index 23176c9..6e6e3c0 100644 --- a/src/network/mod.rs +++ b/src/network/mod.rs @@ -168,8 +168,8 @@ pub struct NetworkMonitor { collect_process_info: bool, filter_localhost: bool, local_ips: std::collections::HashSet, - last_packet_check: Instant, - initial_packet_processing_done: bool, // New flag + // last_packet_check: Instant, // Removed for continuous processing by default + // initial_packet_processing_done: bool, // Removed } /// Manages lookup of service names from a services file. @@ -394,10 +394,7 @@ impl NetworkMonitor { // geo_db, // Field removed collect_process_info: false, filter_localhost, - // Initialize last_packet_check to a time in the past - // to ensure the first call to process_packets runs. - last_packet_check: Instant::now() - Duration::from_millis(200), - initial_packet_processing_done: false, // Initialize the new flag + // last_packet_check and initial_packet_processing_done removed }) } @@ -659,35 +656,9 @@ impl NetworkMonitor { } // This closes the `match protocol` }; // This closes the `process_single_packet` closure definition - // If it's the very first run (during App::start_capture), be extremely lightweight. - if !self.initial_packet_processing_done { - log::debug!("NetworkMonitor::process_packets - First run, skipping detailed packet processing for quick startup."); - // Optionally, process a single packet or none at all. - // For now, let's try processing 0-1 packets to see if it helps. - if let Some(ref mut cap) = self.capture { - match cap.next_packet() { - Ok(packet) => { - process_single_packet(packet.data, &mut self.connections, &self.local_ips, &self.interface, &self.service_lookup); - log::debug!("NetworkMonitor::process_packets - Processed one packet on first run."); - } - Err(pcap::Error::TimeoutExpired) => { - log::debug!("NetworkMonitor::process_packets - No packets on first check."); - } - Err(e) => { - error!("NetworkMonitor::process_packets - Error reading packet on first run: {}", e); - } - } - } - self.initial_packet_processing_done = true; - self.last_packet_check = Instant::now(); // Update timestamp - return Ok(()); - } - - // Only check packets every 100ms to avoid too frequent checks for subsequent runs - if self.last_packet_check.elapsed() < Duration::from_millis(100) { - return Ok(()); - } - self.last_packet_check = Instant::now(); + // Removed initial_packet_processing_done logic and last_packet_check cooldown. + // The loop will now attempt to process packets more continuously, + // controlled by the sleep interval in the app.rs background thread. // Get packets from the capture if let Some(ref mut cap) = self.capture {