为啥 TCP Server 接受连接后会立即发送 FIN?
Posted
技术标签:
【中文标题】为啥 TCP Server 接受连接后会立即发送 FIN?【英文标题】:Why will a TCP Server send a FIN immediately after accepting a connection?为什么 TCP Server 接受连接后会立即发送 FIN? 【发布时间】:2011-04-21 16:18:54 【问题描述】:从 ethreal 数据包捕获中,我看到以下对我来说似乎很奇怪的行为:
Client --> Server [SYN]
Server --> Client [SYN, ACK]
Client --> Server [ACK]
Server --> Client [FIN, ACK]
Client --> Server [ACK]
Client --> Server [TCP Segment of a reassembled PDU] (I don't know what this means)
Server --> Client [RST]
关于为什么会发生这种情况的任何想法?
另外,服务器端口是 6000。这会导致什么问题吗?
我的其他疑问:
-
为什么会有 FIN、ACK?不应该只有FIN吗?该消息中的 ACK 是什么意思?
不应该有来自客户端的 FIN 吗?
编辑: 经过进一步分析,我发现如果文件描述符的数量超过了限制,那么服务器会发送一个 FIN。但是,在这种情况下,文件描述符似乎没有超过限制。还有哪些情况会发生这种情况?
【问题讨论】:
服务器是远程的还是本地的?是否有可能是滥用 ISP 插入虚假数据包? 服务器是远程的。如何查明是否有任何伪造的数据包被插入? @Jay 关于1.请看publib.boulder.ibm.com/infocenter/tpfhelp/current/… 【参考方案1】:经过深入分析,发现问题原因如下:
当客户端尝试 TCP 连接时,即使服务器当前没有调用接受,连接也会通过。如果服务器调用了“侦听”功能,就会发生这种情况,并且它将继续接受连接,直到达到积压限制。
但是,如果应用程序进程超过了它可以使用的最大文件描述符的限制,那么当服务器调用accept时,它就会意识到没有文件描述符可以分配给socket,并且accept调用和TCP失败向另一端发送 FIN 的连接。
我只是想在这里发布这个发现。我仍然将接受的答案保留为哈比的答案。
感谢所有回答这个问题的人。
【讨论】:
【参考方案2】:FIN 通常表示套接字上名为shutdown(..)
的另一端。
【讨论】:
你的意思是说,在这种情况下,对 'accept' 的调用肯定会成功返回? 是的。如果没有 accept(),您只会看到静默并最终超时。 好的,但是,accept 不可能发送 FIN 对吧?我的意思是如果出现一些错误情况,有可能吗? 我不知道,当然。 嗯?不,连接是在调用accept()
之前建立的 - listen()
的 backlog 参数指定了可以处于此状态的连接数(已连接,但尚未调用 accept()
)。【参考方案3】:
我猜想inetd
或类似的守护进程正在接受连接,然后它会尝试fork
和exec
另一个程序来处理连接,并且fork
失败(由于资源耗尽)或exec
失败(由于文件不存在、权限错误等)。
【讨论】:
【参考方案4】:可能是TCP wrappers。如果服务器进程是使用 libwrap 支持构建的,它将接受连接,检查/etc/hosts.allow
和/etc/hosts.deny
,如果被策略拒绝,则立即关闭连接。
很容易看出服务器是否在使用 libwrap:
> ldd /usr/sbin/sshd | grep libwrap
libwrap.so.0 => /lib64/libwrap.so.0 (0x00007f1562d44000)
【讨论】:
【参考方案5】:我认为 FIN 是通过调用 close() 而不是 shutdown() 发送的。
连接在积压队列中;在 accept() 之后,服务器决定以任何原因终止它(例如 TCP 包装 ACL 或文件描述符不足)。在这种情况下,close() 将文件描述符 (FD) 的链接计数从 1 减少到 0,因此该连接的 FD 被完全销毁。之后,从服务器的角度来看,客户端将数据发送到一个不存在的套接字,服务器必须响应一个 RST。
如果是shutdown(),服务器仍然可以恢复客户端发送的数据,并且必须等待客户端的FIN才能优雅地关闭连接。没有 RST 被发回。
附言 close() vs shutdown()
【讨论】:
【参考方案6】:似乎服务器在接受连接后不久就调用了shutdown
。
【讨论】:
以上是关于为啥 TCP Server 接受连接后会立即发送 FIN?的主要内容,如果未能解决你的问题,请参考以下文章