Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Support for {recv,send}mmsg #493

Open
Tuetuopay opened this issue Feb 6, 2024 · 3 comments
Open

Support for {recv,send}mmsg #493

Tuetuopay opened this issue Feb 6, 2024 · 3 comments

Comments

@Tuetuopay
Copy link

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!

@Thomasdezeeuw
Copy link
Collaborator

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
Copy link
Author

For sure! I just opened it: #494

@MarkusPettersson98
Copy link

Hi, I just want to say that this would be amazing to have in socket2! I see that the PR isn't moving too fast, is there anything one can do to help land this feature? 😊

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants