fix(NET): 监听重建单一所有者收口 + 沉降窗 800ms 上限只留痕
T0 降噪 + T1 单一所有者:四处重建触发(recon/accept/eof/drop)与 pending 第五处统一走 net_listener_request(),由 net_listener_tick 单点执行; 沉降重试日志改"只留首末"(E0 口径),每次恢复少打 3 行重复行。 force open 降级为只留痕(E19 反事实 A/B 实测):芯片未回 CLOSED 时强行 open 注定吃 USE 错(TRAP-NET-09),放行与不放行的端口恢复时刻同一分布 (放行 +512 / 不放行 +505·533 / 降级后 +509 ms)——恢复由芯片何时回 CLOSED 决定。真正兜住"监听器永久失效"的是 D10 预算到期 + 对账形态④ 重新登记,不是放行。新增 s_relisten_capped[] 使上限留痕只打一次, 隔离标志不清 → 下一轮继续排空残渣(构建 B 实测每 30ms 两行会刷屏)。 负向注入三轮打靶(E18,注入代码不入库):形态① 吞掉 DISCONNECT 后 4/4 救回、③ 空闲监听器静默失位两轮独立复现、⑤ 开盲区吞掉芯片自发中断 + 收回 LISTEN 后 -> resync 命中且挂起 recv 被取消 → 三条均不可降级为 只留痕。顺带稳定复现 [ERR] relisten retry budget exhausted = 对端不配合 拆链的签名,非回归。 台架:boot PASS;ftp_abort_probe RST 10/10 + FIN 5/5;relisten_stress :21 50/50(p50 507ms);n30_repro 30/30。构建 0 错 0 警 Code=212316; netTask 静态最坏链 1920→1912 B;RAM 台账受管区已 --write 同步(RW +8B)。 文档:E17/E18/E19 三行 + §4.1 常态 0 命中归因 + §4.3 兜底归属改正; 登记簿 N-31 销项(结论沉淀进 §4.3 与 E19)。
This commit is contained in:
@@ -155,7 +155,7 @@ CH395F 以太网驱动与 NET 层的实证陷阱:现象、定案根因、修
|
||||
3. **做法**:直接 `ch395f_close_socket()`;`disconnect` 纯属多余且会**制造** DISCONNECT 事件(bit3=1 下必须被消费/预清,否则污染下一条连接,TRAP-NET-12/23 实证);
|
||||
4. **观测口径**:§5.22 第 1 字节只有 `00H/05H`,第 2 字节(TCP 态)**仅在 byte0=OPEN 时有意义**——关闭后轮询**第 1 字节**等 `00H` 再 open,别拿 byte1 当"卡住"判据。
|
||||
- **边界(E-02 台架)**:`close` 无 RST 的适用条件——对端配合(收到 FIN 后其内核 close):芯片走 `TIME_WAIT` ~150ms → relisten → 新连接接入;**对端内核存活但不 close**:芯片停在 **`FIN_WAIT_2`(byte0=05H/byte1=06H)长尾**——没有 RST 就拆不掉,**监听恢复受限于对端 close**。不配合场景的兜底 = 芯片自身 TIMEOUT/KeepAlive 拆僵尸会话(判死窗 30~90s,`docs/网络/网络自愈架构设计.md` §5.2 E13)——**不是**应用可加速的路径。
|
||||
- **应用侧出口 = `net_drop_conn(fd)`**(自愈收敛阶段 3):netTask 侧走驱动 `sock_reset` QUARANTINE(FIN+排渣+排空事件+等 byte0=00H,400ms 底)+ 本层收口 CLOSED + `auto_relisten` 即时重监听;**保监听不毁**(单连接模型不得 `net_close` 监听 fd)。对端不 close 时复位机等在 `net_poll` 步进里(`ch395f_sock_reset_poll`),对端 FIN 到达即自动走完——**不搁浅**。
|
||||
- **应用侧出口 = `net_drop_conn(fd)`**(自愈收敛阶段 3):netTask 侧走驱动 `sock_reset` QUARANTINE(FIN+排渣+排空事件+等 byte0=00H,400ms 底)+ 本层收口 CLOSED + `auto_relisten` 登记重监听(≤1ms 后 `net_listener_tick` 执行);**保监听不毁**(单连接模型不得 `net_close` 监听 fd)。对端不 close 时复位机等在 `net_poll` 步进里(`ch395f_sock_reset_poll`),对端 FIN 到达即自动走完——**不搁浅**。
|
||||
|
||||
## TRAP-NET-09 · 沉降窗:PHY link up 后 / close 后不能立即 open
|
||||
|
||||
@@ -163,7 +163,7 @@ CH395F 以太网驱动与 NET 层的实证陷阱:现象、定案根因、修
|
||||
- **现象**:PHY_CHANGE 中断同一时刻 `ch395f_open_socket()` 返错(非 BUSY 超时),首次 listen 失败。
|
||||
- **根因(定案)**:PHY link up 后芯片内部协议栈需额外时间完成初始化;同一 `net_poll()` 迭代内立即 `OPEN_SOCKET` 可能返 `ERR_BUSY` 或其他错误码。与 FUN_PARA 无关。
|
||||
- **修复(现行形态)**:
|
||||
1. `net_listen_locked`/`net_connect_locked` open 失败重试 ×3(D10 `net_listener_retry_tick` 重试环);
|
||||
1. `net_listen_locked`/`net_connect_locked` open 失败重试 ×3(D10 `net_listener_tick` 重试环);
|
||||
2. open 失败先走 `net_sock_reset_sync`(确定性排渣,内置二段 CLOSE,见下)再重试——最短等 100ms;
|
||||
3. 启动错峰走**就绪屏障**(`SYS_EVT_NET_READY`/`FTP_READY`),不用魔法延时。
|
||||
- **补充:LISTEN 态 Socket 的二段关闭**(E2/E4 芯片实验,本条"沉降才能重开"的前置形态):
|
||||
@@ -189,6 +189,7 @@ CH395F 以太网驱动与 NET 层的实证陷阱:现象、定案根因、修
|
||||
1. **异常释放(TIMEOUT/RST)隔离**:`handle_timeout_event` 置 per-fd 隔离标记;`net_relisten_locked` 隔离期内持续排空芯片 RX(`net_drain_chip_rx()`)+ 主动 close + 排空该 socket 中断 + 等 `CLOSED/TCP_CLOSED`,满 `NET_RELISTEN_QUARANTINE_MS`(400ms) 才 open+listen;上限 `NET_RELISTEN_SETTLE_MS`(800ms) 强制放行——**必须小于** `NET_RELISTEN_DEADLINE_MS`(2000ms):取 2000ms 会耗尽重试预算 → give up → **监听器死亡**;
|
||||
2. **正常释放(FIN)沉降**:`handle_disconnect_event` 登记(仅 `recv_bytes != 0` 时——纯连接即关与只发不收免沉降保复连时序),relisten 前最短等 `NET_RELISTEN_GRACEFUL_MS`(**100ms**,实测悬崖:0/30ms 无效、100ms 稳定通过);日志区分 `relisten settle`/`relisten quarantine`;
|
||||
3. **应用侧硬化**:`net_sock_t.released_abnormal` 标记(TIMEOUT 置 1/DISCONNECT 置 0,新 fd 与新监听清零——新连接不得继承上一条的释放原因);`net_pending_tick` 断连结束时按标记以 `NET_ERR_CONNRESET` 或 EOF(0) 回传;`lftpd receive_file` 错误路径 **unlink 截断文件** + STOR 回 **450**。
|
||||
- **收口尝试与边界(2026-10-14,E16)**:曾把上面修复 1 的排渣序列收口进驱动复合复位原语 `ch395f_sock_reset_*`(去重复实现与参数副本),**实测回退**:`ftp_abort_probe` RST **0/10**、FIN **0/5**(首笔复连仍被截断到 ≤2048B),并新增 `sock_reset_sync timeout (600ms)` / `close: sock_reset not done` 两条 `[ERR]`;同场 net 层自建序列 **10/10 + 5/5**(快复连 50/50、背靠背 30/30 两版都过 → 失效面精确落在"中止后首笔复连")。结论 = 原语缺**隔离窗内持续排空/关闭**与**复用让位**两条语义,补齐前 **net 层保留自建序列**,勿再直接把监听重建接进原语。前置语义与 A/B 数据 → `docs/网络/网络自愈架构设计.md` §8 延后项 1、§5.2 E16;登记 **N-30**。
|
||||
- **协议边界(不可判定,留痕)**:FTP STOR 无长度声明,"在途 FIN 关闭"与"正常完成"**逐字节不可区分** → 优雅中止仍回 226;仅 RST/掉链(芯片 TIMEOUT)可识别 → 450。FIN 边界由客户端长度校验(SIZE/RETR 往返)兜底。
|
||||
- **回归基线**:`--check-abort` RST **5/5**(450)+ FIN **5/5**(226 边界不变);followup 全过;正常往返 freeze SHA-256 全 MATCH;`:7003` sink 复用 RST×4/FIN×4 全过;`:8888` 真实收包写 RTC 成功。
|
||||
- **与 TC-NET-604 的关系**:本条是独立、已可信复现并已修复的真实缺陷;TC-NET-604 已结案为非缺陷(判读教训见第六章台架纪律)。现场"上传失败/文件不完整/像卡死"类报告优先用本条判据复核。
|
||||
|
||||
Reference in New Issue
Block a user