From d2ff11df184bda4d300fc18d0311723a1ef96d9d Mon Sep 17 00:00:00 2001 From: "Alexander V. Nikolaev" Date: Wed, 11 Sep 2024 16:47:30 +0300 Subject: [PATCH] Refactor ListenerAddress::Vsock to not depend on tokio_vsock::VsockAddr Signed-off-by: Alexander V. Nikolaev --- Cargo.toml | 2 +- src/listener.rs | 7 ++++--- src/listener_address.rs | 25 +++++++++++++++++++------ 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4ce327e..465b983 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ tokio-util = {version = "0.7", optional=true, features=["net","codec"]} tokio-vsock = {version = "0.5", optional=true} [target.'cfg(unix)'.dependencies] -nix = { version = "0.26.2", default-features = false, features = ["user", "fs", "socket"], optional=true } +nix = { version = "0.26.2", default-features = false, features = ["user", "fs"], optional=true } [features] diff --git a/src/listener.rs b/src/listener.rs index ca7c7b5..dde9e3e 100644 --- a/src/listener.rs +++ b/src/listener.rs @@ -169,9 +169,10 @@ fn listen_abstract(a: &String, usr_opts: &UserOptions) -> Result Result { - use tokio_vsock::VsockListener; - let listener = VsockListener::bind(vs.to_owned())?; +fn listen_vsock((cid, port): &(u32, u32)) -> Result { + use tokio_vsock::{VsockAddr, VsockListener}; + let vs = VsockAddr::new(*cid, *port); + let listener = VsockListener::bind(vs)?; Ok(ListenerImpl::Vsock(ListenerImplVsock{ s: listener})) } diff --git a/src/listener_address.rs b/src/listener_address.rs index 33442bb..e664d28 100644 --- a/src/listener_address.rs +++ b/src/listener_address.rs @@ -1,8 +1,5 @@ use std::{fmt::Display, net::SocketAddr, path::PathBuf, str::FromStr}; -#[cfg(all(unix, feature = "vsock"))] -use tokio_vsock::VsockAddr; - /// Abstraction over socket address that instructs in which way and at what address (if any) [`Listener`] /// should listen for incoming stream connections. /// @@ -31,7 +28,7 @@ use tokio_vsock::VsockAddr; feature = "serde", derive(serde_with::DeserializeFromStr, serde_with::SerializeDisplay) )] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum ListenerAddress { /// Usual server TCP socket. Triggered by specifying IPv4 or IPv6 address and port pair. /// Example: `127.0.0.1:8080`. @@ -55,7 +52,8 @@ pub enum ListenerAddress { /// /// Special name `*` means to bind all passed addresses simultaneously, if `multi-listener` crate feature is enabled. FromFdNamed(String), - Vsock(VsockAddr), + /// Pair of CID and port + Vsock((u32, u32)), } pub(crate) const SD_LISTEN_FDS_START: i32 = 3; @@ -86,6 +84,12 @@ impl FromStr for ListenerAddress { return Err("Invalid tokio-listener sd-listen: name"); } Ok(ListenerAddress::FromFdNamed(x.to_owned())) + } else if let Some(vsock) = s.strip_prefix("vsock:") { + if let Some((Ok(cid), Ok(port))) = vsock.split_once(":").map(|(cid, port)| (cid.parse(), port.parse())) { + Ok(ListenerAddress::Vsock((cid, port))) + } else { + Err("Invalid tokio-listener vsock: cid:port pair expected") + } } else if let Ok(a) = s.parse() { Ok(ListenerAddress::Tcp(a)) } else { @@ -125,7 +129,9 @@ impl Display for ListenerAddress { ListenerAddress::FromFdNamed(name) => { write!(f, "sd-listen:{name}") } - ListenerAddress::Vsock(a) => a.fmt(f), + ListenerAddress::Vsock((cid, port)) => { + write!(f, "vsock:{cid}:{port}") + } } } } @@ -156,3 +162,10 @@ pub(crate) fn check_env_for_fd(fdnum: i32) -> Option<()> { Some(()) } + +#[cfg(all(unix, feature = "vsock"))] +impl std::convert::From for ListenerAddress { + fn from(vs: tokio_vsock::VsockAddr) -> Self { + ListenerAddress::Vsock((vs.cid(), vs.port())) + } +}