Why is socket path length limited to a hundred chars?

Why is socket path length limited to a hundred chars?

Unixシステムでは、パス名の長さ制限は通常ほとんどありません(Linuxでは4096文字)。ただし、ソケットファイルのパスは制限されています。約100文字(107文字以上)リナックス)。

  • 最初の質問:なぜこんなに制限が低いのでしょうか?

現在の作業ディレクトリを変更し、さまざまなディレクトリにすべて同じパスを使用する複数のソケット ファイルを作成することで、この制限を回避できることを確認しました./myfile.sock。クライアント アプリケーションは、すべてが同じソケット ファイル パスでリッスンしていることが示されていても、期待されるサーバー プロセスに正しく接続しているようですlsof

  • この回避策は信頼できるものでしょうか、それとも単に運が良かっただけでしょうか?
  • この動作は Linux に特有のものでしょうか、それともこの回避策は他の Unix にも適用できるのでしょうか?

答え1

他のプラットフォームとの互換性、または および の使用中にオーバーランを回避するための古いものとの互換性snprintf()strncpy()

マイケル・ケリスクが説明する彼の本1165ページ- 第57章 ソケット: Unixドメイン:

SUSv3 では、sun_path フィールドのサイズは指定されていません。初期の BSD 実装では 108 バイトと 104 バイトが使用され、最近の実装の 1 つ (HP-UX 11) では 92 バイトが使用されています。移植可能なアプリケーションでは、この低い値に合わせてコーディングし、このフィールドに書き込むときにバッファ オーバーランを回避するために snprintf() または strncpy() を使用する必要があります。

Docker の人たちは、ソケットが 110 文字もあるので、それをからかっていました。

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

答え2

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.

関連情報