Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add support for sendmmsg(2) on linux #1171

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

colinmarc
Copy link

https://man7.org/linux/man-pages/man2/sendmmsg.2.html

Partially addresses #1156. I would've liked to add recvmmsg in the same PR, but it's actually much more complicated.

@colinmarc colinmarc force-pushed the sendmmsg branch 3 times, most recently from 10452dc to 779b2b7 Compare September 18, 2024 21:34
@colinmarc

This comment was marked as resolved.

@colinmarc colinmarc force-pushed the sendmmsg branch 2 times, most recently from e6b2394 to 6534026 Compare September 19, 2024 07:42
#[cfg(target_os = "linux")]
impl<'a> MMsgHdr<'a> {
/// Constructs a new message with no destination address.
pub fn new(iov: &[IoSlice<'a>], control: &mut SendAncillaryBuffer<'_, '_, '_>) -> Self {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you comment on why control needs to be a mut reference here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dumb answer is "because sendmsg requires a mut reference" (as does with_noaddr_msghdr and friends). I assumed some random API modified the cmsg on send, but I don't know which one.

tests/net/v4.rs Show resolved Hide resolved
src/net/send_recv/msg.rs Outdated Show resolved Hide resolved
src/net/send_recv/msg.rs Outdated Show resolved Hide resolved
@colinmarc
Copy link
Author

I think I addressed all your comments.

iov: &[IoSlice<'a>],
control: &mut SendAncillaryBuffer<'_, '_, '_>,
) -> Self {
with_v4_msghdr(addr, iov, control, Self::wrap)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this unsound? with_v4_msghdr allocates the V4 socket address on the stack and then passes that stack address in the msghdr in Self::wrap. So when we eventually call into the system call it is pointing to invalid stack memory.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right. Maybe SockAddrStorage can be used for this?

Copy link
Author

@colinmarc colinmarc Oct 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to avoid passing the length in here, we'll need to add a RawSockAddr type, I think, created with SockAddrV4::as_raw etc. It'll be slightly unergonomic, as the borrow checker won't let you do this:

MMsgHdr::new_with_addr(my_v4_addr.as_raw(), ...)

Since that would create a temporary value which is dropped. But it should work fine otherwise.

Then the signature becomes:

    pub fn new_with_addr(
        addr: &'a RawSockAddr,
        iov: &[IoSlice<'a>],
        control: &mut SendAncillaryBuffer<'_, '_, '_>,
    ) -> Self {
        // ...
    }

I think that helps with the recvmmsg(2) case, as well.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a RawSocketAddr type in my latest push (it's a separate commit, so can be reviewed independently).

src/net/send_recv/msg.rs Outdated Show resolved Hide resolved
@colinmarc colinmarc force-pushed the sendmmsg branch 3 times, most recently from afe3c24 to 695e084 Compare October 18, 2024 16:13
It wraps SockAddrStorage, but includes a length, for when a sockaddr has
to be stored for a longer lifetime.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants