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


18

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

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

我检查了,它似乎有可能通过改变当前的工作目录,并在不同的目录中创建所有使用相同的路径几个套接字文件来解决此限制./myfile.sock:客户端应用程序似乎正确地连接到预期的服务器进程偶数虽然lsof显示所有他们中的一个在同一套接字文件路径上侦听。

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

在当前的OpenBSD系统或Mac OS X 10.11上,该限制甚至更低(104)。
thrig

重要的是,为了兼容起见,它必须低于108 :)

AFAIK在Linux上是108个字符。请在您的机器上检查/usr/include/$arch-linux-gnu/sys/un.h。
schaiba

@schaiba:108个字节,表示107个字符的字符串,以空终止符结尾。
WhiteWinterWolf

Answers:


18

与其他平台的兼容性,或与较旧版本的兼容性,以避免在使用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域套接字):


1
SUSv3 XNET保持沉默,因为对此问题尚未达成共识。
fpmurphy '17

您是否有任何链接可以证明您的观点?

感谢您的回答。使用多个相对于不同工作目录具有相同名称的套接字文件是否可靠(例如,创建一个./my.socket在directory下面命名的套接字文件A/,以及另一个./my.socket在directory之下命名另一个套接字文件B/)?lsof不会在两个套接字文件之间进行任何区分,但是它似乎仍然有效,但是我想知道这是否仅是因为我很幸运。这是在低于已允许大小的路径下创建套接字文件的好方法。
WhiteWinterWolf

在我的邮件服务器上搜索unix套接字,似乎带来了完整的路径名:(lsof -U| grep amavis换行符)amavis-se 2708 zimbra 17u unix 0xffff8806c0a95400 0t0 310330411 /opt/zimbra/data/tmp/amavisd-zmq.sock

是的,我知道这很不正常,因此我在这里提出问题;)!对于我测试的内容,相对名称有效,但对我来说似乎仍然很奇怪...但是有效。我的应用程序不是系统范围的,因此套接字文件或者与所有其他应用程序数据一起存储在用户控制的位置,这是强烈优选的选择,但是路径可能太长,或者我可能会混乱/tmp成堆,每一个都有大量的唯一命名的未删除目录包含一个套接字文件(非常难看,但可移植且安全)。
WhiteWinterWolf

5

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

在这里,我将只关注方式和相对路径的用法。

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

可以很容易地检查如下:

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

我在少数Unix系统(Linux Debian,FreeBSD和OpenIndiana)上检查了此行为,因此,即使不是标准情况,这种行为似乎至少也很广泛。

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.