about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock423
-rw-r--r--Cargo.toml1
-rw-r--r--src/count.rs67
-rw-r--r--src/main.rs138
4 files changed, 553 insertions, 76 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 41586eb..dc4f752 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3,14 +3,256 @@
 version = 4
 
 [[package]]
+name = "async-channel"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a"
+dependencies = [
+ "concurrent-queue",
+ "event-listener-strategy",
+ "futures-core",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "async-executor"
+version = "1.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb812ffb58524bdd10860d7d974e2f01cc0950c2438a74ee5ec2e2280c6c4ffa"
+dependencies = [
+ "async-task",
+ "concurrent-queue",
+ "fastrand",
+ "futures-lite",
+ "pin-project-lite",
+ "slab",
+]
+
+[[package]]
+name = "async-fs"
+version = "2.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a"
+dependencies = [
+ "async-lock",
+ "blocking",
+ "futures-lite",
+]
+
+[[package]]
+name = "async-io"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059"
+dependencies = [
+ "async-lock",
+ "cfg-if",
+ "concurrent-queue",
+ "futures-io",
+ "futures-lite",
+ "parking",
+ "polling",
+ "rustix",
+ "slab",
+ "tracing",
+ "windows-sys",
+]
+
+[[package]]
+name = "async-lock"
+version = "3.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18"
+dependencies = [
+ "event-listener",
+ "event-listener-strategy",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "async-net"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7"
+dependencies = [
+ "async-io",
+ "blocking",
+ "futures-lite",
+]
+
+[[package]]
+name = "async-process"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb"
+dependencies = [
+ "async-channel",
+ "async-io",
+ "async-lock",
+ "async-signal",
+ "async-task",
+ "blocking",
+ "cfg-if",
+ "event-listener",
+ "futures-lite",
+ "rustix",
+ "tracing",
+]
+
+[[package]]
+name = "async-signal"
+version = "0.2.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3"
+dependencies = [
+ "async-io",
+ "async-lock",
+ "atomic-waker",
+ "cfg-if",
+ "futures-core",
+ "futures-io",
+ "rustix",
+ "signal-hook-registry",
+ "slab",
+ "windows-sys",
+]
+
+[[package]]
+name = "async-task"
+version = "4.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"
+
+[[package]]
+name = "atomic-waker"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
+
+[[package]]
+name = "autocfg"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
+
+[[package]]
+name = "bitflags"
+version = "2.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
+
+[[package]]
+name = "blocking"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea"
+dependencies = [
+ "async-channel",
+ "async-task",
+ "futures-io",
+ "futures-lite",
+ "piper",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "concurrent-queue"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
+
+[[package]]
+name = "errno"
+version = "0.3.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18"
+dependencies = [
+ "libc",
+ "windows-sys",
+]
+
+[[package]]
+name = "event-listener"
+version = "5.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae"
+dependencies = [
+ "concurrent-queue",
+ "parking",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "event-listener-strategy"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
+dependencies = [
+ "event-listener",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "fastrand"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
+
+[[package]]
+name = "futures-core"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
+
+[[package]]
+name = "futures-io"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
+
+[[package]]
+name = "futures-lite"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532"
+dependencies = [
+ "fastrand",
+ "futures-core",
+ "futures-io",
+ "parking",
+ "pin-project-lite",
+]
+
+[[package]]
 name = "headlice"
 version = "0.1.0"
 dependencies = [
  "pnet_datalink",
  "scurvy",
+ "smol",
 ]
 
 [[package]]
+name = "hermit-abi"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
+
+[[package]]
 name = "ipnetwork"
 version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -26,12 +268,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
 
 [[package]]
+name = "linux-raw-sys"
+version = "0.4.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
+
+[[package]]
 name = "no-std-net"
 version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65"
 
 [[package]]
+name = "parking"
+version = "2.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
+
+[[package]]
+name = "piper"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066"
+dependencies = [
+ "atomic-waker",
+ "fastrand",
+ "futures-io",
+]
+
+[[package]]
 name = "pnet_base"
 version = "0.35.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -64,6 +335,21 @@ dependencies = [
 ]
 
 [[package]]
+name = "polling"
+version = "3.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f"
+dependencies = [
+ "cfg-if",
+ "concurrent-queue",
+ "hermit-abi",
+ "pin-project-lite",
+ "rustix",
+ "tracing",
+ "windows-sys",
+]
+
+[[package]]
 name = "proc-macro2"
 version = "1.0.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -82,6 +368,19 @@ dependencies = [
 ]
 
 [[package]]
+name = "rustix"
+version = "0.38.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
+dependencies = [
+ "bitflags",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys",
+]
+
+[[package]]
 name = "scurvy"
 version = "0.1.0"
 source = "git+https://git.dreamy.place/scurvy/#c97099648a2117d44b3bc8bef033afde66c2339a"
@@ -107,6 +406,41 @@ dependencies = [
 ]
 
 [[package]]
+name = "signal-hook-registry"
+version = "1.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "slab"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "smol"
+version = "2.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a33bd3e260892199c3ccfc487c88b2da2265080acb316cd920da72fdfd7c599f"
+dependencies = [
+ "async-channel",
+ "async-executor",
+ "async-fs",
+ "async-io",
+ "async-lock",
+ "async-net",
+ "async-process",
+ "blocking",
+ "futures-lite",
+]
+
+[[package]]
 name = "syn"
 version = "2.0.101"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -118,6 +452,22 @@ dependencies = [
 ]
 
 [[package]]
+name = "tracing"
+version = "0.1.41"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
+dependencies = [
+ "pin-project-lite",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
+
+[[package]]
 name = "unicode-ident"
 version = "1.0.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -144,3 +494,76 @@ name = "winapi-x86_64-pc-windows-gnu"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows-sys"
+version = "0.59.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
diff --git a/Cargo.toml b/Cargo.toml
index 51b8fe6..43a9b92 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,3 +6,4 @@ edition = "2024"
 [dependencies]
 pnet_datalink = "0.35.0"
 scurvy = { git = "https://git.dreamy.place/scurvy/" }
+smol = "2.0.2"
diff --git a/src/count.rs b/src/count.rs
new file mode 100644
index 0000000..c3d92bf
--- /dev/null
+++ b/src/count.rs
@@ -0,0 +1,67 @@
+const U16_MAX: usize = u16::MAX as usize;
+
+pub struct Count {
+	tcp_tx: Box<[usize]>,
+	tcp_rx: Box<[usize]>,
+	udp_tx: Box<[usize]>,
+	udp_rx: Box<[usize]>,
+}
+
+impl Count {
+	pub fn new() -> Self {
+		Self {
+			tcp_tx: Box::new([0; U16_MAX]),
+			tcp_rx: Box::new([0; U16_MAX]),
+			udp_tx: Box::new([0; U16_MAX]),
+			udp_rx: Box::new([0; U16_MAX]),
+		}
+	}
+
+	pub fn push_tcp(&mut self, tx_flag: bool, src: u16, dst: u16, len: usize) {
+		// The unsafe code here is bad and not good. As far as I am aware, this
+		// is safe except for allowing race conditions.
+		if tx_flag {
+			let bad_mut = unsafe { &mut *(self.tcp_tx.as_ptr() as *mut [usize; U16_MAX]) };
+			bad_mut[src as usize] += len;
+		} else {
+			let bad_mut = unsafe { &mut *(self.tcp_rx.as_ptr() as *mut [usize; U16_MAX]) };
+			bad_mut[dst as usize] += len;
+		}
+	}
+
+	pub fn push_udp(&mut self, tx_flag: bool, src: u16, dst: u16, len: usize) {
+		// The unsafe code here is bad and not good. As far as I am aware, this
+		// is safe except for allowing race conditions.
+		if tx_flag {
+			let bad_mut = unsafe { &mut *(self.udp_tx.as_ptr() as *mut [usize; U16_MAX]) };
+			bad_mut[src as usize] += len;
+		} else {
+			let bad_mut = unsafe { &mut *(self.udp_rx.as_ptr() as *mut [usize; U16_MAX]) };
+			bad_mut[dst as usize] += len;
+		}
+	}
+
+	pub fn tcp_tx(&self, port: u16) -> usize {
+		self.tcp_tx[port as usize]
+	}
+
+	pub fn tcp_rx(&self, port: u16) -> usize {
+		self.tcp_rx[port as usize]
+	}
+
+	pub fn udp_tx(&self, port: u16) -> usize {
+		self.udp_tx[port as usize]
+	}
+
+	pub fn udp_rx(&self, port: u16) -> usize {
+		self.udp_rx[port as usize]
+	}
+
+	pub fn many_tcp_tx(&self, ports: &[u16]) -> usize {
+		ports.iter().fold(0, |acc, port| acc + self.tcp_tx[*port as usize])
+	}
+
+	pub fn many_tcp_rx(&self, ports: &[u16]) -> usize {
+		ports.iter().fold(0, |acc, port| acc + self.tcp_rx[*port as usize])
+	}
+}
diff --git a/src/main.rs b/src/main.rs
index defd70b..3b0f63c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,17 +1,19 @@
-use std::{
-	error::Error,
-	net::{Ipv4Addr, Shutdown},
-	sync::mpsc::{self, Receiver, Sender, channel},
-	thread::JoinHandle,
-	time::{Duration, Instant},
-};
+use std::{cell::UnsafeCell, error::Error, net::Ipv4Addr, rc::Rc, thread::JoinHandle};
 
+use count::Count;
 use ethertype::EtherType;
 use ippacket::{IpNextHeader, Ipv4Packet};
 use layer3::{Tcp, Udp};
 use pnet_datalink::{Channel, Config};
 use scurvy::{Argument, Scurvy};
+use smol::{
+	LocalExecutor,
+	channel::{self, Receiver, Sender},
+	io::AsyncWriteExt,
+	net::TcpListener,
+};
 
+mod count;
 mod ethertype;
 mod ippacket;
 mod layer3;
@@ -41,12 +43,6 @@ fn main() -> Result<(), Box<dyn Error>> {
 
 	let stat = stat_thread();
 
-	let tx_clone = stat.tx.clone();
-	std::thread::spawn(move || {
-		std::thread::sleep(Duration::from_secs(30));
-		tx_clone.send(Meow::Show).unwrap();
-	});
-
 	loop {
 		let pkt = channel.next()?;
 
@@ -58,6 +54,14 @@ fn main() -> Result<(), Box<dyn Error>> {
 				let ip = Ipv4Packet::new(eth_payload);
 				let ip_payload = ip.get_payload();
 
+				let ip_tx = if ip.src == ip_want {
+					true
+				} else if ip.dst == ip_want {
+					false
+				} else {
+					continue;
+				};
+
 				// 6 byte per MAC (x2), 2 byte ethertype, 2 byte crc
 				let total_l2_len = ip.get_packet_len() + 18;
 
@@ -65,16 +69,8 @@ fn main() -> Result<(), Box<dyn Error>> {
 					IpNextHeader::Tcp => {
 						let tcp = Tcp::new(ip_payload);
 
-						let tcp_tx = if ip.src == ip_want {
-							true
-						} else if ip.dst == ip_want {
-							false
-						} else {
-							continue;
-						};
-
-						stat.tx.send(Meow::Tcp {
-							tx: tcp_tx,
+						stat.tx.send_blocking(Meow::Tcp {
+							tx: ip_tx,
 							src: tcp.source_port(),
 							dst: tcp.destination_port(),
 							len: total_l2_len,
@@ -83,16 +79,8 @@ fn main() -> Result<(), Box<dyn Error>> {
 					IpNextHeader::Udp => {
 						let udp = Udp::new(ip_payload);
 
-						let udp_tx = if ip.src == ip_want {
-							true
-						} else if ip.dst == ip_want {
-							false
-						} else {
-							continue;
-						};
-
-						stat.tx.send(Meow::Udp {
-							tx: udp_tx,
+						stat.tx.send_blocking(Meow::Udp {
+							tx: ip_tx,
 							src: udp.source_port(),
 							dst: udp.destination_port(),
 							len: total_l2_len,
@@ -106,6 +94,7 @@ fn main() -> Result<(), Box<dyn Error>> {
 	}
 }
 
+#[allow(dead_code)]
 struct StatHandle {
 	hwnd: JoinHandle<()>,
 	tx: Sender<Meow>,
@@ -124,12 +113,10 @@ enum Meow {
 		dst: u16,
 		len: usize,
 	},
-	Show,
-	Shutdown,
 }
 
 fn stat_thread() -> StatHandle {
-	let (tx, rx) = channel();
+	let (tx, rx) = channel::unbounded();
 
 	let hwnd = std::thread::spawn(|| stat(rx));
 
@@ -137,50 +124,49 @@ fn stat_thread() -> StatHandle {
 }
 
 fn stat(rx: Receiver<Meow>) {
-	let mut tcp_tx = vec![0; u16::MAX as usize];
-	let mut tcp_rx = vec![0; u16::MAX as usize];
-
-	let mut last_print = Instant::now();
-	loop {
-		if last_print.elapsed() > Duration::from_secs(10) {
-			let http_s = tcp_rx[80] + tcp_rx[443];
-			let http_s_kb = http_s / 1000;
-
-			let http_s_tx = tcp_tx[80] + tcp_tx[443];
-			let http_s_tx_kb = http_s_tx / 1000;
+	let cat = Rc::new(UnsafeCell::new(Count::new()));
 
-			println!("HTTP(S) rx {}kB // tx {}kB", http_s_kb, http_s_tx_kb);
+	let ex = Rc::new(LocalExecutor::new());
 
-			last_print = Instant::now();
-		}
-
-		match rx.recv() {
-			Err(_e) => {
-				eprintln!("error receiving! breaking from loop");
-				break;
-			}
-			Ok(Meow::Show) => {
-				if last_print.elapsed() > Duration::from_secs(30) {
-					println!("Activated by Meow::Show");
+	ex.spawn(async {
+		loop {
+			match rx.recv().await {
+				Err(_e) => {
+					eprintln!("error receiving! breaking from loop");
+					break;
 				}
-			}
-			Ok(Meow::Shutdown) => {
-				eprintln!("got shutdown! breaking from loop");
-				break;
-			}
-			Ok(Meow::Tcp {
-				tx: tcp_tx_flag,
-				src,
-				dst,
-				len,
-			}) => {
-				if tcp_tx_flag {
-					tcp_tx[src as usize] += len;
-				} else {
-					tcp_rx[dst as usize] += len;
+				Ok(Meow::Tcp { tx, src, dst, len }) => {
+					unsafe { &mut *cat.get() }.push_tcp(tx, src, dst, len);
+				}
+				Ok(Meow::Udp { tx, src, dst, len }) => {
+					unsafe { &mut *cat.get() }.push_udp(tx, src, dst, len);
 				}
 			}
-			_ => (),
 		}
-	}
+	})
+	.detach();
+
+	let run_cat = Rc::clone(&cat);
+	let run_ex = Rc::clone(&ex);
+	let run = ex.run(async move {
+		let socket = TcpListener::bind("127.0.0.1:6666").await.unwrap();
+
+		loop {
+			let (mut stream, _caddr) = socket.accept().await.unwrap();
+			let per_spawn_cat = Rc::clone(&run_cat);
+
+			run_ex
+				.spawn(async move {
+					let cat = unsafe { &mut *per_spawn_cat.get() };
+					let http_tx = cat.many_tcp_tx(&[80, 443]);
+					let http_rx = cat.many_tcp_rx(&[80, 443]);
+
+					let str = format!("{http_tx}\n{http_rx}");
+					stream.write_all(str.as_bytes()).await.unwrap();
+				})
+				.detach();
+		}
+	});
+
+	smol::block_on(run);
 }