-
Notifications
You must be signed in to change notification settings - Fork 136
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
Implement opcode sendmsg (non-zc) for UdpStream. #263
Conversation
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.
Mostly looks good. There were no unit tests for the zc version so none expected for this one either.
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.
If you have time. Just one more nit. Sorry I didn't catch it a few minutes ago.
@Icelk You've been very responsive to my comments today. Once the existing tests pass, and I merge, will you be able to confirm this does what you want? As we don't have a unit test for any of the UDP sendmsg* methods, and I don't use them myself, it would help to know it works at least for one use case, before you and I loose the context of this PR. |
You too, thanks!
I will certainly test if they work, but I won't be using the headers in production for a while. |
I did some testing. I got I also had some trouble setting
|
Okay. Glad you tried it out. Just submit a fix for sendmsg. #260 exists for SendMsgZc. |
as_ref(). Do you have the same problem if you pass sendmsg.msghdr.as_ref() to opcode::SendMsg? |
@Icelk Have you had a chance to see if using |
Same for me. I used the example
That's the thing: the msg_control buffer is allocated, so this seems very odd. Here are my changes to the example. Notice that it works when you change the diff --git a/examples/udp_socket.rs b/examples/udp_socket.rs
index 01eb9b3..921cea6 100644
--- a/examples/udp_socket.rs
+++ b/examples/udp_socket.rs
@@ -11,16 +11,12 @@ fn main() {
let socket_addr: SocketAddr = args[1].parse().unwrap();
·
tokio_uring::start(async {
- let socket = UdpSocket::bind(socket_addr).await.unwrap();
+ let socket = UdpSocket::bind("[::0]:0".parse().unwrap()).await.unwrap();
·
let buf = vec![0u8; 128];
·
- let (result, mut buf) = socket.recv_from(buf).await;
- let (read, socket_addr) = result.unwrap();
- buf.resize(read, 0);
- println!("received from {}: {:?}", socket_addr, &buf[..]);
-
- let (result, _buf) = socket.send_to(buf, socket_addr).await;
- println!("sent to {}: {}", socket_addr, result.unwrap());
+ println!("size {}", unsafe {libc::CMSG_SPACE(core::mem::size_of::<libc::in_pktinfo>() as _)});
+ let (result, _buf, _hdr) = socket.sendmsg::<Vec<u8>, Vec<u8>>(vec![buf], Some(socket_addr), Some(vec![0u8;16])).await;
+ println!("sent to {}: {}, headers: {_hdr:?}", socket_addr, result.unwrap());
});
} |
@Icelk I'm reading about control data, often called ancillary data, and it could be its use is very limited and its meaning is very much dependent on the connection type. It seems it is not for sending extra data across the wire but for a way to send data to the kernel in the sendmsg case, and to receive from the kernel in the recvmsg case. Only for a Unix Domain socket, does it allow for sending a file descriptor from one process to another. I'm still looking for the definition of sending ancillary data for a UDP connection to the kernel, how does the kernel interrupt that? So maybe your sendmsg commit could have included an update to src/net/unix/stream.rs. Then a file descriptor could be sent from one process to another with this mechanism. |
That's also what I've read. I believe it's used by QUIC implementations to improve network congestion. As I mentioned here,
I think this would be a very niche use-case, and quite simple to implement on top of our implementation. |
Does |
I'm so sorry. You are correct. In this code, they set the control data. This files handles the encoding. It seems like it would be beneficial for us to expose the entire |
Thanks for pointing me to that. cmsg.rs is very interesting.
Just thinking about it with only a few minutes of understanding at this point. A new, additional, version of sendmsg (sendmsg_hdr?) could be provided but how special purpose would it have to be? It could be but I think we still want the ability to get smart pointer drops called if the future is dropped before So I don't this library could ask the caller to be responsible for the lifetimes of the three or four pieces of memory.
One rather straightforward way would be for the new function to take ownership of three Box values and either rebuild the msghdr from the three pieces, and a msg_flags parameter, or it takes four Box values. So requiring the caller to have boxed the data, but then pass ownership of the boxes to this API. Even building msg_iov has to be done carefully though because it also has pointers that need to be safe for the duration of the operation and should also have smart drop functions at the ready if the future is cancelled (as described above). Is having a new API essential to make this work for A big difference for Just trying to slip in |
Sorry for the very late response. Lately, I've implemented HTTP/3 and therefore use this code. I've opened another issue, #274. I now realize only the I've managed to make |
Fixes #261
Should I maybe try to reduce the code duplication in
src/io/sendmsg_zc.rs
andsrc/io/sendmsg.rs
?