代码
- 内容分发块级寻址:新增 src/net/relay/content/{chunker,store,runtime,source,peer,crypto}.ts
- 组密钥(C 档)确定性加密:AES-256-GCM,块 id β′ = sha256(密文) 前 32 hex;双 epoch 过渡窗口
- 实例生命周期:三处 teardown() 不再杀实例(local/remote/leased-spawner);启动认领 + TCP 探活判孤儿
- 骨干选路:jitter 选路 + endpoint-target;relay client/server/wire/identity/directory/rendezvous/switcher 调整
- 工作台 src/web/server.ts、src/worker/relay-tunnel.ts 装配与候选链观测
脚本与测试
- scripts/overlay-{probe,keyring,jitter}.cjs 更新
- 探针新增 OBS-21(每连接候选数)/ OBS-22(teardown 静态守卫 + 认领面)/ OBS-23(组密钥加密)
- 新增 test/{orchestrator-teardown,orchestrator-rehydrate,overlay-content,overlay-jitter}.test.mjs;relay 两例更新
文档
- 新增交接单:覆盖网络-序24-内容分发块级寻址 / 序25-实例逐步拉起 / 序26-骨干稳定选路与加密
- INDEX.md、交接单/README.md、skills/dsh-auto-handoff-chain/SKILL.md 同步
验收(零回归,2026-09-18 08:0x 复核)
- npm test 201 tests / 200 pass / 0 fail / 1 skipped
- overlay-failover-drill --scene all --table 12 PASS / 0 SKIP / 0 FAIL
- overlay-probe --table 23 PASS / 0 SKIP / 0 FAIL (rc=0)
12 KiB
12 KiB
交接单 · 骨干节点落地(稳定高效选路 + 传输可加密)
- 序号:覆盖网络线 序 ㉖ · 规划棒
- 立单:2026-09-17 20:3x
- 用户拍板:「入口 §4 骨干节点的服务范围:按照连接稳定高效的方式 数据安全可加密传输」(2026-09-17 20:2x)
- 上游依据:
覆盖网络_骨干层方案_20260916.md§7(原 A/B 待拍板)/§8 落地顺序/覆盖网络_瓶颈落地方案_20260916.md§4(jitter 是一等指标)/覆盖网络_补遗与参考方案_20260916.md(45% 设计 / 55% 余量口径) - 状态:待执行
§0 摘要 + 我把用户口径翻译成的两条硬判据
用户没有按 A/B 选,而是给了一句目标导向的话:「按照连接稳定高效的方式 数据安全可加密传输」。
⇒ 我的解读(已定项,可推翻):用户要的不是"服务范围"这个二元选择,而是两条可验证的工程质量判据:
| 口径 | 翻译成机器判据 | 与 A/B 的关系 |
|---|---|---|
| 连接稳定高效 | 选路按 jitter 排序(⛔ 不按 RTT)+ 每连接保 2–3 条候选路径 + 中继利用率留 30%+ 余量 + 骨干间心跳 ≤10 成员全互联 | 与 A/B 正交 —— 无论自用还是全网,这条都要满足 |
| 数据安全可加密传输 | ① 传输层加密(wss/TLS 已在,⛔ 不新造)② 内容/信令完整性由签名与哈希兜住(本线已有 relay 签名目录 + 密钥体系)③ 对外只暴露"转发能力",⛔ 不暴露"看到谁连谁"的元数据 | B 档的最大缺点正是"骨干会看到流量元数据" ⇒ 用户这句恰好把 B 档的最大代价按住了 |
✅ 因此我的判定(可推翻):按 "A 起步、口径按 B 的质量标准建设" 落地 —— 即 §7 原倾向 A→B 渐进 与用户口径并不冲突:
- 可见范围仍取 A(只服务自己名下设备):无计费/合规纠纷、权限面不变(⛔ 不命中 R5)、元数据暴露面最小 —— 这直接满足"数据安全";
- 质量与冗余按 B 的标准建设(多中心骨干、jitter 选路、30%+ 余量):这直接满足"稳定高效";
- "可加密" ⇒ 做成能力就位(TLS + 签名 + 内容哈希),⛔ 不在本单引入端到端加密(见 §7)。
§1 目标(可判定"做完了没有")
| # | 判据 | 期望 | 怎么测 |
|---|---|---|---|
| E1 | 选路按 jitter(⛔ 不按 RTT) | 两候选路径中 jitter 更低者被选中,即使其 RTT 更高 | 夹具:候选 A(RTT 20ms/jitter 15ms) vs B(RTT 30ms/jitter 2ms) ⇒ 断言选 B |
| E2 | jitter 可观测 | 每连接有 jitter 直方图 + 超阈值自动切路径并告警 | 判别器计数 + 直方图落盘 |
| E3 | 路径多样性 | 每连接维护 2–3 条候选(直连 / 就近中继 / 备用中继) | /status 可查候选数 ≥ 2 |
| E4 | 利用率留余量 | 中继利用率 ≤ 70%(留 30%+) | used / capacity 可查、超限拒绝新接入(⛔ 不打满) |
| E5 | 骨干互认只校验不自行批准 | 控制面签发资格;骨干间只验签 | 未签名骨干接入 ⇒ 被拒并点名 |
| E6 | 元数据最小化(A 档) | 骨干只知"转发给谁",不知"谁在连谁";跨用户不可见 | 断言跨用户 0 命中(与内容分发的 E5 同族) |
| E7 | 零回归 | npm test 176/175/0/1、--scene all --table 12P/0S/0F、overlay-probe --table 16P/0F/0S |
三件套跑同值 |
§2 只读前置(执行前必须先核实的 5 条)
| # | 要核实什么 | 命令 | 期望 |
|---|---|---|---|
| P1 | 现行 relay 是否已做到"只绑回环 + 443 兜底" | ss -lntp + relay ExecStart |
已实测:两台 relay 均只绑 127.0.0.1:20080、106 复用既有 443 ⇒ 零新增公网口(⛔ 本单不许破坏这条) |
| P2 | 现行选路是按什么排序 | 读 src/net/relay/switcher.ts / directory.ts |
⚠️ 预判:按健康度/冷却,⛔ 不是按 jitter ⇒ 这是本单的主要缺口 |
| P3 | jitter 现测值 | scripts/overlay-jitter.cjs |
已有脚本;序⑥ 实测 p95(|ΔRTT|) = 3 ms(达标)⇒ 本单把"点测"变成"持续采样 + 参与选路" |
| P4 | 骨干"资格"体系现状 | scripts/overlay-keyring.cjs + relay keys 表 |
已有四层密钥模型(离线根 → 在线签名者 → 每机节点密钥 → 会话)+ 逻辑名索引 + 成员资格校验 ⇒ E5 大部分已就位 |
| P5 | 45% 容量口径现值 | 参数表 RELAY_MAX_HOSTS |
实测 7515(序⑥ 重算并已下发两台)⇒ 本单只读不改,⛔ 不动容量值 |
§3 范围
3.1 在册文件集(⚠️ 超出必须先停下报告 — R7)
| 面 | 文件 | 说明 |
|---|---|---|
| 新增 | src/net/relay/jitter.ts |
jitter 采样与直方图(选路的输入) |
| 改动 | src/net/relay/directory.ts |
候选排序:健康度 → jitter 为主序(⛔ 不删既有冷却语义) |
| 改动 | src/net/relay/switcher.ts |
⚠️ 只加"jitter 劣化即切",⛔ 不改冷却语义 |
| 改动 | src/net/relay/server.ts |
利用率守卫(E4)+ 候选路径可查(E3) |
| 改动 | scripts/overlay-jitter.cjs |
点测 → 持续采样 |
| 改动 | scripts/overlay-probe.cjs |
新增 OBS-17(jitter)/OBS-18(余量) |
| 改动 | 参数表_覆盖网络_20260917.md |
新增 JITTER_* / RELAY_UTIL_MAX_PCT 键 |
⛔ 不在本单范围:RELAY_FAILOVER_* 任何值、HB_SEC、burst、switcher.ts 冷却语义、RELAY_MAX_HOSTS、房间层、打洞实现、内容分发的块级实现(另单,见 交接单_内容分发块级寻址_20260917.md)。
3.2 三条硬约束
- 🔴 ⛔ 不改
switcher.ts冷却语义(本线持久禁令)—— 只新增 jitter 触发条件。 - 🔴 ⛔ 不新增公网监听口 / 不改 nft·nginx(R5)—— 骨干仍只绑回环 + 443/TCP 兜底复用。
- 🔴 骨干资格只能控制面签发(权威状态单点 Manager)—— 骨干只校验,不自行批准。
§4 步骤 S0–S6
| 步 | 做什么 | 验证(一次可执行) | 回滚 |
|---|---|---|---|
| S0 | 只读前置 P1–P5 + 基线 jitter 采样(零改动) |
输出 Before:现行选路按什么排序(原文行号级证据) | 无(只读) |
| S1 | jitter 采样与直方图(jitter.ts) |
夹具:喂 3 条已知 jitter 序列 ⇒ 直方图与 p95 逐项可断言 | 删新增文件 |
| S2 | 候选排序改为 jitter 为主序(directory.ts) |
E1:先红后绿(jitter 更低但 RTT 更高的那条必须被选中) |
还原排序函数 |
| S3 | 切换条件新增"jitter 劣化即切"(switcher.ts,⛔ 不碰冷却) |
E2:劣化 ⇒ 切 + 告警;⛔ 冷却语义断言不变 |
移除新增条件 |
| S4 | 利用率守卫 + 候选可查(server.ts) |
E4:利用率 > 阈值 ⇒ 拒绝新接入并点名;E3:候选数 ≥ 2 |
还原守卫 |
| S5 | 骨干互认与元数据最小化复验(E5 / E6) |
未签名骨干被拒并点名;跨用户 0 命中 | 同 S2 |
| S6 | 真机验收 + 观测 + 零回归(E7)+ 收口 |
三件套同值;探针新增 2 项 PASS | 产物回滚点 |
§5 验收判据 E1–E7
见 §1。⚠️ E1 是主判据("选路按 jitter 排序而非 RTT")—— 这一条能不能机器断言,决定了"连接稳定高效"是不是嘴上说说。
§6 回滚(两层)
- 排序级:还原
directory.ts的排序函数 + 移除switcher.ts新增条件 →tsc→ scplib/→restart dshs⇒ 回到"按健康度/冷却"的旧选路。 - 产物级:scp 回滚点
/opt/dsh/backups/seq26-<ts>/lib/net/relay/{directory,switcher,server,jitter}.js。 🔴 ⛔ 回滚路径里不许出现RELAY_FAILOVER_COOLDOWN_MS=0。
§7 安全与加密档位(用户口径的关键落点;属已定项、⛔ 不再上抛)
用户原话:「数据安全可加密传输」。逐条落法:
| 层 | 现状 | 本单怎么做 |
|---|---|---|
| 传输层加密 | ✅ wss / TLS 已在(relay 经 https://alotbuy.com/dshs-relay 可达、双路 101) |
复用,⛔ 不重造。骨干之间同样只走 wss |
| 身份与授权 | ✅ 四层密钥模型已落地(离线根 → 在线签名者 → 每机节点密钥 → 会话)+ 逻辑名索引 + 成员资格校验 + 吊销演练通过 | E5:骨干间只校验,不自行批准(补齐"骨干资格"这一档) |
| 完整性 | ✅ 有签名目录 | 信令与目录全程验签;⛔ 不引入第二套密钥体系 |
| 元数据最小化 | ⚠️ B 档的最大缺点是"看到谁连谁" | E6:A 档可见范围 ⇒ 骨干只知转发目标、不知连接双方;跨用户不可见 |
| 端到端加密(E2E) | ⛔ 不做 | 属真取舍:E2E 会让"每个接收者密文不同" ⇒ 与内容分发的按哈希共享块直接冲突(要加密就失去共享)⇒ 本阶段取 "TLS + 验签 + 内容哈希";E2E 登记为待评估(见 §9-3) |
🔑 一句话:"可加密"= 能力就位(TLS + 验签 + 哈希)+ 元数据最小化,⛔ 不是"现在就上端到端加密"。
§8 回报格式(执行会话必须回填)
### 8.x 序 ㉖ 执行棒回报(YYYY-MM-DD HH:MM–HH:MM)
#### ① S0–S6 逐条(命令 + 原文输出 + 判定)
#### ② 主判据 E1:jitter 更低(但 RTT 更高)的候选被选中
- 候选 A = ? | 候选 B = ? | 实测选中 = ? | 原文 = ?
#### ③ 先红后绿(原文级)
#### ④ 零回归三件套(均带 `--table`)
#### ⑤ 边界自证
⛔ 未改 `switcher.ts` 冷却语义 / ⛔ 未改生产值 / ⛔ 未新增公网口 / ⛔ 未改 nft·nginx / 🔴 `COOLDOWN_MS=0` = ? / ⛔ 未 commit·未 push
#### ⑥ 指纹
参数表 = ?(前值 `42238175d84319ada99afa56d583f9db`)|directory.ts / switcher.ts / server.ts md5 = ?
§9 回头条件(一出现必须回头)
- 要改
switcher.ts冷却语义 ⇒ 停下报告(持久禁令)。 - 要新增公网监听口 / 改 nft·nginx ⇒ 停下报告(R5)。
- 要引入端到端加密(E2E)⇒ 属真取舍(加密即失去按哈希共享块)⇒ 停下上抛。
- 要改
RELAY_MAX_HOSTS/ 45% 容量口径值 ⇒ 停下报告。 - 需要超出 §3.1 文件集 ⇒ 停下报告(R7)。
E1跑不出机器断言 ⇒ 停下报告,⛔ 不许放宽判据凑绿。- 零回归三件套任一退化 ⇒ 停下报告。
- 🔴 ⛔ 不许把
RELAY_FAILOVER_COOLDOWN_MS=0写进任何回滚 / 演练 / 夹具路径。
§10 未验证项
| # | 项 | 状态 |
|---|---|---|
| 1 | 各网络类型实际占比(决定骨干数量需求) | ⚠️ 上游仍为推演设定 |
| 2 | 骨干上行带宽是否够(家宽上行常远小于下行) | ⚠️ 上游未实测 |
| 3 | E2E 加密与块级共享的取舍 | ⚠️ 本单未做,登记待评估 |
§11 指纹与状态
| 项 | 值 |
|---|---|
| 本单 §8 之前正文前缀指纹 | dbcbe633aa1aef92f4c35c77fad3ec11(口径 = sed '/^## §8 /,$d' 交接单_骨干稳定选路与加密_20260917.md | md5sum) |
| 参数表指纹(立单时) | 42238175d84319ada99afa56d583f9db |
| 代码仓 HEAD(立单时) | 04776af |
| 本单全文件 md5(立单时) | f85b86234c2ecfaef5b2e43aa40d86a3(176 行) |
| 本单状态 | 待执行 ⇒ 交序 ㉖ 执行棒 |