connect()与unix-domain套接字和完整的待办事项

时间:2013-10-07 09:23:37

标签: linux macos sockets posix solaris

当STREAM unix域套接字的监听积压已满时,connect(2)在大多数具有ECONNREFUSED的系统上失败。它最好返回EAGAIN。

理由是,能够区分死套接字的两种情况(文件系统中存在节点,但不再有进程侦听)和完全积压的情况非常有用。我在移植一些有一些代码来清理死套接字的Linux软件时遇到了这个问题,但是如果代码可以通过垃圾邮件来欺骗它们来填补他们的积压,那么这就是一个安全漏洞。

只有Linux返回EAGAIN; AIX,Solaris和Darwin遵循BSD行为(仅对每个行为进行测试)。

POSIX没有将EAGAIN列为connect()(link)的可能返回代码,因此这里可能存在一些合规性问题。

让每个人都根据Linux改变的最佳途径是什么?我可以向Oracle,Apple,一个FreeBSD PR提交一份错误报告,并在每个组织的邮件列表上进行斗争。或者我应该在标准组织(奥斯汀组)中纠缠某人?即使优势很明显,尝试让每个人都在这里改变也是明智的吗?

2 个答案:

答案 0 :(得分:0)

无论您是否尝试更改标准或更改供应商实施Accepted的方式,从软件的角度来看,我都认为这不会有任何区别。 connect()ECONNREFUSED都应视为重试。

区分这两种情况可能使您可以在客户端上写更具体的诊断消息,但是重试逻辑应该相同。即使该侦听器当前不存在,它最终也可能存在,因此应尝试重试。

EAGAIN

答案 1 :(得分:0)

与大多数事情一样,如果您可以说服消息来源采取行动,那么所有用户都必须遵守。因此,让 POSIX 解决问题当然是最好的选择。那么所有的实现都必须遵守。

另一种解决方案是使用它工作的系统。即只使用 Linux 机器(在这种情况下)。同样在 Linux 中,您可以调整内核并使其以一种或另一种方式工作(这在 BSD 中也是可行的)。

现在,我对此事的看法,在我看来,这里的主要问题是一个流氓进程试图打开一个套接字来接收消息而不是预期的服务。我的问题是:这种情况多久发生一次?

如果您使用类似于 systemctl 的系统,您将只有一个运行该服务的实例。如果您试图在服务中的那个点打开 AF_UNIX 套接字,那么您确实是唯一一个尝试这样做的人。因此,删除文件不是问题。

如果您允许流氓软件在您的系统上运行(即它是公开的并且您有很多用户可以访问,就像过去人们通过 telnet 连接到服务器一样),那么您可能需要使用 TCP 或 UDP而是连接。

最后,如果另一个软件能够打开那个 AF_UNIX 套接字,我认为无论如何你都会遇到麻烦,因为当流氓软件 (1) 删除您的套接字时,您的服务可以运行,(2) { {1}} 重新开始,(3) 您的 新客户现在正在与该流氓软件对话,而不是您的服务,即使您仍在运行并侦听连接......在隐藏文件套接字。 (请注意,旧客户端将继续与您的服务对话,任何重新连接的客户端都将与流氓软件对话)。

那么……你的问题在哪里?