-
Notifications
You must be signed in to change notification settings - Fork 178
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
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. |
695e084
to
e960980
Compare
Hi, anything needed from me on 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.
I think this looks good, just a few more review comments:
b5b2af2
to
9f7c847
Compare
Sorry for pinging and then disappearing - was really sick :) I rebased and addressed your comments. Please let me know how you'd like to resolve the overlap with #1004. It seems like I could use the updated |
Rebased on top of #1004 now that it's in main. The test failures look unrelated. This patch is a lot smaller now! |
|
||
/// Constructs a new message to a specific address. | ||
pub fn new_with_addr( | ||
addr: &'a SocketAddrAny, |
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.
I would like to take a &'a impl SockAddrArg
here, but it doesn't seem like the trait ensures that the pointer passed to the closure lives as long as the SockAddrArg
itself.
We could obviously immediately call as_any
, but that would just be making an explicit clone implicit.
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. Could you add a comment about this? Something like, "this doesn't use SocketAddrArg
because that creates a temporary SocketAddrAny
that only lives for the duration of the with_sockaddr
call, and we need a SocketAddrAny
that lives for 'a
".
Another possibility would be to add a with_socket_addr_any
function to SocketAddrArg
like this:
fn with_socket_addr_any<R>(&self, f: impl FnOnce(&SocketAddrAny) -> R) -> R {
let any = self.as_any();
f(&any)
}
Then users with a family-specific addr
could do
addr.with_socket_addr_any(|addr| {
sendmmsg(
&socket,
&mut [
MMsgHdr::new_with_addr(
&addr,
&[IoSlice::new(b"hello")],
&mut Default::default(),
),
],
SendFlags::empty(),
)
});
and then SocketAddrAny
's impl SocketAddrArg
could skip the as_any()
call:
fn with_socket_addr_any<R>(&self, f: impl FnOnce(&SocketAddrAny) -> R) -> R {
f(self)
}
That way users could avoid calling as_any
themselves. We could do that, though it's not that much of a simplification.
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.
I added a sentence to the docstring pointing users to as_any
- let me know what you think or if you think it needs more explication. I tried a few variants and in the end it felt like too much detail for end-users of the library, but maybe it would be useful as an "internal" comment.
let sent = sendmmsg( | ||
&data_socket, | ||
&mut [ | ||
MMsgHdr::new(&[IoSlice::new(b"hello")], &mut Default::default()), |
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.
Should this use new_wiith_addr
, like the v6 version does?
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.
I think my idea was to exercise both code paths. I changed it so that both tests exercise both.
|
||
/// Constructs a new message to a specific address. | ||
pub fn new_with_addr( | ||
addr: &'a SocketAddrAny, |
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. Could you add a comment about this? Something like, "this doesn't use SocketAddrArg
because that creates a temporary SocketAddrAny
that only lives for the duration of the with_sockaddr
call, and we need a SocketAddrAny
that lives for 'a
".
Another possibility would be to add a with_socket_addr_any
function to SocketAddrArg
like this:
fn with_socket_addr_any<R>(&self, f: impl FnOnce(&SocketAddrAny) -> R) -> R {
let any = self.as_any();
f(&any)
}
Then users with a family-specific addr
could do
addr.with_socket_addr_any(|addr| {
sendmmsg(
&socket,
&mut [
MMsgHdr::new_with_addr(
&addr,
&[IoSlice::new(b"hello")],
&mut Default::default(),
),
],
SendFlags::empty(),
)
});
and then SocketAddrAny
's impl SocketAddrArg
could skip the as_any()
call:
fn with_socket_addr_any<R>(&self, f: impl FnOnce(&SocketAddrAny) -> R) -> R {
f(self)
}
That way users could avoid calling as_any
themselves. We could do that, though it's not that much of a simplification.
The FreeBSD CI failure is fixed on main in #1322. |
https://man7.org/linux/man-pages/man2/sendmmsg.2.html Partially addresses bytecodealliance#1156. Signed-off-by: Colin Marc <[email protected]>
Thanks! |
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.