Files

7.5 KiB
Raw Permalink Blame History

单通外呼线路测试

独立程序 sip-call,只复用项目包,不进入 Agent/Dispatcher 业务流程。不接 SaaS、MQ、AI、OSS,不录音,不排队、不重拨、不换线。

使用

make build-sip-call
cp cmd/sip-call/sip.env.example sip-xx.env
chmod 600 sip-xx.env
# 填写服务商确认的线路参数及本机 Asterisk 路径后执行:
./dist/sip-call sip-xx.env 18601010101
# 需要本通抓包与 SIP/RTP 证据时:
./dist/sip-call -D sip-xx.env 18601010101

命令格式为 sip-call [-D|--debug] <线路.env> <原始号码>,不再支持 call 子命令或 --sip 参数。--debug 与 -D 等价。环境安装统一预装 tcpdump/tshark(生产与测试相同);预装不等于开启抓包。默认模式不调用或检查这些工具;调试模式要求两者可执行、指定接口可抓包且权限充分。调试抓包未就绪或在 Dial 前已退出就不拨号。参数后的号码是原始号码,仅添加该文件声明的前缀一次;不要自己先加线路前缀。

命令会真实拨号。每次执行都须另获线路和号码的明确授权;本文示例不是授权。 独立工具已另经使用者批准部署到登记测试机;没有执行真实试拨。

运行条件

  • 在已有原生 Asterisk 的主机运行;已有 asterisk.conf、0600 的 pjsip.conf、原生 PJSIP/ARI 模块及私有 ari-secret。
  • pjsip.conf 须预先配置且仅配置一次 #tryinclude sip-call-managed.conf。这是主机的一次性准备;工具不会自动补写,缺少或重复入口就拒绝执行。该临时文件不存在时,Asterisk 正常忽略此入口。
  • 以 Asterisk 配置的所属用户运行(登记测试机为 rogee),不要 sudo sip-call。root 或文件归属不匹配会在创建结果、抓包及改配置前明确拒绝;不自动改归属或放宽权限。
  • 使用现有本地 ARI 用户 go-sip-agent 和已配置的 loopback HTTP 地址;密码只从 ASTERISK_CONFIG_DIR/ari-secret 在内存读取,不复制到 ENV 或结果。
  • 已有静态 go-sip-udp UDP transport,绑定 0.0.0.0:5060;工具不更改静态 transport,不启动/重启 Asterisk。
  • 不存在活动通话,且业务调用方、Agent/其他 ARI 应用已停止。工具拒绝接管业务应用;采用独立 sip-call ARI 应用及 siptest-<SIP_ID> endpoint。
  • 只支持 IPv4、UDP、IP 鉴权、无需 REGISTER、PCMA(alaw)。其他方式明确拒绝,不猜测配置。
  • ENV 为 0600 普通文件;结果目录为 0700。所有配置项见 sip.env.example;不读取 shell 环境覆盖线路,也不执行 source。

调试抓包权限

主程序不提权。Linux 主机安装人员可仅为 tcpdump 设置抓包能力,生产与测试按同样方式准备:

sudo setcap cap_net_raw,cap_net_admin=eip /usr/bin/tcpdump
/usr/sbin/getcap /usr/bin/tcpdump

先确认该路径是主机实际安装的 tcpdump;不对 sip-call、tshark 或整个目录设置能力。普通用户仍使用前述不带 sudo 的 -D 命令。权限不足时不拨号、不回退到无抓包模式,输出“已请求,但未启动”;具体启动错误保留在本次私有 tcpdump.log。

自动配置与退出

取得该 Asterisk 配置目录的独占测试锁,确认空闲和固定入口已准备后,只创建本次专用 sip-call-managed.conf,其中包含独立 endpoint/AOR。工具不改写、不备份 pjsip.conf,也不修改原有业务线路;输入的 SIP.env 只读且保留。使用原生 module reload res_pjsip.so 并核对明确的成功响应,不依赖可选的 pjsip reload 别名,不把 CLI 退出码 0 当作加载成功;随后核对实际服务地址、主叫、codec、transport 和 context。通过才执行一次原生 ARI Dial。

