Files
blackbird/dnfs2/README.md
T
qing 9b6aa39b94 fix(dnfs2): update_note 成环检测(修复已知限制 L-1)
新增 _is_descendant 祖先走查:改 pid 时从新父节点沿 pid 链逐级向上,
命中自身即拒绝(自引用/移入自身子树均成环,子树不可达);深度上限 64
+ visited 集防存量脏数据死循环,db 错误 fail-closed 抛 500。
README 已知限制 L-1 移入安全修复表。
2026-08-13 04:10:35 +08:00

82 lines
3.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# dnfs2 — C++20 树状网络文件系统
dnfs 的 C++ 重实现,接口与 Python dnfs 完全兼容,修复 P0/P1 安全问题。基于 libhttp + libmsg + boost::json。
## 架构
```
ca :8443 (验签 /whoami,验签通过后经 gateway 转发)
│ Bearer Token
▼
dnfs2 :8006 ──pymsg──► db2 :8005 (execute 路由) ──► SQLite
│ ▲
│ libmsg (RpcClient)
└──HTTP──► ai_review :8007 (内容审核)
```
- **HTTP 服务**: libhttp `HttpServer`(Boost.Beast 异步,多线程)
- **Token 验签**: HttpClient POST ca `/whoami`(CLI 参数 `--gateway-url` 指向 ca:8443),fail-closed(503)
- **数据操作**: libmsg `RpcClient` 调 db2 `execute` 路由
- **内容审核**: HttpClient POST ai_review `/review`,fail-closed
- **异步日志**: libmsg `AsyncQueue` → db2 Logs 表
## 接口
| 路由 | 鉴权 | 说明 |
|------|------|------|
| POST /get_notes | 否(可选 Token,用于 can_operate) | 返回子节点数组 |
| POST /add_note | 是 | 校验 Token → 父节点存在 → AI 审核 → 插入 |
| POST /delete_note | 是 | 校验 Token → 检查子节点 → 所有权 → 删除 |
| POST /update_note | 是 | 校验 Token → 所有权 → 父节点存在 → AI 审核 → 更新 |
请求/响应 JSON 格式与 Python dnfs 完全一致,前端零改动。
## 配置
纯 CLI + 环境变量 + 默认值,不依赖 confs。
| 配置项 | CLI 参数 | 环境变量 | 默认值 |
|--------|---------|---------|--------|
| 绑定地址 | `--host` / `--addr` / `-a` | `LISTEN_ADDR` | 127.0.0.1 |
| 监听端口 | `--port` / `-p` | `LISTEN_PORT` | 8006 |
| 工作线程 | `--threads` / `-t` | — | 4 |
| 数据库地址 | `--db-host` | `DB_HOST` | 127.0.0.1 |
| 数据库端口 | `--db-port` | `DB_PORT` | 8005 |
| 数据库超时 | `--db-timeout` | — | 10 |
| AI 审核URL | `--review-url` | `REVIEW_URL` | http://127.0.0.1:8007/review |
| AI 审核超时 | `--review-timeout` | — | 10 |
| ca 验签URL | `--gateway-url` | `GATEWAY_URL` | http://127.0.0.1:8443/whoami |
| 网关超时 | `--gateway-timeout` | — | 5 |
| 日志级别 | `--log-level` | — | info |
| 实例名 | `--instance` | — | dnfs2 |
优先级: CLI > 环境变量 > 默认值
## 构建
```bash
./_set.sh # 编译
./_run.sh # 运行
```
依赖: libhttp, libmsg, boost::json, OpenSSL, libcurl
## 安全修复(相比 Python dnfs)
| 编号 | 问题 | 修复方案 |
|------|------|---------|
| P0-4 | 父节点删除 TOCTOU + 未检查 success | 统一封装 `_call_db()` 检查 `success` 后再访问 `data` |
| P1-6 | 请求体无限制 | `server.setMaxBodySize(10MB)` |
| P1-7 | log_client 配置不一致 | 日志客户端复用主配置 |
| P1-8 | update_note 改 pid 未校验父节点 | pid≠0 时校验父节点存在 |
| P1-9 | db RPC 未启用启动等待 | `RpcClient(retry_on_refused=true)` |
| P1-11 | note_id 无强制类型转换 | 显式 `as_int64()` + 类型校验 |
| L-1 | update_note 允许创建循环 | `_is_descendant` 祖先走查:拒绝新父节点为自身或位于自身子树内(深度上限 64,防存量环死循环) |
## 已知限制(P2,设计决策不修复)
- L-2: delete_note TOCTOU 残余(需 db2 事务支持)
- L-4: 无速率限制(gateway/WAF 职责)
- L-5: title/content 无最大长度校验
- L-6: AI 审核不可用时阻断写入(fail-closed 设计决策)