18

On Unix systems path names have usually virtually no length limitation (well, 4096 characters on Linux)... except for socket files paths which are limited to around 100 characters (107 characters on Linux).

  • First question: why such a low limitation?

I've checked that it seems possible to work around this limitation by changing the current working directory and creating in various directories several socket files all using the same path ./myfile.sock: the client applications seem to correctly connect to the expected server processes even-though lsof shows all of them listening on the same socket file path.

  • Is this workaround reliable or was I just lucky?
  • Is this behavior specific to Linux or may this workaround be applicable to other Unixes as well?
  • The limit is even lower (104) on current OpenBSD systems or Mac OS X 10.11. – thrig May 24 '17 at 17:28
  • The important thing, is that it has to be lower than 108, for the sake of compatibility :) – user34720 May 24 '17 at 17:32
  • AFAIK it's 108 chars on Linux. Please check /usr/include/$arch-linux-gnu/sys/un.h on your machine. – schaiba May 25 '17 at 11:36
  • @schaiba: 108 bytes, which means a 107 characters string ended by a null terminator. – WhiteWinterWolf May 25 '17 at 14:48
16

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:

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:

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):

  • 1
    SUSv3 XNET was silent because there not consensus on the issue. – fpmurphy May 24 '17 at 18:16
  • Do you have any link to proof your point of view? – user34720 May 24 '17 at 18:39
  • Thanks for this answer. Is it reliable to use several socket files bearing identical names relative to different working directories (for instance, create a sockets file named ./my.socket below directory A/, and another socket file also named ./my.socket below directory B/)? lsof doesn't make any distinction between the two socket files, however it still seem to work but I wonder if this is just because I'm lucky. This would be a good workaround to create socket files below a path which is already longer than the allowed size. – WhiteWinterWolf May 24 '17 at 18:57
  • Searching for unix sockets on my mailserver, seems to bring full path name: lsof -U| grep amavis (newline) amavis-se 2708 zimbra 17u unix 0xffff8806c0a95400 0t0 310330411 /opt/zimbra/data/tmp/amavisd-zmq.sock – user34720 May 24 '17 at 19:19
  • Yes, I know this is unusual, hence my question here ;) ! For what I tested, relative names work, but it still seems odd to me... but it works. My application is not system-wide, so socket files are either stored with all other application data in a user-controlled location, which is strongly preferred but with a potentially too long path, or I can clutter /tmp with tons of uniquely named undeleted directories each containing a single socket file (utterly ugly, but portable and secure). – WhiteWinterWolf May 24 '17 at 19:38
4

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.