Merge pull request #435 from imsnif/cleanup

Minor cleanup and optimisations
This commit is contained in:
cyqsimon
2024-10-09 12:55:22 +08:00
committed by GitHub
10 changed files with 50 additions and 43 deletions

View File

@@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
### Changed ### Changed
* Add build optimizations for release binary #434 - @pando85 * Add build optimizations for release binary #434 - @pando85
* Minor cleanup and optimisations #435 - @cyqsimon
## [0.23.1] - 2024-10-09 ## [0.23.1] - 2024-10-09

View File

@@ -99,12 +99,15 @@ impl Layout<'_> {
} }
} }
pub fn render(&self, frame: &mut Frame, rect: Rect, ui_offset: usize) { pub fn render(&self, frame: &mut Frame, rect: Rect, table_cycle_offset: usize) {
let (top, app, bottom) = top_app_and_bottom_split(rect); let (top, app, bottom) = top_app_and_bottom_split(rect);
let layout_slots = self.build_layout(app); let layout_slots = self.build_layout(app);
for i in 0..layout_slots.len() { for i in 0..layout_slots.len() {
if let Some(rect) = layout_slots.get(i) { if let Some(rect) = layout_slots.get(i) {
if let Some(child) = self.children.get((i + ui_offset) % self.children.len()) { if let Some(child) = self
.children
.get((i + table_cycle_offset) % self.children.len())
{
child.render(frame, *rect); child.render(frame, *rect);
} }
} }

View File

@@ -36,6 +36,7 @@ where
state.interface_name.clone_from(&opts.interface); state.interface_name.clone_from(&opts.interface);
state.unit_family = opts.render_opts.unit_family.into(); state.unit_family = opts.render_opts.unit_family.into();
state.cumulative_mode = opts.render_opts.total_utilization; state.cumulative_mode = opts.render_opts.total_utilization;
state.show_dns = opts.show_dns;
state state
}; };
Ui { Ui {
@@ -45,17 +46,17 @@ where
opts: opts.render_opts, opts: opts.render_opts,
} }
} }
pub fn output_text(&mut self, write_to_stdout: &mut (dyn FnMut(String) + Send)) { pub fn output_text(&mut self, write_to_stdout: &mut (dyn FnMut(&str) + Send)) {
let state = &self.state; let state = &self.state;
let ip_to_host = &self.ip_to_host; let ip_to_host = &self.ip_to_host;
let local_time: DateTime<Local> = Local::now(); let local_time: DateTime<Local> = Local::now();
let timestamp = local_time.timestamp(); let timestamp = local_time.timestamp();
let mut no_traffic = true; let mut no_traffic = true;
let output_process_data = |write_to_stdout: &mut (dyn FnMut(String) + Send), let output_process_data = |write_to_stdout: &mut (dyn FnMut(&str) + Send),
no_traffic: &mut bool| { no_traffic: &mut bool| {
for (proc_info, process_network_data) in &state.processes { for (proc_info, process_network_data) in &state.processes {
write_to_stdout(format!( write_to_stdout(&format!(
"process: <{timestamp}> \"{}\" up/down Bps: {}/{} connections: {}", "process: <{timestamp}> \"{}\" up/down Bps: {}/{} connections: {}",
proc_info.name, proc_info.name,
process_network_data.total_bytes_uploaded, process_network_data.total_bytes_uploaded,
@@ -67,9 +68,9 @@ where
}; };
let output_connections_data = let output_connections_data =
|write_to_stdout: &mut (dyn FnMut(String) + Send), no_traffic: &mut bool| { |write_to_stdout: &mut (dyn FnMut(&str) + Send), no_traffic: &mut bool| {
for (connection, connection_network_data) in &state.connections { for (connection, connection_network_data) in &state.connections {
write_to_stdout(format!( write_to_stdout(&format!(
"connection: <{timestamp}> {} up/down Bps: {}/{} process: \"{}\"", "connection: <{timestamp}> {} up/down Bps: {}/{} process: \"{}\"",
display_connection_string( display_connection_string(
connection, connection,
@@ -84,10 +85,10 @@ where
} }
}; };
let output_adressess_data = |write_to_stdout: &mut (dyn FnMut(String) + Send), let output_adressess_data = |write_to_stdout: &mut (dyn FnMut(&str) + Send),
no_traffic: &mut bool| { no_traffic: &mut bool| {
for (remote_address, remote_address_network_data) in &state.remote_addresses { for (remote_address, remote_address_network_data) in &state.remote_addresses {
write_to_stdout(format!( write_to_stdout(&format!(
"remote_address: <{timestamp}> {} up/down Bps: {}/{} connections: {}", "remote_address: <{timestamp}> {} up/down Bps: {}/{} connections: {}",
display_ip_or_host(*remote_address, ip_to_host), display_ip_or_host(*remote_address, ip_to_host),
remote_address_network_data.total_bytes_uploaded, remote_address_network_data.total_bytes_uploaded,
@@ -99,7 +100,7 @@ where
}; };
// header // header
write_to_stdout("Refreshing:".into()); write_to_stdout("Refreshing:");
// body1 // body1
if self.opts.processes { if self.opts.processes {
@@ -119,14 +120,14 @@ where
// body2: In case no traffic is detected // body2: In case no traffic is detected
if no_traffic { if no_traffic {
write_to_stdout("<NO TRAFFIC>".into()); write_to_stdout("<NO TRAFFIC>");
} }
// footer // footer
write_to_stdout("".into()); write_to_stdout("");
} }
pub fn draw(&mut self, paused: bool, show_dns: bool, elapsed_time: Duration, ui_offset: usize) { pub fn draw(&mut self, paused: bool, elapsed_time: Duration, table_cycle_offset: usize) {
let layout = Layout { let layout = Layout {
header: HeaderDetails { header: HeaderDetails {
state: &self.state, state: &self.state,
@@ -134,10 +135,13 @@ where
paused, paused,
}, },
children: self.get_tables_to_display(), children: self.get_tables_to_display(),
footer: HelpText { paused, show_dns }, footer: HelpText {
paused,
show_dns: self.state.show_dns,
},
}; };
self.terminal self.terminal
.draw(|frame| layout.render(frame, frame.area(), ui_offset)) .draw(|frame| layout.render(frame, frame.area(), table_cycle_offset))
.unwrap(); .unwrap();
} }

View File

@@ -88,6 +88,7 @@ pub struct UIState {
pub total_bytes_downloaded: u128, pub total_bytes_downloaded: u128,
pub total_bytes_uploaded: u128, pub total_bytes_uploaded: u128,
pub cumulative_mode: bool, pub cumulative_mode: bool,
pub show_dns: bool,
pub unit_family: BandwidthUnitFamily, pub unit_family: BandwidthUnitFamily,
pub utilization_data: VecDeque<UtilizationData>, pub utilization_data: VecDeque<UtilizationData>,
pub processes_map: HashMap<ProcessInfo, NetworkData>, pub processes_map: HashMap<ProcessInfo, NetworkData>,

View File

@@ -82,7 +82,7 @@ pub struct OsInputOutput {
pub get_open_sockets: fn() -> OpenSockets, pub get_open_sockets: fn() -> OpenSockets,
pub terminal_events: Box<dyn Iterator<Item = Event> + Send>, pub terminal_events: Box<dyn Iterator<Item = Event> + Send>,
pub dns_client: Option<dns::Client>, pub dns_client: Option<dns::Client>,
pub write_to_stdout: Box<dyn FnMut(String) + Send>, pub write_to_stdout: Box<dyn FnMut(&str) + Send>,
} }
pub fn start<B>(terminal_backend: B, os_input: OsInputOutput, opts: Opt) pub fn start<B>(terminal_backend: B, os_input: OsInputOutput, opts: Opt)
@@ -93,8 +93,7 @@ where
let paused = Arc::new(AtomicBool::new(false)); let paused = Arc::new(AtomicBool::new(false));
let last_start_time = Arc::new(RwLock::new(Instant::now())); let last_start_time = Arc::new(RwLock::new(Instant::now()));
let cumulative_time = Arc::new(RwLock::new(Duration::new(0, 0))); let cumulative_time = Arc::new(RwLock::new(Duration::new(0, 0)));
let ui_offset = Arc::new(AtomicUsize::new(0)); let table_cycle_offset = Arc::new(AtomicUsize::new(0));
let dns_shown = opts.show_dns;
let mut active_threads = vec![]; let mut active_threads = vec![];
@@ -113,7 +112,7 @@ where
.spawn({ .spawn({
let running = running.clone(); let running = running.clone();
let paused = paused.clone(); let paused = paused.clone();
let ui_offset = ui_offset.clone(); let table_cycle_offset = table_cycle_offset.clone();
let network_utilization = network_utilization.clone(); let network_utilization = network_utilization.clone();
let last_start_time = last_start_time.clone(); let last_start_time = last_start_time.clone();
@@ -123,7 +122,7 @@ where
move || { move || {
while running.load(Ordering::Acquire) { while running.load(Ordering::Acquire) {
let render_start_time = Instant::now(); let render_start_time = Instant::now();
let utilization = { network_utilization.lock().unwrap().clone_and_reset() }; let utilization = network_utilization.lock().unwrap().clone_and_reset();
let OpenSockets { sockets_to_procs } = get_open_sockets(); let OpenSockets { sockets_to_procs } = get_open_sockets();
let mut ip_to_host = IpTable::new(); let mut ip_to_host = IpTable::new();
if let Some(dns_client) = dns_client.as_mut() { if let Some(dns_client) = dns_client.as_mut() {
@@ -139,7 +138,7 @@ where
{ {
let mut ui = ui.lock().unwrap(); let mut ui = ui.lock().unwrap();
let paused = paused.load(Ordering::SeqCst); let paused = paused.load(Ordering::SeqCst);
let ui_offset = ui_offset.load(Ordering::SeqCst); let table_cycle_offset = table_cycle_offset.load(Ordering::SeqCst);
if !paused { if !paused {
ui.update_state(sockets_to_procs, utilization, ip_to_host); ui.update_state(sockets_to_procs, utilization, ip_to_host);
} }
@@ -152,7 +151,7 @@ where
if raw_mode { if raw_mode {
ui.output_text(&mut write_to_stdout); ui.output_text(&mut write_to_stdout);
} else { } else {
ui.draw(paused, dns_shown, elapsed_time, ui_offset); ui.draw(paused, elapsed_time, table_cycle_offset);
} }
} }
let render_duration = render_start_time.elapsed(); let render_duration = render_start_time.elapsed();
@@ -183,13 +182,12 @@ where
let paused = paused.load(Ordering::SeqCst); let paused = paused.load(Ordering::SeqCst);
ui.draw( ui.draw(
paused, paused,
dns_shown,
elapsed_time( elapsed_time(
*last_start_time.read().unwrap(), *last_start_time.read().unwrap(),
*cumulative_time.read().unwrap(), *cumulative_time.read().unwrap(),
paused, paused,
), ),
ui_offset.load(Ordering::SeqCst), table_cycle_offset.load(Ordering::SeqCst),
); );
} }
Event::Key(KeyEvent { Event::Key(KeyEvent {
@@ -250,9 +248,9 @@ where
paused, paused,
); );
let table_count = ui.get_table_count(); let table_count = ui.get_table_count();
let new = ui_offset.load(Ordering::SeqCst) + 1 % table_count; let new = table_cycle_offset.load(Ordering::SeqCst) + 1 % table_count;
ui_offset.store(new, Ordering::SeqCst); table_cycle_offset.store(new, Ordering::SeqCst);
ui.draw(paused, dns_shown, elapsed_time, new); ui.draw(paused, elapsed_time, new);
} }
_ => (), _ => (),
}; };
@@ -280,7 +278,7 @@ where
while running.load(Ordering::Acquire) { while running.load(Ordering::Acquire) {
if let Some(segment) = sniffer.next() { if let Some(segment) = sniffer.next() {
network_utilization.lock().unwrap().update(segment); network_utilization.lock().unwrap().ingest(segment);
} }
} }
}) })

View File

@@ -93,19 +93,19 @@ macro_rules! extract_transport_protocol {
pub struct Sniffer { pub struct Sniffer {
network_interface: NetworkInterface, network_interface: NetworkInterface,
network_frames: Box<dyn DataLinkReceiver>, network_frames: Box<dyn DataLinkReceiver>,
dns_shown: bool, show_dns: bool,
} }
impl Sniffer { impl Sniffer {
pub fn new( pub fn new(
network_interface: NetworkInterface, network_interface: NetworkInterface,
network_frames: Box<dyn DataLinkReceiver>, network_frames: Box<dyn DataLinkReceiver>,
dns_shown: bool, show_dns: bool,
) -> Self { ) -> Self {
Sniffer { Sniffer {
network_interface, network_interface,
network_frames, network_frames,
dns_shown, show_dns,
} }
} }
pub fn next(&mut self) -> Option<Segment> { pub fn next(&mut self) -> Option<Segment> {
@@ -138,7 +138,7 @@ impl Sniffer {
let version = ip_packet.get_version(); let version = ip_packet.get_version();
match version { match version {
4 => Self::handle_v4(ip_packet, &self.network_interface, self.dns_shown), 4 => Self::handle_v4(ip_packet, &self.network_interface, self.show_dns),
6 => Self::handle_v6( 6 => Self::handle_v6(
Ipv6Packet::new(&bytes[payload_offset..])?, Ipv6Packet::new(&bytes[payload_offset..])?,
&self.network_interface, &self.network_interface,
@@ -149,7 +149,7 @@ impl Sniffer {
EtherTypes::Ipv4 => Self::handle_v4( EtherTypes::Ipv4 => Self::handle_v4(
Ipv4Packet::new(pkg.payload())?, Ipv4Packet::new(pkg.payload())?,
&self.network_interface, &self.network_interface,
self.dns_shown, self.show_dns,
), ),
EtherTypes::Ipv6 => { EtherTypes::Ipv6 => {
Self::handle_v6(Ipv6Packet::new(pkg.payload())?, &self.network_interface) Self::handle_v6(Ipv6Packet::new(pkg.payload())?, &self.network_interface)

View File

@@ -24,7 +24,7 @@ impl Utilization {
self.connections.clear(); self.connections.clear();
clone clone
} }
pub fn update(&mut self, seg: Segment) { pub fn ingest(&mut self, seg: Segment) {
let total_bandwidth = self let total_bandwidth = self
.connections .connections
.entry(seg.connection) .entry(seg.connection)

View File

@@ -80,10 +80,10 @@ fn get_interface(interface_name: &str) -> Option<NetworkInterface> {
.find(|iface| iface.name == interface_name) .find(|iface| iface.name == interface_name)
} }
fn create_write_to_stdout() -> Box<dyn FnMut(String) + Send> { fn create_write_to_stdout() -> Box<dyn FnMut(&str) + Send> {
let mut stdout = io::stdout(); let mut stdout = io::stdout();
Box::new({ Box::new({
move |output: String| match writeln!(stdout, "{}", output) { move |output| match writeln!(stdout, "{}", output) {
Ok(_) => (), Ok(_) => (),
Err(e) if e.kind() == ErrorKind::BrokenPipe => { Err(e) if e.kind() == ErrorKind::BrokenPipe => {
// A process that was listening to bandwhich stdout has exited // A process that was listening to bandwhich stdout has exited

View File

@@ -257,14 +257,14 @@ pub fn os_input_output_factory(
) -> OsInputOutput { ) -> OsInputOutput {
let interfaces_with_frames = get_interfaces_with_frames(network_frames); let interfaces_with_frames = get_interfaces_with_frames(network_frames);
let write_to_stdout: Box<dyn FnMut(String) + Send> = match stdout { let write_to_stdout: Box<dyn FnMut(&str) + Send> = match stdout {
Some(stdout) => Box::new({ Some(stdout) => Box::new({
move |output: String| { move |output| {
let mut stdout = stdout.lock().unwrap(); let mut stdout = stdout.lock().unwrap();
writeln!(&mut stdout, "{}", output).unwrap(); writeln!(&mut stdout, "{}", output).unwrap();
} }
}), }),
None => Box::new(move |_output: String| {}), None => Box::new(|_output| {}),
}; };
OsInputOutput { OsInputOutput {

View File

@@ -657,7 +657,7 @@ fn traffic_with_host_names(network_frames: Vec<Box<dyn DataLinkReceiver>>) {
String::from("i-like-cheese.com"), String::from("i-like-cheese.com"),
); );
let dns_client = create_fake_dns_client(ips_to_hostnames); let dns_client = create_fake_dns_client(ips_to_hostnames);
let write_to_stdout = Box::new(move |_output: String| {}); let write_to_stdout = Box::new(|_output: &_| {});
let os_input = OsInputOutput { let os_input = OsInputOutput {
interfaces_with_frames, interfaces_with_frames,
@@ -696,7 +696,7 @@ fn truncate_long_hostnames(network_frames: Vec<Box<dyn DataLinkReceiver>>) {
String::from("i-like-cheese.com"), String::from("i-like-cheese.com"),
); );
let dns_client = create_fake_dns_client(ips_to_hostnames); let dns_client = create_fake_dns_client(ips_to_hostnames);
let write_to_stdout = Box::new(move |_output: String| {}); let write_to_stdout = Box::new(|_output: &_| {});
let os_input = OsInputOutput { let os_input = OsInputOutput {
interfaces_with_frames, interfaces_with_frames,
@@ -735,7 +735,7 @@ fn no_resolve_mode(network_frames: Vec<Box<dyn DataLinkReceiver>>) {
String::from("i-like-cheese.com"), String::from("i-like-cheese.com"),
); );
let dns_client = None; let dns_client = None;
let write_to_stdout = Box::new(move |_output: String| {}); let write_to_stdout = Box::new(|_output: &_| {});
let os_input = OsInputOutput { let os_input = OsInputOutput {
interfaces_with_frames, interfaces_with_frames,
@@ -768,7 +768,7 @@ fn traffic_with_winch_event() {
let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50);
let dns_client = create_fake_dns_client(HashMap::new()); let dns_client = create_fake_dns_client(HashMap::new());
let write_to_stdout = Box::new(move |_output: String| {}); let write_to_stdout = Box::new(|_output: &_| {});
let os_input = OsInputOutput { let os_input = OsInputOutput {
interfaces_with_frames, interfaces_with_frames,