From 8220be039036a667f0fdffe1e6923ddf0095dc53 Mon Sep 17 00:00:00 2001 From: GyulyVGC Date: Thu, 23 Oct 2025 22:51:56 +0200 Subject: [PATCH 1/7] add icon to freeze live capture --- resources/fonts/subset/icons.ttf | Bin 19828 -> 20032 bytes src/gui/components/header.rs | 66 ++++++++++++++++++++++++++++--- src/gui/sniffer.rs | 6 +++ src/gui/types/message.rs | 2 + src/utils/types/icon.rs | 4 ++ 5 files changed, 73 insertions(+), 5 deletions(-) diff --git a/resources/fonts/subset/icons.ttf b/resources/fonts/subset/icons.ttf index a77400c68889757fe6342dd9122f62c947ea5b6c..f577e3c153029418d7d8d56d8ea82da520572fa5 100644 GIT binary patch delta 931 zcmYLHNla5g82;wH0V-X1ZCUk|&BqP}QCdK#D+P)mQ6WS?Q`Ux1Z3GpKNvj8f28p4r z!~+@+#uHH!6ZaSoNDK!TPDC%77`dTdNZ|RuV&Y6@{`vmzpMU0GeowL2w^PR=< z?;Q%LDtSWVBJsNZ!83g&ov%6o-UGO~uh-j?bK~7OaT@RN`Few1T^{FjIi3`X&p$jO zT@$Ja&k(*oc)Z)&YVR=s;wQpa{N9lO8|CH1(?a?&ufJFBx=OsqN1u2bI6gESb2_Gh zK2S*fOe8o8u(bC1rK53Gf1szQXneigFsjM#>9G|$^_jZFC7u}8u`*U0cCmI=5T0UL zq6eYyOLi+bN)c&UlEE=R(gKMz0-cIbhDy|<14B4Vk!zy>C2*n&4e;XRx=#J9eo{ZG zAJlo`HBXXe_;19Lq>Pd8-Pl8NFKXZ>v*>kGAUrE%HH*X}Dmq5DAr^Xr(S$h3Y_Y~C zBqk-NY}_QnmYSBHk-1sP%FfBn%P%M_vTN>(OSY75-B#vsmRD46uc~(K*trY4_khY8 z-X)F)DT8Rm8z!?0Y*A2zQ^K66h<)N?uJB4e6=l#1`kw~3;jkfKm@p0)CyZ+*#k3Mv z8Fx-fmO7-HX4%|j{$X)g0+un$ywzp(S??z-Cp9I_B_nw(g{M5-G%YLgw7g(5*bdlE z*d}f7Q{8C`>2n$J8ApN{_cC>vp3K?J0%gUcE{RWgBK0Czb`i^tjxnb)Cv$8Q{fdgU z#iom#Uu+WUJi=Jw?T7g-ovRg{E%~gc^nn(sfDolIL`gEjMjlK|yPo7?PP3gw#iwWr zJIgVXB9$>X>KUtdIwC^wu=@2A?HmMF*LjCXGFY-UvlfaNMljub)Xb~v^tJRVqjyb^ z!dLfQJ7|Z4P!!dYd>|H9+7oCpZioijmIIx<3vC*-4kX*mAWME24Q3 zUKxnTAk>S92nmTOkRXUCSvN8Ixe1Eu!iz4tkTmilIK9UkpO^1^ywAh;eed&}R|{lg zj^uync zxD1Kfcruga&14<>C)m#<#z(~PX7nBai;uumQp~2vE$T%b7uYX~$(V3{mILU;A(@rb zcsipRQ~3b;6R0n3nL~rWhE0KCz5fqr@F~Ri+kKPDzM3nYpO#<9o0O-#q$VvSBz2I} zq)D11b=N7H z4mIVDZ75T8LKl7m&<#PUz%*k(2$mKVtJF|Zs^LJZ)AI(SsmxqnVX3SFt6K9lu+8Uh?>GdVT@dIFO2^nK=^RUQ3CNQMGD!-I zoyjl-mS@kh1$LDN>2m3kW>&MtQLc*fYRj} Container<'_, Message, StyleType> { language, color_gradient, unread_notifications, + sniffer.frozen, ); } @@ -60,10 +62,15 @@ pub fn header(sniffer: &Sniffer) -> Container<'_, Message, StyleType> { Container::new(Space::with_width(60)) }) .push(horizontal_space()) - .push(Container::new(Space::with_width(40))) + .push(Container::new(Space::with_width(80))) .push(Space::with_width(20)) .push(logo) .push(Space::with_width(20)) + .push(if is_running { + Container::new(get_button_freeze(font, language, sniffer.frozen, false)) + } else { + Container::new(Space::with_width(40)) + }) .push(if is_running { Container::new(get_button_minimize(font, language, false)) } else { @@ -161,9 +168,56 @@ pub fn get_button_minimize<'a>( .class(ButtonType::Thumbnail) .on_press(Message::ToggleThumbnail(false)); - Tooltip::new(content, Text::new(tooltip).font(font), Position::Right) - .gap(0) - .class(tooltip_style) + Tooltip::new( + content, + Text::new(tooltip).font(font), + Position::FollowCursor, + ) + .gap(0) + .class(tooltip_style) +} + +pub fn get_button_freeze<'a>( + font: Font, + language: Language, + frozen: bool, + thumbnail: bool, +) -> Tooltip<'a, Message, StyleType> { + let size = if thumbnail { 19 } else { 23 }; + let button_size = if thumbnail { 30 } else { 40 }; + let icon = if frozen { Icon::Resume } else { Icon::Pause }; + let tooltip = if thumbnail { + "" + } else if frozen { + resume_translation(language) + } else { + pause_translation(language) + }; + let tooltip_style = if thumbnail { + ContainerType::Standard + } else { + ContainerType::Tooltip + }; + + let content = button( + icon.to_text() + .size(size) + .align_x(Alignment::Center) + .align_y(Alignment::Center), + ) + .padding(0) + .height(button_size) + .width(button_size) + .class(ButtonType::Thumbnail) + .on_press(Message::Freeze); + + Tooltip::new( + content, + Text::new(tooltip).font(font), + Position::FollowCursor, + ) + .gap(0) + .class(tooltip_style) } fn thumbnail_header<'a>( @@ -172,14 +226,16 @@ fn thumbnail_header<'a>( language: Language, color_gradient: GradientType, unread_notifications: usize, + frozen: bool, ) -> Container<'a, Message, StyleType> { Container::new( Row::new() .align_y(Alignment::Center) .push(horizontal_space()) - .push(Space::with_width(80)) + .push(Space::with_width(110)) .push(Text::new(SNIFFNET_TITLECASE).font(font_headers)) .push(Space::with_width(10)) + .push(get_button_freeze(font, language, frozen, true)) .push(get_button_minimize(font, language, true)) .push(horizontal_space()) .push(if unread_notifications > 0 { diff --git a/src/gui/sniffer.rs b/src/gui/sniffer.rs index 62030b339..05c06a40d 100644 --- a/src/gui/sniffer.rs +++ b/src/gui/sniffer.rs @@ -121,6 +121,8 @@ pub struct Sniffer { pub id: Option, /// Host data for filter dropdowns (comboboxes) pub host_data_states: HostDataStates, + /// Flag reporting whether the live capture is frozen + pub frozen: bool, } impl Sniffer { @@ -160,6 +162,7 @@ impl Sniffer { thumbnail: false, id: None, host_data_states: HostDataStates::default(), + frozen: false, } } @@ -555,6 +558,9 @@ impl Sniffer { .remote_notifications .set_url(&url); } + Message::Freeze => { + self.frozen = !self.frozen; + } } Task::none() } diff --git a/src/gui/types/message.rs b/src/gui/types/message.rs index 200e9cb66..d9a8f9774 100644 --- a/src/gui/types/message.rs +++ b/src/gui/types/message.rs @@ -139,4 +139,6 @@ pub enum Message { ToggleRemoteNotifications, /// The remote notifications URL has been updated RemoteNotificationsUrl(String), + /// Pause or resume live capture + Freeze, } diff --git a/src/utils/types/icon.rs b/src/utils/types/icon.rs index 5208aa6a2..7ff3065ad 100644 --- a/src/utils/types/icon.rs +++ b/src/utils/types/icon.rs @@ -52,6 +52,8 @@ pub enum Icon { Update, Warning, Waves, + Pause, + Resume, } impl Icon { @@ -105,6 +107,8 @@ impl Icon { Icon::Update => '<', // Icon::Expand => 'p', // Icon::Collapse => 'q', + Icon::Pause => '-', + Icon::Resume => '+', } } From a63a5c09a23316860b146912a90ca6c9641251ae Mon Sep 17 00:00:00 2001 From: GyulyVGC Date: Thu, 23 Oct 2025 23:04:06 +0200 Subject: [PATCH 2/7] add keyboard shortcut to freeze live capture --- src/gui/sniffer.rs | 10 ++++++++++ src/gui/types/message.rs | 2 ++ 2 files changed, 12 insertions(+) diff --git a/src/gui/sniffer.rs b/src/gui/sniffer.rs index 05c06a40d..ecc340949 100644 --- a/src/gui/sniffer.rs +++ b/src/gui/sniffer.rs @@ -178,6 +178,7 @@ impl Sniffer { }) => match key.as_ref() { Key::Character("q") => Some(Message::QuitWrapper), Key::Character("t") => Some(Message::CtrlTPressed), + Key::Named(Named::Space) => Some(Message::CtrlSpacePressed), _ => None, }, _ => None, @@ -188,6 +189,7 @@ impl Sniffer { Modifiers::COMMAND => match key.as_ref() { Key::Character("q") => Some(Message::QuitWrapper), Key::Character("t") => Some(Message::CtrlTPressed), + Key::Named(Named::Space) => Some(Message::CtrlSpacePressed), Key::Character(",") => Some(Message::OpenLastSettings), Key::Named(Named::Backspace) => Some(Message::ResetButtonPressed), Key::Character("d") => Some(Message::CtrlDPressed), @@ -503,6 +505,14 @@ impl Sniffer { return Task::done(Message::ToggleThumbnail(false)); } } + Message::CtrlSpacePressed => { + if self.running_page.is_some() + && self.settings_page.is_none() + && self.modal.is_none() + { + return Task::done(Message::Freeze); + } + } Message::ScaleFactorShortcut(increase) => { let scale_factor = self.conf.settings.scale_factor; if !(scale_factor > 2.99 && increase || scale_factor < 0.31 && !increase) { diff --git a/src/gui/types/message.rs b/src/gui/types/message.rs index d9a8f9774..bee2beabe 100644 --- a/src/gui/types/message.rs +++ b/src/gui/types/message.rs @@ -121,6 +121,8 @@ pub enum Message { Drag, /// Ctrl+T keys have been pressed CtrlTPressed, + /// Ctrl+Space keys have been pressed + CtrlSpacePressed, /// Edit scale factor via keyboard shortcut ScaleFactorShortcut(bool), /// Set new release status From 85344cad45acbf5d2c897c3cbb8eed8a840e7172 Mon Sep 17 00:00:00 2001 From: GyulyVGC Date: Tue, 28 Oct 2025 00:44:46 +0100 Subject: [PATCH 3/7] pause/resume packet capture implementation --- src/gui/sniffer.rs | 13 ++++++++++++- src/networking/parse_packets.rs | 11 ++++++++++- src/networking/types/capture_context.rs | 2 +- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/gui/sniffer.rs b/src/gui/sniffer.rs index ecc340949..9f4a49c20 100644 --- a/src/gui/sniffer.rs +++ b/src/gui/sniffer.rs @@ -121,8 +121,10 @@ pub struct Sniffer { pub id: Option, /// Host data for filter dropdowns (comboboxes) pub host_data_states: HostDataStates, - /// Flag reporting whether the live capture is frozen + /// Flag reporting whether the packet capture is frozen pub frozen: bool, + /// Sender to freeze the packet capture + freeze_tx: Option>, } impl Sniffer { @@ -163,6 +165,7 @@ impl Sniffer { id: None, host_data_states: HostDataStates::default(), frozen: false, + freeze_tx: None, } } @@ -570,6 +573,9 @@ impl Sniffer { } Message::Freeze => { self.frozen = !self.frozen; + if let Some(tx) = &self.freeze_tx { + let _ = tx.send(()); + } } } Task::none() @@ -766,6 +772,7 @@ impl Sniffer { self.traffic_chart .change_capture_source(matches!(capture_source, CaptureSource::Device(_))); let (tx, rx) = async_channel::unbounded(); + let (freeze_tx, freeze_rx) = std::sync::mpsc::channel(); let _ = thread::Builder::new() .name("thread_parse_packets".to_string()) .spawn(move || { @@ -775,10 +782,12 @@ impl Sniffer { &mmdb_readers, capture_context, &tx, + &freeze_rx, ); }) .log_err(location!()); self.current_capture_rx.1 = Some(rx.clone()); + self.freeze_tx = Some(freeze_tx); return Task::run(rx, |backend_msg| match backend_msg { BackendTrafficMessage::TickRun(cap_id, msg, host_msg, no_more_packets) => { Message::TickRun(cap_id, msg, host_msg, no_more_packets) @@ -816,6 +825,8 @@ impl Sniffer { self.page_number = 1; self.thumbnail = false; self.host_data_states = HostDataStates::default(); + self.frozen = false; + self.freeze_tx = None; } fn set_device(&mut self, name: &str) { diff --git a/src/networking/parse_packets.rs b/src/networking/parse_packets.rs index f3236aebe..0c76311ca 100644 --- a/src/networking/parse_packets.rs +++ b/src/networking/parse_packets.rs @@ -40,6 +40,7 @@ pub fn parse_packets( mmdb_readers: &MmdbReaders, capture_context: CaptureContext, tx: &Sender, + freeze_rx: &std::sync::mpsc::Receiver<()>, ) { let my_link_type = capture_context.my_link_type(); let (cap, mut savefile) = capture_context.consume(); @@ -52,13 +53,21 @@ pub fn parse_packets( // instant of the first parsed packet plus multiples of 1 second (only used in live captures) let mut first_packet_ticks = None; - let (pcap_tx, pcap_rx) = std::sync::mpsc::sync_channel(10_000); + let (pcap_tx, pcap_rx) = std::sync::mpsc::sync_channel(0); let _ = thread::Builder::new() .name("thread_packet_stream".to_string()) .spawn(move || packet_stream(cap, &pcap_tx)) .log_err(location!()); loop { + // check if we need to freeze the parsing + if freeze_rx.try_recv().is_ok() { + // wait until unfreeze + let _ = freeze_rx.recv(); + // reset the first packet ticks + first_packet_ticks = Some(Instant::now()); + } + let (packet_res, cap_stats) = pcap_rx .recv_timeout(Duration::from_millis(150)) .unwrap_or((Err(pcap::Error::TimeoutExpired), None)); diff --git a/src/networking/types/capture_context.rs b/src/networking/types/capture_context.rs index b28d4d22a..f89620b70 100644 --- a/src/networking/types/capture_context.rs +++ b/src/networking/types/capture_context.rs @@ -128,7 +128,7 @@ impl CaptureType { CaptureSource::Device(device) => { let inactive = Capture::from_device(device.to_pcap_device())?; let cap = inactive - .promisc(true) + .promisc(false) .buffer_size(2_000_000) // 2MB buffer -> 10k packets of 200 bytes .snaplen(if pcap_out_path.is_some() { i32::from(u16::MAX) From 8afd77c94f98be2d3b9650ca2e6474cd1ec2d9f3 Mon Sep 17 00:00:00 2001 From: GyulyVGC Date: Thu, 30 Oct 2025 21:08:53 +0100 Subject: [PATCH 4/7] pause/resume packet captures by applying proper BPF programs --- src/gui/sniffer.rs | 4 ++- src/networking/parse_packets.rs | 37 ++++++++++++++++++------- src/networking/types/capture_context.rs | 16 +++++++++++ 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/src/gui/sniffer.rs b/src/gui/sniffer.rs index 9f4a49c20..2c2cdc733 100644 --- a/src/gui/sniffer.rs +++ b/src/gui/sniffer.rs @@ -773,6 +773,7 @@ impl Sniffer { .change_capture_source(matches!(capture_source, CaptureSource::Device(_))); let (tx, rx) = async_channel::unbounded(); let (freeze_tx, freeze_rx) = std::sync::mpsc::channel(); + let filters = self.conf.filters.clone(); let _ = thread::Builder::new() .name("thread_parse_packets".to_string()) .spawn(move || { @@ -781,8 +782,9 @@ impl Sniffer { capture_source, &mmdb_readers, capture_context, + filters, &tx, - &freeze_rx, + freeze_rx, ); }) .log_err(location!()); diff --git a/src/networking/parse_packets.rs b/src/networking/parse_packets.rs index 0c76311ca..369e03af6 100644 --- a/src/networking/parse_packets.rs +++ b/src/networking/parse_packets.rs @@ -1,5 +1,6 @@ //! Module containing functions executed by the thread in charge of parsing sniffed packets +use crate::gui::types::filters::Filters; use crate::location; use crate::mmdb::asn::get_asn; use crate::mmdb::country::get_country; @@ -29,6 +30,7 @@ use etherparse::{EtherType, LaxPacketHeaders}; use pcap::{Address, Packet, PacketHeader}; use std::collections::HashMap; use std::net::IpAddr; +use std::sync::mpsc::Receiver; use std::sync::{Arc, Mutex}; use std::thread; use std::time::{Duration, Instant}; @@ -39,8 +41,9 @@ pub fn parse_packets( mut cs: CaptureSource, mmdb_readers: &MmdbReaders, capture_context: CaptureContext, + filters: Filters, tx: &Sender, - freeze_rx: &std::sync::mpsc::Receiver<()>, + freeze_rx: Receiver<()>, ) { let my_link_type = capture_context.my_link_type(); let (cap, mut savefile) = capture_context.consume(); @@ -53,20 +56,22 @@ pub fn parse_packets( // instant of the first parsed packet plus multiples of 1 second (only used in live captures) let mut first_packet_ticks = None; - let (pcap_tx, pcap_rx) = std::sync::mpsc::sync_channel(0); + let (pcap_tx, pcap_rx) = std::sync::mpsc::sync_channel(10_000); let _ = thread::Builder::new() .name("thread_packet_stream".to_string()) - .spawn(move || packet_stream(cap, &pcap_tx)) + .spawn(move || packet_stream(cap, &pcap_tx, &freeze_rx, &filters)) .log_err(location!()); loop { - // check if we need to freeze the parsing - if freeze_rx.try_recv().is_ok() { - // wait until unfreeze - let _ = freeze_rx.recv(); - // reset the first packet ticks - first_packet_ticks = Some(Instant::now()); - } + // // check if we need to freeze the parsing + // if freeze_rx.try_recv().is_ok() { + // // wait until unfreeze + // let _ = freeze_rx.recv(); + // // discard old buffered packets + // + // // reset the first packet ticks + // first_packet_ticks = Some(Instant::now()); + // } let (packet_res, cap_stats) = pcap_rx .recv_timeout(Duration::from_millis(150)) @@ -495,8 +500,20 @@ fn maybe_send_tick_run_offline( fn packet_stream( mut cap: CaptureType, tx: &std::sync::mpsc::SyncSender<(Result, Option)>, + freeze_rx: &Receiver<()>, + filters: &Filters, ) { loop { + // check if we need to freeze the parsing + if freeze_rx.try_recv().is_ok() { + // pause the capture + cap.pause(); + // wait until unfreeze + let _ = freeze_rx.recv(); + // resume the capture + cap.resume(filters); + } + let packet_res = cap.next_packet(); let packet_owned = packet_res.map(|p| PacketOwned { header: *p.header, diff --git a/src/networking/types/capture_context.rs b/src/networking/types/capture_context.rs index f89620b70..12fc363c1 100644 --- a/src/networking/types/capture_context.rs +++ b/src/networking/types/capture_context.rs @@ -150,6 +150,22 @@ impl CaptureType { Self::Offline(cap) => cap.filter(bpf, true), } } + + pub fn pause(&mut self) { + if let Self::Live(cap) = self { + let _ = cap.filter("less 2", true).log_err(location!()); + } + } + + pub fn resume(&mut self, filters: &Filters) { + if let Self::Live(cap) = self { + if filters.is_some_filter_active() { + let _ = cap.filter(filters.bpf(), true).log_err(location!()); + } else if cap.filter("", true).log_err(location!()).is_err() { + let _ = cap.filter("greater 0", true).log_err(location!()); + } + } + } } #[derive(Clone)] From a20162d37c8885a88335966e3fb6fa4d117ef59e Mon Sep 17 00:00:00 2001 From: GyulyVGC Date: Fri, 31 Oct 2025 23:06:13 +0100 Subject: [PATCH 5/7] use a tokio broadcast channel to block both parsing packet routines --- src/gui/sniffer.rs | 7 ++++--- src/networking/parse_packets.rs | 26 +++++++++++++------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/gui/sniffer.rs b/src/gui/sniffer.rs index 2c2cdc733..9354b74b7 100644 --- a/src/gui/sniffer.rs +++ b/src/gui/sniffer.rs @@ -124,7 +124,7 @@ pub struct Sniffer { /// Flag reporting whether the packet capture is frozen pub frozen: bool, /// Sender to freeze the packet capture - freeze_tx: Option>, + freeze_tx: Option>, } impl Sniffer { @@ -772,7 +772,8 @@ impl Sniffer { self.traffic_chart .change_capture_source(matches!(capture_source, CaptureSource::Device(_))); let (tx, rx) = async_channel::unbounded(); - let (freeze_tx, freeze_rx) = std::sync::mpsc::channel(); + let (freeze_tx, freeze_rx) = tokio::sync::broadcast::channel(65535); + let freeze_rx2 = freeze_tx.subscribe(); let filters = self.conf.filters.clone(); let _ = thread::Builder::new() .name("thread_parse_packets".to_string()) @@ -784,7 +785,7 @@ impl Sniffer { capture_context, filters, &tx, - freeze_rx, + (freeze_rx, freeze_rx2), ); }) .log_err(location!()); diff --git a/src/networking/parse_packets.rs b/src/networking/parse_packets.rs index 369e03af6..4548d23b7 100644 --- a/src/networking/parse_packets.rs +++ b/src/networking/parse_packets.rs @@ -30,10 +30,10 @@ use etherparse::{EtherType, LaxPacketHeaders}; use pcap::{Address, Packet, PacketHeader}; use std::collections::HashMap; use std::net::IpAddr; -use std::sync::mpsc::Receiver; use std::sync::{Arc, Mutex}; use std::thread; use std::time::{Duration, Instant}; +use tokio::sync::broadcast::Receiver; /// The calling thread enters a loop in which it waits for network packets pub fn parse_packets( @@ -43,8 +43,10 @@ pub fn parse_packets( capture_context: CaptureContext, filters: Filters, tx: &Sender, - freeze_rx: Receiver<()>, + freeze_rxs: (Receiver<()>, Receiver<()>), ) { + let (mut freeze_rx, mut freeze_rx2) = freeze_rxs; + let my_link_type = capture_context.my_link_type(); let (cap, mut savefile) = capture_context.consume(); @@ -59,19 +61,17 @@ pub fn parse_packets( let (pcap_tx, pcap_rx) = std::sync::mpsc::sync_channel(10_000); let _ = thread::Builder::new() .name("thread_packet_stream".to_string()) - .spawn(move || packet_stream(cap, &pcap_tx, &freeze_rx, &filters)) + .spawn(move || packet_stream(cap, &pcap_tx, &mut freeze_rx2, &filters)) .log_err(location!()); loop { // // check if we need to freeze the parsing - // if freeze_rx.try_recv().is_ok() { - // // wait until unfreeze - // let _ = freeze_rx.recv(); - // // discard old buffered packets - // - // // reset the first packet ticks - // first_packet_ticks = Some(Instant::now()); - // } + if freeze_rx.try_recv().is_ok() { + // wait until unfreeze + let _ = freeze_rx.blocking_recv(); + // reset the first packet ticks + first_packet_ticks = Some(Instant::now()); + } let (packet_res, cap_stats) = pcap_rx .recv_timeout(Duration::from_millis(150)) @@ -500,7 +500,7 @@ fn maybe_send_tick_run_offline( fn packet_stream( mut cap: CaptureType, tx: &std::sync::mpsc::SyncSender<(Result, Option)>, - freeze_rx: &Receiver<()>, + freeze_rx: &mut Receiver<()>, filters: &Filters, ) { loop { @@ -509,7 +509,7 @@ fn packet_stream( // pause the capture cap.pause(); // wait until unfreeze - let _ = freeze_rx.recv(); + let _ = freeze_rx.blocking_recv(); // resume the capture cap.resume(filters); } From 5fd3ebc2e26c1094800f7830e2dba3427037ecdb Mon Sep 17 00:00:00 2001 From: GyulyVGC Date: Fri, 31 Oct 2025 23:14:45 +0100 Subject: [PATCH 6/7] update CHANGELOG --- CHANGELOG.md | 1 + src/networking/parse_packets.rs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b16a4e79..6f4806110 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ All Sniffnet releases with the relative changes are documented in this file. ## [UNRELEASED] - Send remote notifications via webhook ([#991](https://github.com/GyulyVGC/sniffnet/pull/991) — fixes [#841](https://github.com/GyulyVGC/sniffnet/issues/841)) +- Pause and resume packet captures ([#992](https://github.com/GyulyVGC/sniffnet/pull/992) — fixes [#551](https://github.com/GyulyVGC/sniffnet/issues/551)) - Added Czech translation 🇨🇿 ([#960](https://github.com/GyulyVGC/sniffnet/pull/960)) - Improve update checks using `semver` ([#891](https://github.com/GyulyVGC/sniffnet/pull/891)) - Build the app also for Windows ARM64 (fixes [#988](https://github.com/GyulyVGC/sniffnet/issues/988)) diff --git a/src/networking/parse_packets.rs b/src/networking/parse_packets.rs index 4548d23b7..03e5f257f 100644 --- a/src/networking/parse_packets.rs +++ b/src/networking/parse_packets.rs @@ -45,7 +45,7 @@ pub fn parse_packets( tx: &Sender, freeze_rxs: (Receiver<()>, Receiver<()>), ) { - let (mut freeze_rx, mut freeze_rx2) = freeze_rxs; + let (mut freeze_rx, mut freeze_rx_2) = freeze_rxs; let my_link_type = capture_context.my_link_type(); let (cap, mut savefile) = capture_context.consume(); @@ -61,7 +61,7 @@ pub fn parse_packets( let (pcap_tx, pcap_rx) = std::sync::mpsc::sync_channel(10_000); let _ = thread::Builder::new() .name("thread_packet_stream".to_string()) - .spawn(move || packet_stream(cap, &pcap_tx, &mut freeze_rx2, &filters)) + .spawn(move || packet_stream(cap, &pcap_tx, &mut freeze_rx_2, &filters)) .log_err(location!()); loop { From 5d2516469ebb4a77403a4a937330b1244f90f2f0 Mon Sep 17 00:00:00 2001 From: GyulyVGC Date: Sun, 2 Nov 2025 13:29:22 +0100 Subject: [PATCH 7/7] minor fixes --- src/gui/sniffer.rs | 2 +- src/networking/parse_packets.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/sniffer.rs b/src/gui/sniffer.rs index 9354b74b7..9e5fb67d3 100644 --- a/src/gui/sniffer.rs +++ b/src/gui/sniffer.rs @@ -772,7 +772,7 @@ impl Sniffer { self.traffic_chart .change_capture_source(matches!(capture_source, CaptureSource::Device(_))); let (tx, rx) = async_channel::unbounded(); - let (freeze_tx, freeze_rx) = tokio::sync::broadcast::channel(65535); + let (freeze_tx, freeze_rx) = tokio::sync::broadcast::channel(1_048_575); let freeze_rx2 = freeze_tx.subscribe(); let filters = self.conf.filters.clone(); let _ = thread::Builder::new() diff --git a/src/networking/parse_packets.rs b/src/networking/parse_packets.rs index 03e5f257f..8fb1e6407 100644 --- a/src/networking/parse_packets.rs +++ b/src/networking/parse_packets.rs @@ -65,7 +65,7 @@ pub fn parse_packets( .log_err(location!()); loop { - // // check if we need to freeze the parsing + // check if we need to freeze the parsing if freeze_rx.try_recv().is_ok() { // wait until unfreeze let _ = freeze_rx.blocking_recv();