Files
go-sip/docs/evidence/20260919-sip-routing-implementation-comparison.md
T

34 lines
5.2 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.
# SIP 注册、认证、主叫、前缀与选路对比(2026-09-19)
## 结论
本记录只对比父目录既有生产验证实现与 `sip-go-agent` 当前 Go 实现,不把 Mock、SIPp 探测或收到临时 SIP 响应称为生产验收。当前 Go Agent 尚未实现 SIP 注册、SIP Digest/IP 鉴权、Asterisk/ARI 呼叫建立或 `From`/`P-Asserted-Identity`(PAI)生成;这些能力仍必须由批准的 Cell/Asterisk 运行面和版本化路由制品提供。
父目录实现可以证明“配置和受控调用路径如何表达线路”,不能证明供应商已授权、已接通、已收 RTP 或已生成最终录音。
## 对比表
| 项目 | 父目录生产验证实现 | 当前 `sip-go-agent` | 结论/后续门禁 |
| --- | --- | --- | --- |
| SIP 注册 | `deploy/asterisk.three-sip.json` 的三条线路均为 `register: false`;`real_cell.py`/`cell_worker_main.py` 通过已配置的 Asterisk/ARI 呼叫,不在 Python Cell 内执行注册。 | Go Agent 只有 mTLS Unary gRPC 会话;没有 SIP 注册客户端或注册状态机。 | 当前不能声称支持供应商注册。后续按供应商确认的 IP 直连或注册模式实现,不能臆造备用注册。 |
| SIP 认证 | 当前三条线路是 IP 白名单模式;生成配置保留 trunk 的服务端和 `from_user`,Digest trunk 没有受控 secret resolver 时被拒绝。认证实际由 Asterisk/PJSIP 执行。 | Go 代码没有 SIP 用户名、密码、Digest、Contact 或注册凭据字段;Dispatcher 也不会把凭据下发到任务。 | 这是正确的边界,但认证能力尚未迁移/验收。凭据仍只能由部署受控注入,不能写入任务、日志或契约。 |
| `From`/主叫 | `cell-routes.three-sip.json` 将 `caller_profile_id` 绑定到受信 `caller_id`;`real_cell.py` 只把受信 caller ID 传给 ARI `callerId`。Asterisk renderer 将 provider caller identifier 写入 trunk 的 `from_user`/callerid 相关配置。 | `call.execute` 只携带 `caller_profile_id` 和 `route_policy_id`;Go 没有 SIP URI/header 生成,也没有 caller profile 到 `From` 的映射。 | 必须以管理平台发布的 caller profile 为唯一来源;不能让任务注入任意主叫。 |
| PAI | 父目录搜索/renderer 没有独立 `send_pai` 或应用层 PAI 注入实现;探测脚本中的 `From`/PAI 候选只证明探测包内容,不能证明 Asterisk 最终 PAI 映射。 | 当前 Go 没有 PAI 代码或字段。 | 需供应商确认 `From`、`PAI`、`Remote-Party-ID` 等要求,并用抓包验证最终 INVITE;未确认前标 unknown/未启用。 |
| 被叫原值与前缀 | 线路映射为:数企 `trunk=数企`、`caller=BD93205882`、`prefix=7089`;中鼎 `mbkq`、无前缀;百应 `KQ91526`、`prefix=mka755`。`real_cell.py` 从原始业务号码构造选中线路的有效目标,不把上一线路前缀带入下一线路。 | Go 持久化原始 `callee`、`route_policy_id`、`caller_profile_id`,没有 SIP 目标构造或供应商前缀应用。 | 前缀只能由受信 route policy 应用一次;任务不得预先混入 `7089`/`mka755`,也不得跨线路复用。 |
| 线路选路 | 父目录使用受信 route map:`route_policy_id + caller_profile_id` 绑定 trunk、caller 和 prefix;payload 不能注入 SIP 地址、凭据或主叫。 | Dispatcher 只做任务、租约、配额和 Agent 选择;Go Agent 尚未加载 SIP trunk/Cell route 表,也不执行 trunk 选路。 | 选路必须在批准的静态 Cell artifact/本地 route table 中完成,并在实际呼叫前核验版本、准入和资源租约。 |
| 编解码/媒体 | 三条配置只允许 PCMA(Asterisk `allow=alaw`);父目录测试覆盖配置渲染、ARI/RTP guard 和 signaling probe。 | `internal/media` 目前只有 Pion RTP `PacketGuard`,不建立 SIP/RTP 会话。 | PacketGuard 不是 SIP/RTP 生产验收;仍需真实线路 `200 OK`、双向 RTP、录音和 AI 链路验证。 |
## 证据边界
- 对照来源:`../deploy/asterisk.three-sip.json`、`../deploy/cell-routes.three-sip.json`、`../deploy/render_asterisk.py`、`../agent_call/real_cell.py`、`../agent_call/cell_worker_main.py`、`../tests/test_real_cell.py`。
- 父目录测试主要是 Mock Asterisk/ARI、配置渲染和受控 signaling probe;已登记的真实探测没有得到最终 `200 OK`、RTP 或录音,因此不能作为供应商接通验收。
- 当前 Go 来源:`internal/contract`、`internal/dispatcher`、`internal/rpc`、`internal/media`。其中 `internal/rpc` 的 mTLS/session fencing 与 SIP 认证无关,不能混称为 SIP 认证。
- 父目录源和本项目均可能处于 dirty workspace;本记录是实现差异清单,不是外部契约发布、生产批准或真实拨号授权。
## 下一步门禁
1. 先冻结 Cell route artifact:trunk、IP/注册模式、codec、caller profile、`From`/PAI 规则、前缀和出口绑定。
2. 由 Asterisk/官方或成熟 SIP/ARI 组件实现协议栈,Go 只实现授权、路由、状态、幂等和薄适配,不从零重写 SIP。
3. 对每条线路分别验证原始被叫、前缀、主叫、最终 From/PAI、SIP 状态、RTP、录音和结果;任何线路未得到最终接通都保持未验收。
4. 真实呼叫仍仅限已批准的白名单号码和单独授权窗口;本记录不扩大拨号授权。