Summary
Unix domain sockets provide
a commonly used form of IPC on Unix-derived systems. This RFC proposes move the
unix_socket nursery crate into the
std::os::unix module.
Motivation
Unix sockets are a common form of IPC on unixy systems. Databases like PostgreSQL and Redis allow connections via Unix sockets, and Servo uses them to communicate with subprocesses. Even though Unix sockets are not present on Windows, their use is sufficiently widespread to warrant inclusion in the platform-specific sections of the standard library.
Detailed design
Unix sockets can be configured with the SOCK_STREAM, SOCK_DGRAM, and
SOCK_SEQPACKET types. SOCK_STREAM creates a connection-oriented socket that
behaves like a TCP socket, SOCK_DGRAM creates a packet-oriented socket that
behaves like a UDP socket, and SOCK_SEQPACKET provides something of a hybrid
between the other two - a connection-oriented, reliable, ordered stream of
delimited packets. SOCK_SEQPACKET support has not yet been implemented in the
unix_socket crate, so only the first two socket types will initially be
supported in the standard library.
While a TCP or UDP socket would be identified by a IP address and port number,
Unix sockets are typically identified by a filesystem path. For example, a
Postgres server will listen on a Unix socket located at
/run/postgresql/.s.PGSQL.5432 in some configurations. However, the
socketpair function can make a pair of unnamed connected Unix sockets not
associated with a filesystem path. In addition, Linux provides a separate
abstract namespace not associated with the filesystem, indicated by a leading
null byte in the address. In the initial implementation, the abstract namespace
will not be supported - the various socket constructors will check for and
reject addresses with interior null bytes.
A std::os::unix::net module will be created with the following contents:
The UnixStream type mirrors TcpStream:
Differences from TcpStream:
connecttakes anAsRef<Path>rather than aToSocketAddrs.- The
pairmethod creates a pair of connected, unnamed sockets, as this is commonly used for IPC. - The
SocketAddrreturned by thelocal_addrandpeer_addrmethods is different. - The
set_nonblockingandtake_errormethods are not currently present onTcpStreambut are provided in thenet2crate and are being proposed for addition to the standard library in a separate RFC.
As noted above, a Unix socket can either be unnamed, be associated with a path
on the filesystem, or (on Linux) be associated with an ID in the abstract
namespace. The SocketAddr struct is fairly simple:
The UnixListener type mirrors the TcpListener type:
Differences from TcpListener:
bindtakes anAsRef<Path>rather than aToSocketAddrs.- The
SocketAddrtype is different. - The
set_nonblockingandtake_errormethods are not currently present onTcpListenerbut are provided in thenet2crate and are being proposed for addition to the standard library in a separate RFC.
Finally, the UnixDatagram type mirrors the UpdSocket type:
Differences from UdpSocket:
bindtakes anAsRef<Path>rather than aToSocketAddrs.- The
unboundmethod creates an unbound socket, as a Unix socket does not need to be bound to send messages. - The
pairmethod creates a pair of connected, unnamed sockets, as this is commonly used for IPC. - The
SocketAddrreturned by thelocal_addrandpeer_addrmethods is different. - The
connect,send,recv,set_nonblocking, andtake_errormethods are not currently present onUdpSocketbut are provided in thenet2crate and are being proposed for addition to the standard library in a separate RFC.
Functionality not present
Some functionality is notably absent from this proposal:
- Linux's abstract namespace is not supported. Functionality may be added in
the future via extension traits in
std::os::linux::net. - No support for
SOCK_SEQPACKETsockets is proposed, as it has not yet been implemented. Since it is connection oriented, there will be a socket typeUnixSeqPacketand a listener typeUnixSeqListener. The naming of the listener is a bit unfortunate, but use ofSOCK_SEQPACKETis rare compared toSOCK_STREAMso naming priority can go to that version. - Unix sockets support file descriptor and credential transfer, but these will
not initially be supported as the
sendmsg/recvmsginterface is complex and bindings will need some time to prototype.
These features can bake in the rust-lang-nursery/unix-socket as they're
developed.
Drawbacks
While there is precedent for platform specific components in the standard library, this will be the by far the largest platform specific addition.
Alternatives
Unix socket support could be left out of tree.
The naming convention of UnixStream and UnixDatagram doesn't perfectly
mirror TcpStream and UdpSocket, but UnixStream and UnixSocket seems way
too confusing.
Unresolved questions
Is std::os::unix::net the right name for this module? It's not strictly
"networking" as all communication is local to one machine. std::os::unix::unix
is more accurate but weirdly repetitive and the extension trait module
std::os::linux::unix is even weirder. std::os::unix::socket is an option,
but seems like too general of a name for specifically AF_UNIX sockets as
opposed to all sockets.