Skip to content

Support for {recv,send}mmsg #493

Open
@Tuetuopay

Description

Hi,

When working with DGRAM sockets, the recvmmsg and sendmmsg syscalls are available to send multiple datagrams in a single syscall, potentially leading to increased performance (if the syscall rate is the bottleneck). I already have a draft available at https://github.com/Tuetuopay/socket2/tree/mmsg which is heavily inspired from the existing recvmsg/sendmsg implementation, because I wanted to test it out.

I'm opening the issue to discuss the API exposed, which is a bit simplified from the actual syscalls. The actual syscalls support scatter/gather buffers, just like sendmsg/recvmsg, and are exposed by socket2; this however does not to keep the API in control. My questions are:

  • is it worth to expose the scatter/gather buffers? (like the _vectored variants)
  • if so, how to do it without making overcomplicated function arguments? ("just expose MmsgHdr(Mut)" is a valid option as it is done)
  • should we both expose the full blown version and the simple version there is here? (like the _vectored variants)

I'm asking your opinion because the API is starting to look a lot like a full matrix of features with recv(_multiple)?_from(_vectored)?. Here is the added functions, with #[cfg] removed for brievty:

impl Socket {
    /// Receive multiple messages in a single call.
    pub fn recv_multiple_from(
        &self,
        msgs: &mut [MaybeUninitSlice<'_>],
        flags: c_int,
    ) -> io::Result<Vec<(usize, RecvFlags, SockAddr)>> {
        sys::recv_multiple_from(self.as_raw(), msgs, flags)
    }

    /// Receive multiple messages from a socket using a message structure.
    pub fn recvmmsg(
        &self,
        msgs: &mut MmsgHdrMut<'_, '_, '_>,
        flags: sys::c_int,
    ) -> io::Result<usize> {
        sys::recvmmsg(self.as_raw(), msgs, flags)
    }

    /// Send multiple data to multiple peers listening on `addrs`. Return the amount of bytes
    /// written for each message.
    pub fn send_multiple_to(
        &self,
        msgs: &[IoSlice<'_>],
        to: &[SockAddr],
        flags: c_int,
    ) -> io::Result<Vec<usize>> {
        sys::send_multiple_to(self.as_raw(), msgs, to, flags)
    }

    /// Send multiple messages on a socket using a multiple message structure.
    pub fn sendmmsg(&self, msgs: &MmsgHdr<'_, '_, '_>, flags: sys::c_int) -> io::Result<usize> {
        sys::sendmmsg(self.as_raw(), msgs, flags)
    }
}

Thank you for your time!

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions