有没有办法模拟陷入 CLOSE_WAIT 或 FIN_WAIT2 的套接字?

有没有办法模拟陷入 CLOSE_WAIT 或 FIN_WAIT2 的套接字?

我有一个问题,我正在尝试解决以下问题:大量本地端口转发使套接字陷入 CLOSE_WAIT,而大量远程端口转发使套接字陷入 FIN_WAIT2。

目前我不知道为什么会发生这种情况。似乎是 ssh 中的错误(在 SuSE11 R4 上运行 OpenSSH_6.6.1p1、OpenSSL 0.9.8j-fips 07 Jan 2009)。但是,我想模拟这个,以便我可以编写一个套接字粉碎程序。

我尝试编写打开套接字并死掉的Python脚本,我尝试在线程中打开它们并杀死调用应用程序。我尝试过建立 MySQL 连接并让它们悬空(因为这是导致 CLOSE_WAIT 的原因,但我无法复制它)我可以尝试 1000 种其他方法,但没有一种可能会导致这种情况发生。启动挂起连接的两个应用程序都是闭源的:((一个是 Science Logic 数据库连接,另一个是来自 Cisco CSPC 盒的某些专有连接)

那么我需要做什么才能使套接字陷入 CLOSE_WAIT 状态,以及如何使套接字陷入 FIN_WAIT2 状态?

答案1

当对等系统(进程)关闭其 TCP 连接一侧时,会发生 CLOSE-WAIT,这已被本地操作系统检测到并传输到本地进程,但本地进程尚未通过关闭其一侧的 TCP 连接来确认这一点TCP 连接。当应用程序繁忙、有错误使其“忘记”关闭其某些套接字或挂起时(因此无法进一步关闭),这通常会变得可见。同时远端会有一个相应的FIN-WAIT-2,但是这个FIN-WAIT-2最终会过期。

它可以通过本地侦听和分叉socat进程来重现,该进程将向每个分叉子socat进程发送 STOP 信号以“挂起”它,以及 1 秒后放弃的远程连接(也可以通过命令完成socat):

  • 本地将立即停止自身,保证 CLOSE-WAIT 状态,因为它无法关闭其一侧的 TCP 连接:

    socat tcp4-listen:5555,reuseaddr,fork system:'kill -STOP $SOCAT_PID'
    

    对于每个收到的连接,socat子进程都会被分叉,并且本身会分叉一个 shell,该 shell 将立即停止该socat子进程(使用继承变量$SOCAT_PID),防止它(检测远程端已关闭并)关闭 TCP 连接的其端。

  • 远程(或者在本例中也是本地的,以保持简单)将在 1 秒不活动后放弃,并沿着对等方的 CLOSE-WAIT 获取关联的 FIN-WAIT-2 状态:

    for i in $(seq 1 5); do  socat -T 1 -u tcp4:127.0.0.1:5555 -; echo $i; done
    

上述循环完成后的示例结果:

$ ss -tn sport == 5555 or dport == 5555
State        Recv-Q   Send-Q     Local Address:Port        Peer Address:Port    
FIN-WAIT-2   0        0              127.0.0.1:33836          127.0.0.1:5555    
FIN-WAIT-2   0        0              127.0.0.1:33846          127.0.0.1:5555    
FIN-WAIT-2   0        0              127.0.0.1:33842          127.0.0.1:5555    
CLOSE-WAIT   1        0              127.0.0.1:5555           127.0.0.1:33840   
CLOSE-WAIT   1        0              127.0.0.1:5555           127.0.0.1:33836   
CLOSE-WAIT   1        0              127.0.0.1:5555           127.0.0.1:33842   
FIN-WAIT-2   0        0              127.0.0.1:33840          127.0.0.1:5555    
CLOSE-WAIT   1        0              127.0.0.1:5555           127.0.0.1:33846   
CLOSE-WAIT   1        0              127.0.0.1:5555           127.0.0.1:33834   
FIN-WAIT-2   0        0              127.0.0.1:33834          127.0.0.1:5555    

FIN-WAIT-2 最终会过期,但只要(已停止的)进程存在,CLOSE-WAIT 就会一直存在。打断主要的聆听socat会杀死它的孩子并清理一切。

相关内容