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

Nic*_*son 9 sockets linux macos posix solaris

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

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

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

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

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

jxh*_*jxh 2

无论您是否尝试更改标准,或更改供应商的实施方式connect(),我认为从软件的角度来看,这都不会产生任何影响。ECONNREFUSED并且EAGAIN都应该被视为重试。

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

try_again:
    rc = connect(s, (void *)&addr, sizeof(addr));
    if (rc == 0) return connect_succeeded(s, &addr);
    switch (errno) {
    case EAGAIN:
    case ECONNREFUSED:
        if (should_try_again(retries++)) {
            goto try_again;
        }
        break;
    case EINTR:
        goto try_again;
    default:        
        break;
    }
    return connect_failed(s, errno);
Run Code Online (Sandbox Code Playgroud)