摘要

  • RFC 3435 要求每个端点在任一时刻只有一个 NotifiedEntity,但它只决定网关发出的命令送往哪里;对收到命令的响应仍返回该命令的来源地址。
  • 备用呼叫代理可以改写去向,却没有因此获得跨控制器冲突解决、完整状态转移或媒体不中断的证明;审计、清除连接、可达、授权与用户结果是不同凭据。

指针动了,交接未必完成

设想一个接入网关失去与呼叫代理的联系。备用代理来到端点前,写入新的 NotifiedEntity。从此,网关知道下一条 Notify 或 RestartInProgress 应送往哪里。这个动作真实而重要,却没有自动复制旧代理的连接记录,也没有消除旧代理恢复后可能出现的竞争状态,更没有说明语音仍在双向传输。

RFC 3435 在 2003 年 1 月修订 MGCP 1.0 时,把这种边界写进协议。它的纯文本版本、RFC Editor 条目、IETF 文档页、历史记录、引用关系与勘误页能够证明规范文本和过程,却不能证明某家产品部署过它,更不能证明一次现实故障切换成功。

MGCP 把系统拆成两个责任面:呼叫代理保存呼叫控制“智能”,媒体网关处理媒体并暴露端点。代理可以创建、修改、删除连接,请求事件检测与信号,并审计端点和连接。RFC 2705是被 RFC 3435 取代的早期版本,它已经假设多个代理会彼此同步,却没有定义同步机制。RFC 2805记录 IETF 对媒体网关控制的总体要求;RFC 3015则描述 IESG 注释所指向的 Megaco/H.248 标准路线。RFC 3435 本身是信息类文档,细密的 MUST 不等于互联网标准地位、普遍采用或服务效果。

被通知实体究竟保存什么

RFC 3435 规定,每个端点在某一时刻关联一个且仅一个呼叫代理。当前被通知实体决定网关把自己发起的命令送往何处。呼叫代理携带的 NotifiedEntity 参数会更新端点保存的值。

若从未收到显式值,就使用预配置默认值。如果默认值也不存在而参数为空——规范强烈不建议这样配置——最近一条非审计命令的来源地址成为被通知实体。审计命令本身不会暗中夺取这个指针。

但响应遵循另一条规则:无论当前被通知实体是谁,响应都返回触发它的命令来源。若响应与 Notify 放在同一数据报,仍发往该来源。规范还说明,网关接收的命令可能来自任何来源。于是至少有四张不可合并的收据:网关命令的当前目的地、某条命令的网络来源、返回该来源的响应,以及该来源是否拥有合法控制权。

RFC 2119的规范用词与RFC 2234的 ABNF 语法能使线上行为精确,却不能凭空补出控制器之间的授权协议。

DNS 只能扩大可达面

呼叫代理用域名和可选端口标识,而不是绑定一条 IP 地址。一个名称可以解析到多个接口,也可以代表由多台机器组成的逻辑代理。网关若联系当前地址失败,就应尝试其他地址;故障切换不能依赖 DNS 返回顺序。

这种间接层解决的是可达性。一台机器能接收数据包,并不证明它与另一台机器拥有同一份连接数据库、同一事件顺序和同一授权判断。域名解析、地址可达、逻辑身份、状态复制与控制权需要各自证据。

当整个代理持续不可达,端点最终进入 disconnected 状态。备用代理可以通过新被通知实体接触这些端点。规范假定故障代理与备用代理会通信并同步,以便日后归还控制权,或者交换主备角色。紧接着,它坦率说明:不同呼叫代理之间没有交接冲突解决机制,协议依赖代理知道自己在做什么并彼此沟通。

AuditEndpoint 可以读到当前被通知实体,却不能证明最后一次写入的授权,也不能复原每次控制决定。数据库里只有一个当前值,不等于分布式系统已经就这个值的来历达成共识。

断联之后有两条不同道路

端点不会因丢一个包就宣布断联。MGCP 使用重传、指数退避、备用地址、DNS 刷新与时间上限。T-MAX 限制继续重传的时间;超过两倍 T-HIST 后,端点进入 disconnected。随机等待避免大量端点同时掀起恢复风暴。

断联后,呼叫代理看到的第一条非审计交互必须携带这个状态。代理得知后,可以审计端点,也可以直接清除端点的全部连接。审计试图从协议可见记录中对账;清除则通过删除制造收敛。两者不是同一件事,也不能证明媒体未曾中断。

一次 RestartInProgress 成功响应只证明该协议事务完成。RFC 3661后来澄清 MGCP 返回码的用法,但更清楚的返回码仍只覆盖其规定动作,不覆盖听众是否听见声音、状态是否无损或控制权是否正当。

RFC 3991增加重定向与重置包,RFC 3992为有限的通知交互定义 lockstep 状态报告。它们收窄特定不确定性,却没有把基础指针改造成控制器选举协议。IANA 的MGCP 包注册表和本地连接选项注册表证明名称得到协调,不证明实现、部署或切换效果。

不让去向借走权威

RFC 3435 的历史价值,在于它没有把 failover 写成一个瞬间。目的地改变、地址响应、控制器接收断联通知、审计返回状态、清除命令成功、媒体恢复,都是不同事件。任何一个先发生,都不能替其余事件作证。

Heng Lu 后来关于现实层与符号权力的讨论,提醒我们不要让醒目的当前指针借走它并不包含的权威;运行代码优先的观点要求把规范设计和实际结果分开;最小初始规范则解释了共同内核为何可以只协调去向,把更复杂的冲突处理留给未来。这些都是 Sofia Ren 的后见分析,不是对 RFC 作者动机的宣称。

被通知实体必须存在,因为网关需要知道下一条命令送给谁。它仍然不够,因为真正的连续性还需要授权、状态同步、冲突仲裁和媒体观察。一个指针是操作杠杆,不是完整账本。

来源