TCP 关闭时未能发送 RST 以待处理数据
问题名称 '关闭时未能发送RST以待处理的数据'
分类 '资源管理'
描述 当应用程序以无法再读取任何接收到的数据的方式关闭连接时,根据RFC 1122的4.2.2.13节,TCP应该在有未读取的接收数据或接收到任何新数据时发送一个RST。如果TCP未能这样做,则表现为'关闭时未能发送RST以待处理的数据'。
需要注意的是,对于某些TCP来说,此情况可能是由于在对等方发送数据时应用程序'崩溃'引起的。
我们已经观察到许多出现此问题的TCP。如果向现已关闭的连接端点发送的任何后续数据引发RST(请参见下面的示例),则问题较不严重。
重要性 对于进行大量连接的端点来说,此问题的重要性最大,因为它们的资源将被耗尽,从而减少了它们进行连接的能力。
影响 未能重置连接可能导致永久挂起的连接,其中远程端点不采取进一步的操作来拆除连接,因为它正在等待本地TCP首先采取一些操作。如果本地TCP还允许广告窗口变为零,并且在远程TCP执行'持续'探测时未能拆除连接,则情况尤其如此(请参见下面的示例)。
相关RFC RFC 1122的4.2.2.13节。此外,RFC 1122的4.2.2.17节中讨论了零窗口探测。
用示例文件演示 使用tcpdump生成。无可用的丢失信息。
13:11:46.04 A > B: S 458659166:458659166(0) win 4096 <mss 1460,wscale 0,eol> (DF) 13:11:46.04 B > A: S 792320000:792320000(0) ack 458659167 win 4096 13:11:46.04 A > B: . ack 1 win 4096 (DF) 13:11.55.80 A > B: . 1:513(512) ack 1 win 4096 (DF) 13:11.55.80 A > B: . 513:1025(512) ack 1 win 4096 (DF) 13:11:55.83 B > A: . ack 1025 win 3072 13:11.55.84 A > B: . 1025:1537(512) ack 1 win 4096 (DF) 13:11.55.84 A > B: . 1537:2049(512) ack 1 win 4096 (DF) 13:11.55.85 A > B: . 2049:2561(512) ack 1 win 4096 (DF) 13:11:56.03 B > A: . ack 2561 win 1536 13:11.56.05 A > B: . 2561:3073(512) ack 1 win 4096 (DF) 13:11.56.06 A > B: . 3073:3585(512) ack 1 win 4096 (DF) 13:11.56.06 A > B: . 3585:4097(512) ack 1 win 4096 (DF) 13:11:56.23 B > A: . ack 4097 win 0 13:11:58.16 A > B: . 4096:4097(1) ack 1 win 4096 (DF) 13:11:58.16 B > A: . ack 4097 win 0 13:12:00.16 A > B: . 4096:4097(1) ack 1 win 4096 (DF) 13:12:00.16 B > A: . ack 4097 win 0 13:12:02.16 A > B: . 4096:4097(1) ack 1 win 4096 (DF) 13:12:02.16 B > A: . ack 4097 win 0 13:12:05.37 A > B: . 4096:4097(1) ack 1 win 4096 (DF) 13:12:05.37 B > A: . ack 4097 win 0 13:12:06.36 B > A: F 1:1(0) ack 4097 win 0
上述跟踪中的机器B在套接字被应用程序'关闭'(在本例中,应用程序进程被终止)时不会丢弃接收到的数据。这发生在约13:12:06.36,导致FIN在响应关闭时被发送。但是,由于不再有应用程序来传递数据,TCP应该发送RST。
注意:机器A的零窗口探测也存在问题。它正在重新发送旧数据,而不是新数据。RFC 793中的第3.7节和RFC 1122中的第4.2.2.17节讨论了零窗口探测。
用示例文件演示更好的行为 使用tcpdump生成。无可用的丢失信息。
更好,但仍然不完全正确,行为,根据下面的讨论。我们展示这种行为,因为它已在许多不同的TCP实现中观察到。
13:48:29.24 C > D: S 73445554:73445554(0) win 4096 <mss 1460,wscale 0,eol> (DF) 13:48:29.24 D > C: S 36050296:36050296(0) ack 73445555 win 4096 <mss 1460,wscale 0,eol> (DF) 13:48:29.25 C > D: . ack 1 win 4096 (DF) 13:48:30.78 C > D: . 1:1461(1460) ack 1 win 4096 (DF) 13:48:30.79 C > D: . 1461:2921(1460) ack 1 win 4096 (DF) 13:48:30.80 D > C: . ack 2921 win 1176 (DF) 13:48:32.75 C > D: . 2921:4097(1176) ack 1 win 4096 (DF) 13:48:32.82 D > C: . ack 4097 win 0 (DF) 13:48:34.76 C > D: . 4096:4097(1) ack 1 win 4096 (DF) 13:48:34.84 D > C: . ack 4097 win 0 (DF) 13:48:36.34 D > C: FP 1:1(0) ack 4097 win 4096 (DF) 13:48:36.34 C > D: . 4097:5557(1460) ack 2 win 4096 (DF) 13:48:36.34 D > C: R 36050298:36050298(0) win 24576 13:48:36.34 C > D: . 5557:7017(1460) ack 2 win 4096 (DF) 13:48:36.34 D > C: R 36050298:36050298(0) win 24576
在此跟踪中,应用程序进程在约13:48:36.34在机器D上终止。它的TCP发送FIN,并再次打开窗口(因为它丢弃了先前接收到的数据)。机器C立即发送更多数据,导致机器D重置连接,因为它无法将数据传递给应用程序。理想情况下,机器D应该发送RST,而不是丢弃数据并重新打开接收窗口。
注意:机器C的零窗口探测存在问题,与上面的示例相同。
用示例文件演示正确行为 使用tcpdump生成。没有由数据包过滤器报告的丢失。
14:12:02.19 E > F: S 1143360000:1143360000(0) win 4096 14:12:02.19 F > E: S 1002988443:1002988443(0) ack 1143360001 win 4096 <mss 1460> (DF) 14:12:02.19 E > F: . ack 1 win 4096 14:12:10.43 E > F: . 1:513(512) ack 1 win 4096 14:12:10.61 F > E: . ack 513 win 3584 (DF) 14:12:10.61 E > F: . 513:1025(512) ack 1 win 4096 14:12:10.61 E > F: . 1025:1537(512) ack 1 win 4096 14:12:10.81 F > E: . ack 1537 win 2560 (DF) 14:12:10.81 E > F: . 1537:2049(512) ack 1 win 4096 14:12:10.81 E > F: . 2049:2561(512) ack 1 win 4096 14:12:10.81 E > F: . 2561:3073(512) ack 1 win 4096 14:12:11.01 F > E: . ack 3073 win 1024 (DF) 14:12:11.01 E > F: . 3073:3585(512) ack 1 win 4096 14:12:11.01 E > F: . 3585:4097(512) ack 1 win 4096 14:12:11.21 F > E: . ack 4097 win 0 (DF) 14:12:15.88 E > F: . 4097:4098(1) ack 1 win 4096 14:12:16.06 F > E: . ack 4097 win 0 (DF) 14:12:20.88 E > F: . 4097:4098(1) ack 1 win 4096 14:12:20.91 F > E: . ack 4097 win 0 (DF) 14:12:21.94 F > E: R 1002988444:1002988444(0) win 4096
当应用程序在14:12:21.94终止时,F立即发送RST。
注意:机器E的零窗口探测(最终)是正确的。
如何检测 此问题通常可以通过检查接收应用程序异常终止的传输的数据包跟踪来检测。这样做时,可能会存在一种模糊性(如果只查看跟踪),即接收TCP是否确实有它现在无法传递的未读数据。为了激发这种情况,暂停接收应用程序以使其无法使用任何数据,最终耗尽广告窗口可能会有所帮助。此时,由于广告窗口为零,我们知道接收TCP有未传递的数据缓冲起来。终止应用程序进程应该足以测试TCP行为的正确性。
原文地址: https://www.cveoy.top/t/topic/ojNa 著作权归作者所有。请勿转载和采集!