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

UnixStream / UnixDatagram requires API for sending packet with FDs #2975

Open
zonyitoo opened this issue Oct 16, 2020 · 17 comments
Open

UnixStream / UnixDatagram requires API for sending packet with FDs #2975

zonyitoo opened this issue Oct 16, 2020 · 17 comments
Labels
A-tokio Area: The main tokio crate C-feature-accepted Category: A feature request that has been accepted pending implementation. C-feature-request Category: A feature request. E-help-wanted Call for participation: Help is requested to fix this issue. M-net Module: tokio/net

Comments

@zonyitoo
Copy link
Contributor

zonyitoo commented Oct 16, 2020

Is your feature request related to a problem? Please describe.

Since v0.3 PollEvented is in public APIs, I couldn't make one by myself.

Describe the solution you'd like

An additional function on UnixStream / UnixSocket, such as send_with_fds that calls libc::sendmsg and recv_with_fds calls libc::recvmsg internally.

Describe alternatives you've considered

  • A way that could let developers to make customized IO objects.
  • AsyncFd? PollEvented?
@zonyitoo zonyitoo added A-tokio Area: The main tokio crate C-feature-request Category: A feature request. labels Oct 16, 2020
@Darksonn
Copy link
Contributor

Would #2903 solve your issue?

@Darksonn Darksonn added the M-net Module: tokio/net label Oct 16, 2020
@zonyitoo
Copy link
Contributor Author

Yes, it will. But that would require me to rewrite the whole UdpSocket.

@Darksonn
Copy link
Contributor

Are the functions in question available in mio? If not, open an issue there.

@zonyitoo
Copy link
Contributor Author

Nope. Ok.

@de-vri-es
Copy link
Contributor

Interesting point: the standard library has an open PR rust-lang/rust/pull/69864 for adding this functionality. I copied the functionality to the tokio-seqpacket crate, but I don't believe it's possible to update tokio-seqpacket crate to tokio 0.3.0 until #2903 is merged.

It would make sense to stay close to the API that will be in the standard library. The initial PR does not allow external libraries to use the exact same mechanism since some important parts are not public. But the author was supportive of making that possible in a follow-up PR, so on the long term a large chunk of this could be done by std itself :)

@rgcottrell
Copy link

I've been struggling with a way to send an fd as well. My original thought was just to use as_raw_fd to get the underlying socket and call sendmsg on that, but that usually resulted in an EBADF error.

My current workaround, which seems to be doing the trick, although I haven't tested it extensively yet:

  • Call dup on the raw socket
  • Let the UnixStream go out of scope to close the original connected socket.
  • Perform the sendmsg on the duplicate socket
  • Wrap the duplicate socket in a new UnixStream.

It would be great to have a built in way of sending the socket. But it also feels like it would make sense to be able to temporarily disassociate the UnixStream if we need to work with the underlying socket directly.

@sbosnick
Copy link

sbosnick commented Nov 5, 2020

I have implemented a crate to do this: fd-queue which I am currently trying to upgrade to tokio v0.3. The pre-release published version of the crate works with tokio v0.2.21. I did essentially have to rewrite the whole UdpStream and UdpListener to get the behaviour I wanted.

The upgrade to tokio v0.3 currently delayed a bit while I think up a workaround for #3068.

@carllerche
Copy link
Member

carllerche commented Nov 12, 2020

I"m generally fine adding new APIs to the socket types. Somebody should propose these.

We are also working to add fns to wait for readiness on all the socket types. This is tracked in #2968.

@carllerche carllerche added the E-help-wanted Call for participation: Help is requested to fix this issue. label Nov 12, 2020
@malaire
Copy link

malaire commented Dec 8, 2020

Interesting point: the standard library has an open PR rust-lang/rust/pull/69864 for adding this functionality. ...

That PR has been added to 1.50.0 milestone 6 days ago.

@Darksonn Darksonn added the C-feature-accepted Category: A feature request that has been accepted pending implementation. label Dec 10, 2020
@Darksonn
Copy link
Contributor

Darksonn commented Dec 10, 2020

What are the details of the API that std is stabilizing for this?

@malaire
Copy link

malaire commented Dec 10, 2020

I'm not familiar with Rust stabilization, but here are the related docs I've found:

@Darksonn
Copy link
Contributor

Once the methods have been fully stabilized in std, I find it very likely that we would accept a PR that adds methods to Tokio that mirror std's design.

@LinkTed
Copy link
Contributor

LinkTed commented Jul 24, 2021

@Darksonn I am the author of the PR, as soon as the API is the stabilized, I planned to implement it for mio/tokio. Here is the tracking issue for the stabilization. There is two PR open 86432 and 82858 (by me). After the two PRs are merged, I would create one more PR to fix one alignment bug, and then I hope that it would be stabilized (wish me luck 😄).

@Darksonn
Copy link
Contributor

It's worth mentioning that the new try_io methods would make it possible to implement this externally without going through AsyncFd.

@frehberg
Copy link

frehberg commented Feb 16, 2023

I would like to implement a version of UdpSocket based on socket2::Socket, as I want to use the method socket2::Socket::send_to_vectored()

The following declaration fails, as PollEvened and IoSource are not exported by crates tokio and mio

mod udp2 {
   pub struct UdpSocket {
        io: tokio::io::PollEvented<mio::IoSource<socket2::Socket>>,
    }
}

I need this declaration to be able to implement the following

impl UdpSocket {
...

    async fn send_to_addr_vectored(&self, bufs: &[IoSlice<'_>], target: SocketAddr) -> io::Result<usize> {
        self.io
            .registration()
            .async_io(Interest::WRITABLE, || self.io.send_to_vectored(bufs, &SockAddr::from(target)))
            .await
    }
...
}

AFAICS, if the following symbols would be exported tokio::PollEvented and mio:IoSource, the framework would be open for external IO entities.
What do you think?

Any comments are welcome.

@frehberg
Copy link

frehberg commented Feb 16, 2023

The native socket impl in rustlib is supporting Socket::sendmsg. So it would be possible to implement the functionality UdpSocket::send_to_vectored(), first provided in API of rustlib:std::net, then in mio and finally in tokio::net

To start with, I did a first pitch in rustlib. (WIP), implementing UdpSccket::send_to_vectored( iovec, dst)
Comments are welcome

rust-lang/rust#68617

@Darksonn
Copy link
Contributor

The PollEvented type is not going to become public. You can do what you want using the UdpSocket::try_io method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tokio Area: The main tokio crate C-feature-accepted Category: A feature request that has been accepted pending implementation. C-feature-request Category: A feature request. E-help-wanted Call for participation: Help is requested to fix this issue. M-net Module: tokio/net
Projects
None yet
Development

No branches or pull requests

9 participants