summaryrefslogtreecommitdiffstats
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs109
1 files changed, 65 insertions, 44 deletions
diff --git a/src/main.rs b/src/main.rs
index dbebc46..0d44a61 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -4,19 +4,19 @@ mod os;
#[cfg(test)]
mod tests;
-use display::display_loop;
+use display::Ui;
use network::{Connection, DnsQueue, Sniffer, Utilization};
-use ::std::net::IpAddr;
+use ::std::net:: IpAddr;
use ::pnet::datalink::{DataLinkReceiver, NetworkInterface};
use ::std::collections::HashMap;
use ::std::sync::atomic::{AtomicBool, Ordering};
use ::std::sync::{Arc, Mutex};
use ::std::{thread, time};
+use ::std::thread::park_timeout;
use ::termion::event::{Event, Key};
use ::tui::backend::Backend;
-use ::tui::Terminal;
use ::std::io;
use ::termion::raw::IntoRawMode;
@@ -37,7 +37,7 @@ fn main() {
"Sorry, no implementations for platforms other than linux yet :( - PRs welcome!"
);
- use os::{get_datalink_channel, get_interface, get_open_sockets, lookup_addr, KeyboardEvents};
+ use os::{get_datalink_channel, get_interface, get_open_sockets, lookup_addr, receive_winch, KeyboardEvents};
let opt = Opt::from_args();
let stdout = io::stdout().into_raw_mode().unwrap();
@@ -47,6 +47,7 @@ fn main() {
let network_interface = get_interface(&opt.interface).unwrap();
let network_frames = get_datalink_channel(&network_interface);
let lookup_addr = Box::new(lookup_addr);
+ let receive_winch = Box::new(receive_winch);
let os_input = OsInput {
network_interface,
@@ -54,6 +55,7 @@ fn main() {
get_open_sockets,
keyboard_events,
lookup_addr,
+ receive_winch,
};
start(terminal_backend, os_input)
@@ -65,33 +67,19 @@ pub struct OsInput {
pub get_open_sockets: fn() -> HashMap<Connection, String>,
pub keyboard_events: Box<Iterator<Item = Event> + Send + Sync + 'static>,
pub lookup_addr: Box<Fn(&IpAddr) -> Option<String> + Send + Sync + 'static>,
+ pub receive_winch: Box<Fn(&Arc<AtomicBool>)>,
}
pub fn start<B>(terminal_backend: B, os_input: OsInput)
where
- B: Backend + Send + 'static,
+ B: Backend + Send + Sync + 'static,
{
let running = Arc::new(AtomicBool::new(true));
let keyboard_events = os_input.keyboard_events; // TODO: as methods in os_interface
let get_open_sockets = os_input.get_open_sockets;
let lookup_addr = os_input.lookup_addr;
-
- let stdin_handler = thread::spawn({
- let running = running.clone();
- move || {
- for evt in keyboard_events {
- match evt {
- Event::Key(Key::Ctrl('c')) | Event::Key(Key::Char('q')) => {
- // TODO: exit faster
- running.store(false, Ordering::Relaxed);
- break;
- }
- _ => (),
- };
- }
- }
- });
+ let receive_winch = os_input.receive_winch;
let mut sniffer = Sniffer::new(os_input.network_interface, os_input.network_frames);
let network_utilization = Arc::new(Mutex::new(Utilization::new()));
@@ -111,43 +99,75 @@ where
}
});
+ let ui = Arc::new(Mutex::new(Ui::new(terminal_backend)));
+ let winch = Arc::new(AtomicBool::new(false));
+ receive_winch(&winch);
+
+ let resize_handler = thread::spawn({
+ let running = running.clone();
+ let winch = winch.clone();
+ let ui = ui.clone();
+ move || {
+ while running.load(Ordering::Acquire) {
+ while winch.load(Ordering::Acquire) {
+ let mut ui = ui.lock().unwrap();
+ ui.draw();
+ winch.store(false, Ordering::Release);
+ }
+ }
+ }
+ });
+
let display_handler = thread::spawn({
let running = running.clone();
let network_utilization = network_utilization.clone();
let ip_to_host = ip_to_host.clone();
let dns_queue = dns_queue.clone();
+ let ui = ui.clone();
move || {
- let mut terminal = Terminal::new(terminal_backend).unwrap();
- terminal.clear().unwrap();
- terminal.hide_cursor().unwrap();
- while running.load(Ordering::Relaxed) {
- {
- let connections_to_procs = get_open_sockets();
- let ip_to_host = ip_to_host.lock().unwrap();
- let unresolved_ips = connections_to_procs.keys().fold(vec![], |mut unresolved_ips, connection| {
- if !ip_to_host.contains_key(&connection.local_socket.ip) {
- unresolved_ips.push(connection.local_socket.ip.clone());
- }
- if !ip_to_host.contains_key(&connection.remote_socket.ip) {
- unresolved_ips.push(connection.remote_socket.ip.clone());
- }
- unresolved_ips
- });
+ while running.load(Ordering::Acquire) {
+ let connections_to_procs = get_open_sockets();
+ let ip_to_host = {
+ ip_to_host.lock().unwrap().clone()
+ };
+ let utilization = {
let mut network_utilization = network_utilization.lock().unwrap();
- let utilization = network_utilization.clone_and_reset();
- dns_queue.add_ips_to_resolve(unresolved_ips);
- display_loop(&utilization, &mut terminal, connections_to_procs, &ip_to_host);
+ network_utilization.clone_and_reset()
+ };
+ dns_queue.find_ips_to_resolve(&connections_to_procs, &ip_to_host);
+ {
+ let mut ui = ui.lock().unwrap();
+ ui.update_state(connections_to_procs, utilization, ip_to_host);
+ ui.draw();
}
- thread::sleep(time::Duration::from_secs(1));
+ park_timeout(time::Duration::from_secs(1));
}
- terminal.clear().unwrap();
- terminal.show_cursor().unwrap();
+ let mut ui = ui.lock().unwrap();
+ ui.end();
dns_queue.end();
}
});
+ let stdin_handler = thread::spawn({
+ let running = running.clone();
+ let display_handler = display_handler.thread().clone(); // TODO: better
+ move || {
+ for evt in keyboard_events {
+ match evt {
+ Event::Key(Key::Ctrl('c')) | Event::Key(Key::Char('q')) => {
+ running.store(false, Ordering::Release);
+ display_handler.unpark();
+ break;
+ }
+ _ => (),
+ };
+ }
+ }
+ });
+
+
let sniffing_handler = thread::spawn(move || {
- while running.load(Ordering::Relaxed) {
+ while running.load(Ordering::Acquire) {
if let Some(segment) = sniffer.next() {
network_utilization.lock().unwrap().update(&segment)
}
@@ -157,4 +177,5 @@ where
sniffing_handler.join().unwrap();
stdin_handler.join().unwrap();
dns_handler.join().unwrap();
+ resize_handler.join().unwrap();
}