rust-lang / socket2

Advanced configuration options for sockets.
https://docs.rs/socket2
Apache License 2.0
677 stars 221 forks source link

Support for {recv,send}mmsg #493

Open Tuetuopay opened 8 months ago

Tuetuopay commented 8 months ago

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:

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!

Thomasdezeeuw commented 8 months ago

The addition of {recv,send}mmsg would certainly be accepted. I'm afraid currently don't have a lot of time to work on this, but if you can send a pr from the changes you made I can take look at it.

Tuetuopay commented 8 months ago

For sure! I just opened it: #494