-
Notifications
You must be signed in to change notification settings - Fork 166
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
base: main
Are you sure you want to change the base?
Conversation
10452dc
to
779b2b7
Compare
This comment was marked as resolved.
This comment was marked as resolved.
e6b2394
to
6534026
Compare
src/net/send_recv/msg.rs
Outdated
#[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 { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
I think I addressed all your comments. |
src/net/send_recv/msg.rs
Outdated
iov: &[IoSlice<'a>], | ||
control: &mut SendAncillaryBuffer<'_, '_, '_>, | ||
) -> Self { | ||
with_v4_msghdr(addr, iov, control, Self::wrap) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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).
afe3c24
to
695e084
Compare
It wraps SockAddrStorage, but includes a length, for when a sockaddr has to be stored for a longer lifetime.
https://man7.org/linux/man-pages/man2/sendmmsg.2.html Partially addresses bytecodealliance#1156. Signed-off-by: Colin Marc <[email protected]>
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.