Since sun_len is the sockaddr_un pun of sockaddr.sa_len, I would very much
prefer to make sure everything sets sun_len correctly, and make the kernel use
it properly.
With respect to userland I for one would prefer if sun_len disappeared. Many
other systems e.g., IRIX, Solaris don't have it and a lot software (maybe most)
ignores it. As NetBSD seems to ignore it and doesn't even document it, getting
rid of it seems an obvious choice to me. I don't mind what the kernel does. I
don't have a strong opinion on that though, if sun_len is there but ignored,
that's fine by me too.
In particular, that's the only way I can see to make AF_LOCAL sockets with path
names longer than 103 octets work properly. Most of my code that uses AF_LOCAL
with non-null names malloc()s based on an expression rather like SUN_LEN,
rather than allocating a struct sockaddr_un and trusting the path name to fit.
Few code does this and it's technically not portable i.e., it works only if
sun_path is last member and if the OS actually uses the trailing data. The
former can be checked at compile or runtime but it might just as well treat
sun_path as a char array that requires no NUL termination.
Actually it looks as if NetBSD doesn't require a terminating NUL if you use a
path longer than sun_path with a dynamically sized socket address as long as
you pass the correct size to bind() and connect(). Note, however, that you
mustn't use SUN_LEN() unless you allocate one additional byte and nullify it as
SUN_LEN() uses strlen().
This allows a maximum socket path of 253 characters which is still below the
minimum maximum pathname length (255) and filename length (1023) handled by
open() et al. That's because sun_len is uint8_t (u_char) like sun_family. So
you have a limit of 255 there and the two bytes are reserved for sun_len and
sun_family. Without sun_len (in userland) you could possibly easily support
longer paths.
I don't think not terminating the path is a good choice for portable code,
though as you obviously can't check for this requirement properly.
For what it's worth, I've checked Linux and apparently it's not possible to use
a path longer than sizeof(un->sun_path). bind() returns EINVAL for paths longer
than that. FreeBSD behaves the same as NetBSD. IRIX seems to have a rather
odd maximum of 221 characters.
It is also careful to set sun_len correctly.
Maybe but it's not documented how to set sun_len correctly. No, I don't accept
a pointer to Stevens as documentation. Also, I tried various flavours of
SUN_LEN() on IRIX and most of them were wrong causing truncation of the path.
sizeof() apparently works everywhere. It's used in NetBSD as well as
third-party code. So, I think this macro just causes unnecessary confusion or
bugs even. Every code I've seen so far uses
#ifndef SUN_LEN
#define SUN_LEN(x) ...
#endif
but as said, these are often wrong which is just never noticed because it works
on the most popular systems. As long as this is only used to set sun_len which
is seemingly ignored anyway, it's no problem.
Attached is test program that can be used to check the limit for the socket
path on a given system. Note, that this works without SUN_LEN() and sun_len. So
they are completely redundant (on NetBSD) in userland.
--
Christian