Why is socket path length limited to a hundred chars?
Compatibility with other platforms, or compatibility with older stuff to avoid overruns while using snprintf()
and strncpy()
.
Michael Kerrisk explain in his book at the page 1165 - Chapter 57, Sockets: Unix domain :
SUSv3 doesn’t specify the size of the sun_path field. Early BSD implementations used 108 and 104 bytes, and one contemporary implementation (HP-UX 11) uses 92 bytes. Portable applications should code to this lower value, and use snprintf() or strncpy() to avoid buffer overruns when writing into this field.
Docker guys even made fun of it, because some sockets were 110 characters long:
- lol 108 chars ETOOMANY
This is why LINUX uses a 108 char socket. Could this be changed? Of course. And this, is the reason why in the first place this limitation was created on older Operating Systems:
- Why is the maximal path length allowed for unix-sockets on linux 108?
Quoting the answer:
It was to match the space available in a handy kernel data structure.
Quoting "The Design and Implementation of the 4.4BSD Operating System" by McKusick et. al. (page 369):
The memory management facilities revolve around a data structure called an mbuf. Mbufs, or memory buffers, are 128 bytes long, with 100 or 108 bytes of this space reserved for data storage.
Other OSs(unix domain sockets):
- OpenBSD: 104 characters
- FreeBSD: 104 characters
- Mac OS X 10.9: 104 characters
Regarding the why, nwildner already wrote an excellent answer.
Here I will just focus on the how and the relative path usage.
Internally, while socket file can also be looked up by name (I guess), they are usually looked up by inode. In Linux, this lookup is ensured by the function unix_find_socket_byinode()
defined in net/unix/af_unix.c.
This can be easily checked as follow:
- Create two directories A/ and B/.
- Under each directory, make a process listen on socket files bearing the same name. With
socat
you would use a command such as:
$ socat UNIX-LISTEN:./my.sock -
- Now exchange the socket files by moving A/my.sock to B/ and vice-versa.
- From now on, if client application connects to A/my.sock it will contact the server B, and if it connects to B/my.sock it will contact the server A (note though that when the communication ends, the server process may legitimately delete what it thinks to be its own socket file).
I checked this behavior on a handful of Unix systems (Linux Debian, FreeBSD and OpenIndiana to get some diversity), so this behavior seems to be at least wide-spread, if not standard.
Absolute paths are usually used as a convention between the client and the server processes, as the client process may not otherwise know how to establish the initial communication with the server.
However, if this initial communication is not an issue, it seems therefore safe to use relative paths for socket files creation, allowing to avoid path length issues when the socket file location is not directly controlled by the server process.