diff --git a/ethtool/Cargo.toml b/ethtool/Cargo.toml index b5b9fb00..f6a92ad5 100644 --- a/ethtool/Cargo.toml +++ b/ethtool/Cargo.toml @@ -30,7 +30,7 @@ netlink-packet-core = "0.3.0" netlink-packet-generic = "0.2.0" netlink-packet-utils = "0.4.1" netlink-proto = { default-features = false, version = "0.8.0" } -netlink-sys = "0.7.0" +netlink-sys = "0.8.0" thiserror = "1.0.29" tokio = { version = "1.0.1", features = ["rt"], optional = true} diff --git a/netlink-packet-generic/Cargo.toml b/netlink-packet-generic/Cargo.toml index 39af2717..bfbbce79 100644 --- a/netlink-packet-generic/Cargo.toml +++ b/netlink-packet-generic/Cargo.toml @@ -18,4 +18,4 @@ netlink-packet-core = "0.3" netlink-packet-utils = "0.4" [dev-dependencies] -netlink-sys = { path = "../netlink-sys", version = "0.7" } +netlink-sys = { path = "../netlink-sys", version = "0.8" } diff --git a/netlink-packet-generic/tests/query_family_id.rs b/netlink-packet-generic/tests/query_family_id.rs index a74eadf4..da639eae 100644 --- a/netlink-packet-generic/tests/query_family_id.rs +++ b/netlink-packet-generic/tests/query_family_id.rs @@ -26,8 +26,7 @@ fn query_family_id() { socket.send(&txbuf, 0).unwrap(); - let mut rxbuf = vec![0u8; 2048]; - socket.recv(&mut rxbuf, 0).unwrap(); + let (rxbuf, _addr) = socket.recv_from_full().unwrap(); let rx_packet = >>::deserialize(&rxbuf).unwrap(); if let NetlinkPayload::InnerMessage(genlmsg) = rx_packet.payload { diff --git a/netlink-packet-route/Cargo.toml b/netlink-packet-route/Cargo.toml index fa8e8ff7..d47c3020 100644 --- a/netlink-packet-route/Cargo.toml +++ b/netlink-packet-route/Cargo.toml @@ -26,7 +26,7 @@ name = "dump_links" criterion = "0.3.0" pcap-file = "1.1.1" lazy_static = "1.4.0" -netlink-sys = "0.7" +netlink-sys = "0.8" [[bench]] name = "link_message" diff --git a/netlink-packet-sock-diag/Cargo.toml b/netlink-packet-sock-diag/Cargo.toml index 0e06a448..dfd52347 100644 --- a/netlink-packet-sock-diag/Cargo.toml +++ b/netlink-packet-sock-diag/Cargo.toml @@ -22,4 +22,4 @@ smallvec = "1.4.2" [dev-dependencies] lazy_static = "1.4.0" -netlink-sys = "0.7" +netlink-sys = "0.8" diff --git a/netlink-proto/Cargo.toml b/netlink-proto/Cargo.toml index 74da076b..f8d4f3aa 100644 --- a/netlink-proto/Cargo.toml +++ b/netlink-proto/Cargo.toml @@ -17,7 +17,7 @@ log = "0.4.8" futures = "0.3" tokio = { version = "1.0", default-features = false, features = ["io-util"] } netlink-packet-core = "0.3" -netlink-sys = { default-features = false, version = "0.7" } +netlink-sys = { default-features = false, version = "0.8" } [features] default = ["tokio_socket"] diff --git a/netlink-proto/src/framed.rs b/netlink-proto/src/framed.rs index 3a779525..127de046 100644 --- a/netlink-proto/src/framed.rs +++ b/netlink-proto/src/framed.rs @@ -3,6 +3,7 @@ use std::{ fmt::Debug, io, marker::PhantomData, + mem::MaybeUninit, pin::Pin, slice, task::{Context, Poll}, @@ -63,7 +64,7 @@ where // memory during a recv so it's fine to turn &mut // [>] into &mut[u8] let bytes = reader.chunk_mut(); - let bytes = slice::from_raw_parts_mut(bytes.as_mut_ptr(), bytes.len()); + let bytes = slice::from_raw_parts_mut(bytes.as_mut_ptr() as *mut MaybeUninit, bytes.len()); match ready!(socket.poll_recv_from(cx, bytes)) { Ok((n, addr)) => { reader.advance_mut(n); diff --git a/netlink-sys/Cargo.toml b/netlink-sys/Cargo.toml index 579044eb..5ac31934 100644 --- a/netlink-sys/Cargo.toml +++ b/netlink-sys/Cargo.toml @@ -1,7 +1,7 @@ [package] authors = ["Corentin Henry "] name = "netlink-sys" -version = "0.7.0" +version = "0.8.0" # TODO: drop this comment - already bumped version for trait changes edition = "2018" homepage = "https://github.com/little-dude/netlink" diff --git a/netlink-sys/src/socket.rs b/netlink-sys/src/socket.rs index bdc53cbe..815ffd68 100644 --- a/netlink-sys/src/socket.rs +++ b/netlink-sys/src/socket.rs @@ -1,6 +1,6 @@ use std::{ io::{Error, Result}, - mem, + mem::{self, MaybeUninit}, os::unix::io::{AsRawFd, FromRawFd, RawFd}, }; @@ -224,7 +224,7 @@ impl Socket { /// In datagram oriented protocols, `recv` and `recvfrom` receive normally only ONE datagram, but this seems not to /// be always true for netlink sockets: with some protocols like `NETLINK_AUDIT`, multiple netlink packets can be /// read with a single call. - pub fn recv_from(&self, buf: &mut [u8], flags: libc::c_int) -> Result<(usize, SocketAddr)> { + pub fn recv_from(&self, buf: &mut [MaybeUninit], flags: libc::c_int) -> Result<(usize, SocketAddr)> { // Create an empty storage for the address. Note that Rust standard library create a // sockaddr_storage so that it works for any address family, but here, we already know that // we'll have a Netlink address, so we can create the appropriate storage. @@ -273,7 +273,7 @@ impl Socket { /// For a connected socket, `recv` reads a datagram from the socket. The sender is the remote peer the socket is /// connected to (see [`Socket::connect`]). See also [`Socket::recv_from`] - pub fn recv(&self, buf: &mut [u8], flags: libc::c_int) -> Result { + pub fn recv(&self, buf: &mut [MaybeUninit], flags: libc::c_int) -> Result { let buf_ptr = buf.as_mut_ptr() as *mut libc::c_void; let buf_len = buf.len() as libc::size_t; @@ -288,14 +288,16 @@ impl Socket { /// buffer passed as argument, this method always reads a whole message, no matter its size. pub fn recv_from_full(&self) -> Result<(Vec, SocketAddr)> { // Peek - let mut buf = Vec::::new(); - let (rlen, _) = self.recv_from(&mut buf, libc::MSG_PEEK | libc::MSG_TRUNC)?; + let (peek_len, _) = self.recv_from(&mut [], libc::MSG_PEEK | libc::MSG_TRUNC)?; // Receive - let mut buf = vec![0; rlen as usize]; - let (_, addr) = self.recv_from(&mut buf, 0)?; - - Ok((buf, addr)) + let mut buf: Vec = Vec::with_capacity(peek_len); + unsafe { + let (rlen, addr) = self.recv_from(std::slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut MaybeUninit, peek_len), 0)?; + assert_eq!(rlen, peek_len); + buf.set_len(peek_len); + Ok((buf, addr)) + } } /// Send the given buffer `buf` to the remote peer with address `addr`. The supported flags are the `MSG_*` values diff --git a/netlink-sys/src/tokio.rs b/netlink-sys/src/tokio.rs index a83fe93d..ed508523 100644 --- a/netlink-sys/src/tokio.rs +++ b/netlink-sys/src/tokio.rs @@ -1,5 +1,6 @@ use std::{ io, + mem::MaybeUninit, os::unix::io::{AsRawFd, FromRawFd, RawFd}, task::{Context, Poll}, }; @@ -71,7 +72,7 @@ impl TokioSocket { } } - pub async fn recv(&mut self, buf: &mut [u8]) -> io::Result { + pub async fn recv(&mut self, buf: &mut [MaybeUninit]) -> io::Result { poll_fn(|cx| loop { // Check if the socket is readable. If not, // AsyncFd::poll_read_ready would have arranged for the @@ -87,7 +88,7 @@ impl TokioSocket { .await } - pub async fn recv_from(&mut self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { + pub async fn recv_from(&mut self, buf: &mut [MaybeUninit]) -> io::Result<(usize, SocketAddr)> { poll_fn(|cx| self.poll_recv_from(cx, buf)).await } @@ -98,7 +99,7 @@ impl TokioSocket { pub fn poll_recv_from( &mut self, cx: &mut Context, - buf: &mut [u8], + buf: &mut [MaybeUninit], ) -> Poll> { loop { trace!("poll_recv_from called");