为什么套接字路径长度限制为一百个字符?

Whi*_*olf 26 filenames limit socket unix-sockets

在 Unix 系统上,路径名通常几乎没有长度限制(Linux 上为 4096 个字符)...除了套接字文件路径限制为大约 100 个字符Linux上为 107 个字符)。

  • 第一个问题:为什么限制这么低?

我已经检查过是否可以通过更改当前工作目录并在各个目录中创建多个使用相同路径的套接字文件来解决此限制./myfile.sock:客户端应用程序似乎正确连接到预期的服务器进程,即使lsof显示所有他们在同一个套接字文件路径上侦听。

  • 这种解决方法可靠还是我很幸运?
  • 这种行为是特定于 Linux 的还是这种解决方法也适用于其他 Unix?

小智 25

与其他平台的兼容性,或与旧东西的兼容性,以避免在使用snprintf()和 时溢出strncpy()

Michael Kerrisk 在他的书中解释了第 1165 页- 第 57 章,套接字:Unix 域:

SUSv3 没有指定 sun_path 字段的大小。早期的 BSD 实现使用 108 和 104 字节,而一种当代实现 (HP-UX 11) 使用 92 字节。便携式应用程序应编码为该较低值,并在写入此字段时使用 snprintf() 或 strncpy() 以避免缓冲区溢出。

Docker 人甚至取笑它,因为有些套接字有 110 个字符长:

这就是 LINUX 使用 108 字符套接字的原因。这可以改变吗?当然。这就是为什么首先在旧操作系统上创建此限制的原因:

引用答案:

它是为了匹配一个方便的内核数据结构中的可用空间。

引用 McKusick 等人的“4.4BSD 操作系统的设计与实现”。阿尔。(第 369 页):

内存管理工具围绕称为 mbuf 的数据结构展开。Mbuf 或内存缓冲区长 128 字节,其中 100 或 108 字节保留用于数据存储。

其他操作系统(unix 域套接字):


Whi*_*olf 8

关于原因,nwildner 已经写了一个很好的答案

在这里,我将只关注 how 和相对路径的使用。

在内部,虽然套接字文件也可以按名称查找(我猜),但它们通常由 inode 查找。在 Linux 中,此查找由net/unix/af_unix.c 中unix_find_socket_byinode()定义的函数确保。

这可以很容易地检查如下:

  • 创建两个目录A/B/
  • 在每个目录下,让一个进程侦听具有相同名称的套接字文件。有了socat你可以使用一个命令,例如:
$ socat UNIX-LISTEN:./my.sock -
Run Code Online (Sandbox Code Playgroud)
  • 现在通过将A/my.sock移动到B/来交换套接字文件,反之亦然。
  • 从现在开始,如果客户端应用程序连接到A/my.sock它将联系服务器B,如果它连接到B/my.sock它将联系服务器A(但请注意,当通信结束时,服务器进程可能合法地删除它认为是它自己的套接字文件)。

我在少数 Unix 系统(Linux Debian、FreeBSD 和 OpenIndiana 以获得一些多样性)上检查了这种行为,所以这种行为似乎至少是广泛传播的,如果不是标准的。

绝对路径通常用作客户端和服务器进程之间的约定,因为客户端进程可能不知道如何与服务器建立初始通信。

然而,如果这个初始通信不是问题,那么使用相对路径来创建套接字文件似乎是安全的,当套接字文件位置不受服务器进程直接控制时,可以避免路径长度问题。