wireshift-uring 0.1.1

Native Linux io_uring backend for wireshift
Documentation
//! Shared types used across the uring backend modules.

use std::ffi::CString;
use std::os::fd::RawFd;

use wireshift_core::op::OpDescriptor;

/// Data pinned in memory while an SQE is in-flight.
///
/// `io_uring` operations reference user memory via raw pointers in the SQE.
/// This enum owns that memory so the kernel never sees a dangling pointer.
pub(crate) enum InflightData {
    /// No additional pinned data needed.
    None,
    /// Pinned `CString` path for `OpenAt` / `Statx`.
    Path(CString),
    /// Pinned statx buffer + `CString` path for `Statx`.
    Statx {
        /// The path, kept alive for the kernel.
        path: CString,
        /// Heap-allocated statx result buffer.
        statx_buf: Box<libc::statx>,
    },
    /// Pinned iovec array for `Readv` / `Writev`.
    Iovec(Vec<libc::iovec>),
    /// Pinned sockaddr storage + length for `Connect`.
    Sockaddr {
        /// The raw socket fd created before submission.
        socket_fd: RawFd,
        /// The sockaddr storage, kept alive for the kernel.
        /// Not read by Rust  -  the kernel accesses it via raw pointer in the SQE.
        #[allow(dead_code)]
        storage: Box<libc::sockaddr_storage>,
        /// Actual length of the stored address.
        /// Not read by Rust  -  the kernel accesses it via raw pointer in the SQE.
        #[allow(dead_code)]
        addr_len: libc::socklen_t,
    },
    /// Data for linked child operations.
    Linked(Vec<InflightData>),
}

impl std::fmt::Debug for InflightData {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::None => write!(f, "None"),
            Self::Path(p) => write!(f, "Path({p:?})"),
            Self::Statx { path, .. } => write!(f, "Statx({path:?})"),
            Self::Iovec(v) => write!(f, "Iovec(len={})", v.len()),
            Self::Sockaddr { socket_fd, .. } => write!(f, "Sockaddr(fd={socket_fd})"),
            Self::Linked(items) => write!(f, "Linked(len={})", items.len()),
        }
    }
}

impl Drop for InflightData {
    fn drop(&mut self) {
        if let Self::Sockaddr { socket_fd, .. } = self {
            if *socket_fd >= 0 {
                // SAFETY: This socket was created in build_entry() and the operation
                // was aborted/canceled before creating a rust TcpStream to take ownership.
                unsafe {
                    libc::close(*socket_fd);
                }
            }
        }
    }
}

/// Tracks a single in-flight `io_uring` operation.
#[derive(Debug)]
pub(crate) struct Inflight {
    /// Unique operation id.
    pub id: u64,
    /// The operation descriptor.
    pub descriptor: OpDescriptor,
    /// Heap-pinned data that the kernel references via raw pointers in the SQE.
    pub pinned: InflightData,
    /// Number of CQEs expected for this operation.
    pub expected_cqes: usize,
    /// Collected result codes from completed CQEs.
    pub results: Vec<i32>,
}