tokio-vsock
Async Virtio vsock sockets for Rust, built on Tokio's TcpStream/TcpListener model
Repository Health
Technical Analysis
tokio-vsock provides asynchronous Virtio socket (vsock) support for Rust applications, exposing VsockStream and VsockListener types that mirror Tokio’s TcpStream and TcpListener APIs. Vsock is the communication channel used between a hypervisor host and a guest microVM (Firecracker, QEMU, crosvm) that doesn’t go over a network stack, so this crate is the standard building block for writing async agents, init processes, and container runtimes that need to talk across that host/guest boundary.
Beyond the raw stream/listener primitives, the crate ships optional integrations for tonic (implementing Connected across ten pinned tonic minor versions) and axum (a Listener impl for axum::serve), so teams building gRPC or HTTP control-plane services inside a microVM can swap a TCP listener for a vsock listener with minimal code changes.
What You Get
VsockStreamandVsockListenertypes implementingAsyncRead/AsyncWrite/Stream, modeled directly on Tokio’s TCP equivalents- Owned and borrowed split halves (
OwnedReadHalf/OwnedWriteHalf,ReadHalf/WriteHalf) for concurrent read/write usage - Optional
tonicsupport (Connectedtrait impl) gated behind ten separate feature flags covering tonic 0.5 through 0.14 - Optional
axum08feature implementingaxum::serve::Listenerso an Axum HTTP server can accept connections over vsock instead of TCP - Re-exported
VsockAddr,VMADDR_CID_ANY,VMADDR_CID_HOST,VMADDR_CID_HYPERVISOR, andVMADDR_CID_LOCALconstants from the underlyingvsockcrate
Common Use Cases
- Writing a guest agent inside a Firecracker or QEMU microVM that exchanges commands/metrics with the host over vsock instead of a virtual network interface
- Building a gRPC control-plane service (via
tonic) between a hypervisor and its microVMs without exposing a TCP port - Serving an HTTP API from inside a microVM over vsock using
axum’sListenertrait, avoiding network namespace/firewall setup entirely - Implementing container-runtime shims (e.g. Kata Containers-style agents) that need a byte-stream channel across the host/guest boundary
Under The Hood
Architecture — The crate is a thin async wrapper around the vsock crate’s blocking socket types. VsockStream::connect (src/stream.rs) does the raw socket()/fcntl()/connect() syscalls directly via libc, sets the fd non-blocking, and wraps it in tokio::io::unix::AsyncFd so Tokio’s reactor drives readiness; AsyncRead/AsyncWrite are implemented by polling that AsyncFd and calling into the underlying vsock::VsockStream’s Read/Write. VsockListener (src/listener.rs) follows the same pattern for accept(), implementing futures::Stream via Incoming for use in accept loops. split.rs provides zero-copy owned/borrowed split halves by wrapping an Arc-free raw-fd duplication, matching Tokio’s TCP split API shape. Optional tonic_support.rs and axum_support.rs modules bridge VsockStream/VsockListener into those frameworks’ connection-info and listener traits respectively, each gated behind its own Cargo feature. Tech Stack — Rust 2018 edition; core dependencies are tokio 1.50 (net + sync features), futures 0.3, libc 0.2, bytes 1.11, and the vsock crate (0.5) for the underlying blocking socket bindings; tonic/axum are optional, version-pinned per feature flag rather than a single semver range, which lets consumers on an older tonic keep compiling against this crate without a lockstep upgrade. Dev-dependencies (sha2, rand, tokio with macros/rt/io-util) back an integration-test suite that runs against a real QEMU VM built via the repo’s Makefile and test_fixture/ kernel/initramfs assets. Code Quality — tests/vsock.rs covers connect errors, a full read/write blob round-trip with SHA-256 verification, and split-stream behavior, but all of it requires a live QEMU VM (make vm) and is not runnable in a plain cargo test sandbox — there’s no mocked/unit-level test path for the socket logic itself. The code uses unsafe extensively for raw syscalls (socket/fcntl/connect/close) with consistent OS-error propagation via Error::last_os_error(), and platform-gates Linux/Android-only APIs (VMADDR_CID_LOCAL) with #[cfg]. Naming and structure closely mirror tokio::net::tcp so the crate is easy to audit against a codebase already familiar with Tokio’s TCP module. API Design — The public surface is intentionally small and TCP-shaped: VsockStream::connect/VsockListener::bind/accept read exactly like their tokio::net counterparts, which minimizes onboarding cost for anyone who has used Tokio’s networking before. Feature-flag fan-out for tonic (ten flags, one per minor version) is the one ergonomic wart — consumers must pick the exact flag matching their tonic version rather than a single unified integration, and that list will keep growing as tonic releases new minors.