修复Trap23:异常释放后复监听隔离并排空RX残渣,上传中止截断消除(RST10/10+FIN5/5通过,正常50/50)

This commit is contained in:
2026-09-23 01:31:07 +08:00
parent 5a41b966fc
commit 7d70445c16
3 changed files with 100 additions and 1 deletions
+19
View File
@@ -673,3 +673,22 @@ CH395F 片内 TCP 状态机的角(芯片固件,MCU 侧无法修补)。2026
### 发现时间
2026-09-23(可信复现首轮:真实生产路径 FTP 中止/复连场景,由 `MDK-ARM/ftp_abort_probe.py` 自动判定)
### 修复实施与验证(2026-09-23 当日闭环)
**真因(设备侧日志实证,含正常对照)**:
1. 客户端中止上传时对端**仍有在途数据**;芯片给出 `sock4 TIMEOUT`(此刻 MCU 侧 `recv=0`),net 层随即释放该 socket 并复监听;
2. 那些**在途段随后才落进芯片 RX 缓冲**(约一个缓冲 = 2048B 残渣),而正常传输时 DISCONNECT 到达刻芯片里也仍有数据(对照实测 `recv=64512/65536`,由应用读空 → 完整);
3. 中止后立即 `open+listen`,残渣被**下一条连接当作自己的数据读走**:新上传只“收到”2048B 就被判定结束并回报 226(首笔复连必中招,第二笔起芯片已干净 → 恢复正常)。
**修复(`Drivers/BSP/NET/net_socket.c`,仅异常释放路径,正常 FIN 路径零改动)**:
1. `handle_timeout_event`(ESTABLISHED 超时释放)置 per-fd **隔离标记** `s_relisten_quarantine[]`;
2. `net_relisten_locked` 对带隔离标记的 socket:**隔离期内持续排空芯片 RX**(新增 `net_drain_chip_rx()`,分块读空、零新增静态缓冲)+ **主动 `ch395f_close_socket` 并排空该 socket 中断** + 等芯片回到 `CLOSED/TCP_CLOSED`,隔离满 `NET_RELISTEN_QUARANTINE_MS`(400ms) 才 `open+listen`;
3. 上限 `NET_RELISTEN_SETTLE_MS`(800ms) 强制放行 —— **必须小于** `NET_RELISTEN_DEADLINE_MS`(2000ms):实测取 2000ms 会把重试预算耗尽 → 重试轮询"give up" → **监听器死亡(:21 拒连)**,已修正并在注释中留痕;
4. 隔离状态在 `net_relisten_clear` 内一并清除(关闭/新建 fd 时不残留)。
**验证(可信判据:FTP 协议结果 + 紧接一笔上传的 SHA-256 往返 + 控制通道存活)**:
- 修复前:RST 中止 **0/10**、优雅 FIN 中止 **0/5**(首笔复连上传全部被截断且回报成功);
- 修复后:RST 中止 **10/10**、优雅 FIN 中止 **5/5** 全部通过;
- 正常路径回归:30×64KB 零间隔 **30/30**、20×64KB **20/20**,SHA-256 全匹配;
- 启动门禁:`App init OK` / `net init: OK`、FORBID 0 行。