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

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

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

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

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

  • 这个解决方法可靠还是我只是幸运?
  • 此行为是 Linux 特有的还是此解决方法也适用于其他 Unix?

答案1

与其他平台的兼容性,或与旧版本的兼容性,以避免使用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 的数据结构。 Mbufs(即内存缓冲区)长 128 字节,其中 100 或 108 字节的空间保留用于数据存储。

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

答案2

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

这里我只关注如何使用以及相对路径的使用。

在内部,虽然套接字文件也可以通过名称查找(我猜),但它们通常是通过索引节点查找的。在 Linux 中,此查找由unix_find_socket_byinode()定义在网/unix/af_unix.c

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

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

我在一些 Unix 系统(Linux Debian、FreeBSD 和 OpenIndiana 以获得一些多样性)上检查了这种行为,因此这种行为即使不是标准的,至少也是广泛传播的。

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

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

相关内容