收到真正的 Up 和 StasisStart 才记录接通;按 HOLD_SECONDS 保持后挂断。观察到通道结束或挂断后的 ARI 404 才记录结束确认。正常结束后,仅删除本次专用配置、reload 并确认 endpoint 和 AOR 均已移除,不改 go-sip-managed.conf 或业务 SIP 加载代次。临时文件使用原配置的所属用户/组和 0600;清理前核对原配置及临时文件的内容、归属和权限,reload 后再次核对原配置,发生变化则明确报错,不覆盖或删除变化后的文件。

已有 sip-call-managed.conf、并发配置修改或未知通道状态均报错。无法确认结束时保留临时配置及本次结果/证据供人工排查,不要直接重跑或自行清理。清理、抓包停止或证据解析失败都保留错误并以非零退出,不报告“全部正常”。

~/sip-call/tool-backups/ 是安装时保存的旧版工具和来源清单,不是 SIP 配置备份,也不是拨号必需目录。本次修改不删除这些旧工具或任何历史证据。

输出与证据

归属与输入检查通过后创建独立私有目录,此后的成功或失败均有 result.json(检查未通过时不创建结果):线路、服务地址、主叫、原始/线路被叫、SIP Call-ID、拨号前绑定时间、接通时间、结束确认时间、最终状态及失败原因。

开启调试后另有:

  • capture.pcap 与 SHA-256:只抓指定 SIP 服务端 IP 的 UDP,避免复制其他主机流量。
  • tcpdump.log:本通抓包工具的启动/退出信息。
  • sip.tsv:真实 tshark 按本通 Call-ID 解出的 SIP 时间线;最终响应进一步匹配原始 INVITE 的 CSeq 与 Via branch,不能把 BYE 的 200 当作接通。
  • rtp.tsv:依据该通 SDP 音频端口识别的 RTP 包及字节;结果明确记录观察范围。

SIP 服务端与媒体服务器使用不同 IP 时,这个窄过滤器不覆盖另一个媒体 IP;未观察到 RTP 不能据此断言无媒体。裸线路测试不发送合成语音、不验证双向音质,RTP 包存在也不等于语音/AI 正常。

调试模式观察到原生接通但没有同一原始 INVITE 的真实 2xx 最终响应时,保留原生接通/结束事实,同时明确报告抓证失败,不给出完整成功结论。

未开调试时只报告原生通道事实,不编造 SIP 状态码、媒体事实或抓包证据。原始抓包可能含用户音频,配置副本也须私密保存;不要复制到聊天、普通日志或 Git。

Agent 的调试参数

sip-go-agent agent --mode nonprod-real --capture

普通 Agent 默认不依赖 tcpdump,不校验外部抓包凭证。--capture 则复用 nonprod-call-evidence.sh:脚本提前开启抓包与 PJSIP logger,Agent 核对 AGENT_EVIDENCE_ROOT 下绑定本通 event/线路/原始号码的活跃凭证。调试条件缺失拒绝拨号;脚本不会因为新增参数而自动启动。

--capture 仅属于 Agent,Dispatcher 不接受。Dispatcher、Agent 的 --debug/-D 均只开启详细日志,不与抓包联动;独立 sip-call 的 --debug/-D 仍保留本文原有抓包含义。业务授权、任务/线路时段、额度和 HEP 原生 SIP 响应采集规则未取消;没有 tcpdump 不等于绕过业务门禁。

本地验证范围

单元测试覆盖参数、ENV、一次拨号、无 AI/ExternalMedia/bridge、失效抓包、异常恢复、未知结束和原始 INVITE 关联。额外使用网络禁用的临时 Debian 容器中真实 tcpdump/tshark 离线解析合成 pcap,可用 GO_SIP_TSHARK_TEST_IMAGE 显式启用对应测试。

这些测试没有向真实线路发送 SIP,也不能证明已接通、媒体可用或生产可发布。