Implement supervised rootless network readiness

This commit is contained in:
ms2k 2026-07-15 23:26:37 +09:00
commit ba6a075839

View file

@ -1,6 +1,12 @@
use std::os::fd::OwnedFd;
use std::io;
use std::os::fd::{AsFd, OwnedFd};
use rustix::net::{AddressFamily, SocketFlags, SocketType, socketpair};
use lazaret_core::codec::{decode, encode};
use rustix::net::{
AddressFamily, RecvFlags, SendFlags, SocketFlags, SocketType, recv, send, socketpair,
};
const MAX_PRIVATE_PACKET: usize = 64 * 1024;
/// # Errors
/// Returns an error when the private sequenced-packet pair cannot be created.
@ -26,6 +32,35 @@ pub fn private_stream_pair() -> std::io::Result<(OwnedFd, OwnedFd)> {
.map_err(Into::into)
}
/// # Errors
/// Returns an error when a typed private packet is oversized or cannot be sent atomically.
pub fn send_packet<T: serde::Serialize>(descriptor: impl AsFd, message: &T) -> io::Result<()> {
let encoded = encode(message).map_err(|error| io::Error::other(error.to_string()))?;
if encoded.is_empty() || encoded.len() > MAX_PRIVATE_PACKET {
return Err(io::Error::other("private packet has invalid size"));
}
let sent = send(descriptor.as_fd(), &encoded, SendFlags::empty())?;
if sent == encoded.len() {
Ok(())
} else {
Err(io::Error::other("private packet send was incomplete"))
}
}
/// # Errors
/// Returns an error when a private packet is empty, oversized, malformed, or unknown-version.
pub fn receive_packet<T>(descriptor: impl AsFd) -> io::Result<T>
where
T: serde::de::DeserializeOwned + serde::Serialize,
{
let mut encoded = vec![0_u8; MAX_PRIVATE_PACKET + 1];
let (_, received) = recv(descriptor.as_fd(), &mut encoded, RecvFlags::empty())?;
if received == 0 || received > MAX_PRIVATE_PACKET {
return Err(io::Error::other("private packet has invalid size"));
}
decode(&encoded[..received]).map_err(|error| io::Error::other(error.to_string()))
}
#[cfg(test)]
mod tests {
use std::os::fd::AsFd;