Nursery nomination: unix_socket


#1

The unix_socket crate provides bindings for Unix domain sockets.

The UnixStream and UnixListener types provide an API for SOCK_STREAM type sockets that is basically equivalent to TcpStream and TcpListener. The UnixDatagram type provides an API for SOCK_DGRAM type sockets that is basically equivalent to UdpSocket. UnixDatagram actually goes a bit further than UdpSocket by providing support for connected sockets, but I believe that is supported on UdpSocket by the net2 crate.

I’d like the crate to eventually end up in libstd, where it will be somewhat unique in being the only large piece of platform specific functionality, as Unix sockets do not exist on Windows. It would end up in std::sys::unix, where I believe there has always been an intent to build out with larger features such as Unix socket support. The rough equivalent in Windows, named pipes would presumably end with platform specific support in libstd eventually as well.

The API is in a solid place, but there a few open questions:

  • Linux offers an “abstract namespace” as a nonportable extension. Where Unix sockets normally correspond to files in the filesystem, the abstract namespace contains arbitrary identifiers that have no relation to the filesystem.
    • At the C level, and abstract namespace is identified by a leading null byte, and this method is used in the crate as well. The various constructors take an AsRef<Path> argument which will be passed verbatim to the OS, so an abstract namespace socket can be created via e.g. UnixStream::connect("\0some name"). This is a bit weird, and may be a thing, like 0 duration socket timeouts, that the Rust wrapper should handle translation for.
    • Even though the abstract namespace is a Linux-only extension, the AddressKind enum contains an Abstract variant on all platforms even if such an address can never exist.
  • The SOCK_SEQPACKET socket type is a third variant that exists but is not currently supported.
  • The sendmsg and recvmsg functions can be used to perform more advanced tasks with Unix sockets, such as sending and receiving file descriptors, user credentials, or reading and writing from and to a series of buffers at once. An open PR adds support for these features, but it’s very unclear what the API should look like.

#2

I’d be totally down for moving this in to the nursery. Some thoughts on your open questions:

Linux offers an “abstract namespace” as a nonportable extension

I would personally lean towards thinking "\0some name" being OK, it’s linux-specific so I don’t mind it being a little weird. This could also go the route of generally using a IntoSocketAddr trait like std::net, however, to make it a little more ergonomic in the future.

I think the question about AddressKind may need to be addressed separately regardless in the sense of the conflicting name of SocketAddr and std::net::SocketAddr. It may be a little difficult to unify these two, but the naming there may be a bit odd and I’d think that it may be nice to perhaps touch up the API of the unix_socket address type anyway (e.g. to perhaps more align with std::net). That being said, I don’t have many concrete opinions in this area just yet.

The SOCK_SEQPACKET socket type is a third variant that exists but is not currently supported.

This seems fine to me, the TCP/UDP sockets don’t support more flavorful socket types either, and the FromRawFd constructor is always there if necessary.

The sendmsg and recvmsg functions can be used to perform more advanced tasks with Unix sockets

Like SEQPACKET, this seems flavorful enough to punt on for now. AsRawFd exists for a reason!


Some other thoughts on the API

UnixStream::pair

I think that an analagous API exists for TCP as well (e.g. using the same socketpair implementation on unix), although it may be a Unix-specific extension.

UnixDatagram::unbound

This seems similar to net2::UdpBuilder?

UnixDatagram::{send, recv}

I think these are the two methods which don’t exist on UdpSocket and only work for connected sockets, but does seem fine to me to have.


#3

rust-unix-socket has been moved! https://github.com/rust-lang-nursery/rust-unix-socket