From 5838b0b9eed8b4b35c75e5056d79e1f7c20bdab0 Mon Sep 17 00:00:00 2001 From: Nils Andreas Svee Date: Sat, 21 Feb 2026 18:44:43 +0700 Subject: [PATCH] refactor: replace bincode with zerocopy Replaces bincode with zerocopy for deserialization of network data, improving performance and reducing dependencies. --- Cargo.lock | 55 ++++++++++++++++++++------------------------------ Cargo.toml | 5 +++-- src/netlink.rs | 17 +++++++--------- 3 files changed, 32 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 057e2f8..7d468c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -37,26 +37,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "bincode" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740" -dependencies = [ - "bincode_derive", - "serde", - "unty", -] - -[[package]] -name = "bincode_derive" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf95709a440f45e986983918d0e8a1f30a9b1df04918fc828670606804ac3c09" -dependencies = [ - "virtue", -] - [[package]] name = "bindgen" version = "0.58.1" @@ -786,7 +766,6 @@ name = "sqm-autorate-rust" version = "0.2.0" dependencies = [ "anyhow", - "bincode", "icmp-socket", "log", "neli", @@ -795,6 +774,8 @@ dependencies = [ "rustix", "thiserror", "time", + "zerocopy", + "zerocopy-derive", ] [[package]] @@ -907,12 +888,6 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" -[[package]] -name = "unty" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" - [[package]] name = "vec_map" version = "0.8.2" @@ -925,12 +900,6 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "virtue" -version = "0.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "051eb1abcf10076295e815102942cc58f9d5e3b4560e46e53c21e8ff6f3af7b1" - [[package]] name = "wasip2" version = "1.0.2+wasi-0.2.9" @@ -1200,6 +1169,26 @@ dependencies = [ "wasmparser", ] +[[package]] +name = "zerocopy" +version = "0.8.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zmij" version = "1.0.21" diff --git a/Cargo.toml b/Cargo.toml index 1e23a1b..8ab3a58 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,13 +20,14 @@ strip = "symbols" [dependencies] anyhow = "1.0" -bincode = "2.0" icmp-socket = "0.4.0" neli = "0.7" rand = "0.10" rustix = { version = "1.1", features = ["fs", "thread", "time"] } rust-uci = { version = "0.1", optional = true } thiserror = "2.0" +zerocopy = "0.8.39" +zerocopy-derive = "0.8.39" [dependencies.log] features = ["std"] @@ -40,4 +41,4 @@ version = "0.3" uci = ["dep:rust-uci"] [patch.crates-io] -icmp-socket = { git = 'https://github.com/Lochnair/icmp-socket.git', tag = "v0.4.0"} \ No newline at end of file +icmp-socket = { git = 'https://github.com/Lochnair/icmp-socket.git', tag = "v0.4.0"} diff --git a/src/netlink.rs b/src/netlink.rs index 43e608c..22210bd 100644 --- a/src/netlink.rs +++ b/src/netlink.rs @@ -1,5 +1,3 @@ -use bincode::error::DecodeError; -use bincode::BorrowDecode; use neli::consts::nl::NlmF; use neli::consts::rtnl::{Arphrd, Iff, Ifla, RtAddrFamily, Rtm, Tca}; use neli::consts::socket::NlFamily; @@ -12,11 +10,13 @@ use neli::utils::Groups; use std::io; use std::str::Utf8Error; use thiserror::Error; +use zerocopy::FromBytes; +use zerocopy_derive::{FromBytes, Immutable, KnownLayout}; #[derive(Debug, Error)] pub enum NetlinkError { - #[error("Couldn't deserialize to struct")] - Deserialization(#[from] Box), + #[error("Couldn't deserialize to struct: {0}")] + Deserialization(String), #[error("Couldn't find intreface `{0}`")] InterfaceNotFound(String), @@ -52,7 +52,7 @@ pub struct Qdisc { parent: u32, } -#[derive(BorrowDecode, Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, FromBytes, Immutable, KnownLayout)] #[repr(C)] pub struct RtnlLinkStats64 { pub rx_packets: u64, @@ -172,11 +172,8 @@ impl Netlink { for attr in p.rtattrs().iter() { if attr.rta_type() == &Ifla::Stats64 { let buf = attr.rta_payload().as_ref(); - - let stats: RtnlLinkStats64 = - bincode::borrow_decode_from_slice(buf, bincode::config::standard()) - .map_err(|e| NetlinkError::Deserialization(Box::new(e)))? - .0; + let stats = RtnlLinkStats64::read_from_bytes(buf) + .map_err(|e| NetlinkError::Deserialization(e.to_string()))?; return Ok(stats); }