Linux's abstract namespace for Unix domain sockets
The address of ordinary Unix domain sockets for servers is the file name of a socket file that actually appears in the filesystem. This is pleasantly Unix-y on the surface but winds up requiring you to do a bunch of bureaucracy to manage these socket files, and the socket files by themselves don't actually do anything that would make it useful for them to be in the filesystem; you can't interact with them and the server behind them with normal Unix file tools, for example.
Linux offers you a second choice. Rather than dealing with socket files in the filesystem, you can use names in an abstract (socket) namespace. Each name must be unique, but the namespace is otherwise flat and unstructured, and you can call your server socket whatever you want. Conveniently and unlike socket files, abstract names vanish when the socket is closed (either by you or because your program exited).
Apart from being Linux-only, the abstract socket namespace suffers from two limitations: you have to find a way to get a unique name and it has no permissions. With regular socket files you can use regular Unix file and directory permissions to insure that only you can talk to your server socket. With abstract socket names, anyone who knows or can find the name can connect to your server. If this matters you will have to do access control yourself.
(One approach is to use getsockopt()
with SO_PEERCRED
to get the UID and
so on of the client connecting to you. SO_PEERCRED
is Linux
specific as far as I know, but then so is the abstract socket
namespace.)
Lsof and other tools conventionally represent socket names in the
abstract socket namespace by putting an @
in front of them. This
is not actually how they're specified at the C API level, but it's
a distinct marker and some higher level tools follow it for, eg,
specifying socket names.
(The Go net
package is one such piece of software.)
As far as picking unique names goes, one trick many programs seem
to use is to use whatever filename they would be using if they
didn't have the abstract socket namespace available. This gives you
a convenient way of expressing, eg, per-user sockets; you can just
give it a name based on the user's home directory. Other programs
use a hierarchical namespace of their own; Ubuntu's upstart
listens
on the abstract socket name '/com/ubuntu/upstart
', for example.
(For personal hacks, you can of course just make up your own little short names. Little hacks don't need a big process; that's the whole attraction of the abstract namespace.)
Now that I've poked around this, I'm going to use it for future little Linux-only hacks because checking permissions (if it's even necessary) is a lot more convenient than the whole hassle of dealing with socket files. For things I write that are intended to be portable, I don't see much point; portable code has to deal with socket files so I might as well use regular Unix domain socket names and socket files all the time.
(A bunch of my personal hacks are de facto Linux only because my desktop machines are Linux. I'll regret that laziness if I ever try to move my desktop environment to FreeBSD or the like, but that seems highly unlikely at the moment.)
|
|