[erlang-questions] unix domain sockets with abstract namespace: can't use all 108 bytes

Kenneth Lakin kennethlakin@REDACTED
Thu Apr 27 07:51:38 CEST 2017


NB: The observations of a Linux weenie (that is, me) follow:

On 04/26/2017 05:46 PM, Richard A. O'Keefe wrote:
> Solaris documentation is clear that you should use
> bind(s, (struct sockaddr *) &addr,
> 		strlen(addr.sun_path) + sizeof (addr.sun_family))

Which is _really_ confusing to me.

Even on Solaris, sockaddr_un.sun_path is an array of fixed size, right?
And for INET and INET6 sockets, it seem that the Solaris documentation
says that argument three to bind is the length of the _entire struct_.

Why does it make sense to force client code to special-case UNIX domain
sockets and get strlen involved in calculating bind's third argument?
Why not have the kernel switch on sa_family_t and have any required
special-casing neatly hidden from the client? [0]

>> So it seems it is not a violation of Posix to use a su->sun_path that starts
>> with a 0 combined with an address_len of sizeof(*su).
> 
> It may not be, but the path is still "" and thus a run-time error.
> ...
> POSIX systems *shouldn't* do this, but Linux *does*.

My search skills might be weak, but I'm unable to find the section in
the POSIX documentation that fully addresses UNIX domain sockets. I
think the most it says on the topic is in the documentation for
sys/un.h, which pretty much says "sockaddr_un must have sun_family and
sun_path members. sun_path might be any size at all. Cast this struct to
struct_sockaddr when you use it.". [1] What did I miss?

If we move from thinking of sockaddr_un.sun_path as a null-terminated
string, and move to thinking of it as a fixed-length sequence of bytes
that might happen to be a null-terminated string, but might also be
interpreted in any other way by the underlying OS, does Linux's behavior
seem more sensible? I mean, if we're no longer constrained by the
restriction that sun_path _must_ be something that's a valid filename,
[2] we can get very creative with the interpretation of sun_path, no?

From a practical perspective, it seems to me that as long as you zero
out the entirety of the sockaddr_un before you start filling it and
ensure that whatever you copy into sun_path is not longer than sun_path,
then your code _should_ just work.

And, mostly unrelated to all that:

> It does not say the *size* of the structure but the
> *length* of the structure.

To be fair, the documentation seems to consistently uses "length of
[the] structure" where one might expect to see "size". See the
documentation for connect, for example. ;)

[0] And while we're talking about inconsistent interfaces, why do the
BSDs have a one-byte length as the first member of all(?) of its socket
structs? This wart appears to be absent in both Solaris and Linux.
[1] http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_un.h.html
[2] Because Linux's abstract namespace UNIX sockets are (just like IP
sockets) AFAICT _not_ represented as files in the filesystem.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20170426/69e035d1/attachment.bin>


More information about the erlang-questions mailing list