好的,专家讲师。我将继续为您撰写 SIP 协议深度解析系列的第十一篇。本篇将聚焦于 IMS 网络中会话状态的维护与信令完整性校验,特别是 P-CSCF 如何利用严格的路由和对话标识校验机制来防范异常和错误,并通过返回特定的状态码(如 403, 481, 400)来指导终端和核心网元进行状态同步。
VoLTE高清语音技术精要(十一):IMS对话完整性与P-CSCF状态管理:403、481与路由校验
1. 导论:从会话锚定到状态完整性维护
在前面的篇章中,我们详细探讨了 SIP 协议如何通过 REGISTER 流程使用 Path 和 Service-Route 锚定 P-CSCF 和 S-CSCF 之间的路由关系。一旦用户注册成功并建立了会话(Dialog),网络的首要任务就转变为维持这个会话状态的完整性,确保所有后续的信令交互(如 BYE, UPDATE, Re-INVITE)都属于合法的、已建立的会话,并且沿着正确的路径进行。
在 IMS 架构中,**P-CSCF(代理呼叫会话控制功能)**是实现这一目标的关键“守门员”。P-CSCF 必须保存大量的会话状态信息(包括 Call-ID、From-tag、To-tag、Contact 地址、CSeq 序列号和 Record-Route 列表),并严格校验终端(UE)发来的每一个后续请求。
本章将深度剖析运营商规范(主要参考某运营商和某运营商)对 P-CSCF 状态校验的严苛要求,特别是针对 Route 列表的匹配机制,以及在异常情况下 P-CSCF 返回的关键错误状态码(400 Bad Request、403 Forbidden、481 Dialogue/Transaction Does Not Exist)背后的逻辑和处理目的。
2. 后续请求的路由校验核心:Record-Route与Route的匹配
SIP 协议的稳健性依赖于对话建立时确定的路由路径。Record-Route 记录了路径,而 Route 则指导后续对话内请求的转发。P-CSCF 必须确保这两个列表的一致性。
2.1 目标刷新请求的严格校验
目标刷新请求(Target Refresh Request),如 reINVITE 或 UPDATE,用于在已建立的对话中修改会话参数(如 SDP、Session Timer)或更新终端的 Contact 地址。由于这些请求涉及会话状态的变更,P-CSCF 的校验最为严格。
| P-CSCF 职责 | SIP 头域/参数 | 详细操作要求 | 来源 |
|---|---|---|---|
| 路由一致性校验 | Route / Record-Route | P-CSCF 收到 UE 发起的 reINVITE 或 UPDATE 请求时,应确认请求中的 Route 列表是否与同一对话中保存下来的 Record-Route 列表匹配。 | |
| 状态更新 | Contact / CSeq | 如果路由校验成功,P-CSCF 应用请求消息中的 CSeq 字段的值替换原来保存的值,并应用请求消息中的 Contact 头字段的值替换原来保存的值。 | |
| Via/Record-Route 更新 | Via / Record-Route | P-CSCF 必须在 Via 头域最顶端增加 P-CSCF 的地址并保存该列表。 |
注意: 如果路由校验失败(即 Route 列表与保存的 Record-Route 列表不匹配),P-CSCF 应回复 400 (Bad Request) 响应且不再继续处理请求。
2.2 其他后续请求的校验
对于 UE 发起的除目标刷新请求以外的后续请求(例如 BYE, PRACK, 或与当前对话相关的未知方法),P-CSCF 也必须进行校验:
- 对话关联确认:P-CSCF 应该确认这个请求是否和一个涉及该请求的发起者的对话有关。
- 路由匹配:P-CSCF 应该确认请求中的 Route 列表是否与同一对话中保存下来的 Record-Route 列表匹配。
- CSeq 更新:对于
INVITE对话,P-CSCF 应该用收到的请求消息中的 CSeq 字段的值替换原来保存的值。 - 计费信息:对于非
INVITE对话(如MESSAGE),P-CSCF 应在P-Charging-Vector中增加 icid 参数。
3. P-CSCF 终结侧请求的状态维护(MT INVITE)
P-CSCF 在处理发往 UE 的对话初始请求(UE 终结的请求,如 MT INVITE)时,同样需要执行复杂的路由信息转换和保存,以便后续的对话内请求能够正确路由。
| P-CSCF 职责(MT 初始请求前) | 详细操作要求 | 目的 | 来源 |
|---|---|---|---|
| Route 转换 | 转换 Record-Route 列表信息到 Route 列表信息中,并保存 Route 列表。 | 告知 UE 后续请求应遵循的路径。 | |
| 对话状态保存 | 如果请求为 INVITE,P-CSCF 应保存请求中的 Contact、CSeq 和 Record-Route 字段并备份。 | 维护对话上下文,用于后续校验和更新。 | |
| 路径记录 | 将 P-CSCF 的 SIP URI 填加到 Record-Route 头域最顶端并保存列表。 | 锚定 MT 呼叫的返回路径,确保 P-CSCF 参与后续所有信令。 | |
| Via 记录 | 将 P-CSCF 地址填加到 Via 头域最顶端并保存该列表。 | 指导响应消息原路返回。 | |
| 计费/身份处理 | 删除并保存 P-Charging-Function-Addresses 和 P-Charging-Vector 中的 icid,并备份 P-Called-Party-ID。 | 避免敏感信息透传给 UE,并为后续计费和身份断言做准备。 |
当 P-CSCF 收到上述请求的任何响应时,P-CSCF 均应确认 Via 列表是否与同一对话的请求消息中保存的 Via 列表匹配。
4. 异常情况处理:400、403 与 481 的区别
P-CSCF 必须对不同类型的异常请求返回精确的 SIP 状态码,这些状态码指示了信令失败的原因是语法错误、权限不足还是状态不匹配。
| 状态码 | 含义 | 触发场景 | 目标 | 来源 |
|---|---|---|---|---|
| 400 Bad Request | 请求语法或结构错误。 | Service-Route 校验失败:P-CSCF 收到 UE 始发请求,发现 Route 列表与保存的 Service-Route 不匹配。 | 拒绝非法或路由错误的请求。 | |
| 403 Forbidden | 权限或对话不存在。 | P-CSCF 收到 UE 发起的后续请求或独立请求,但没有发现存在对应的对话。 | 拒绝与任何当前会话无关的请求,防止状态混乱和非法注入。 | |
| 481 Dialog/Transaction Does Not Exist | 对话或事务已失效或正在释放。 | 会话释放过程中:P-CSCF 在释放对话的过程中收到关于对话的请求。或 S-CSCF 发起会话释放时,收到该会话的其他请求。 | 告知发送方该对话已终止,停止相关信令。 |
4.1 路由校验失败(400 Bad Request)
当 UE 始发请求(如 INVITE, MESSAGE)中的 Route 列表与注册时 S-CSCF 返回并保存在 P-CSCF 的 Service-Route 列表不匹配时,P-CSCF 视为路由信息被篡改或错误。
- 处理方式:P-CSCF 应回复
400 (Bad Request)响应且不再继续处理请求。 - 替代选项:在某些配置中,P-CSCF 应支持用最新注册消息中的 Service-Route 头替换请求消息的 Route 头,然后继续转发。
4.2 对话状态丢失(403 Forbidden)
如果请求的 Call-ID、From-tag、To-tag 无法在 P-CSCF 的内存中找到对应的会话上下文,即没有发现存在对应的对话,P-CSCF 必须拒绝该请求。
- 处理方式:P-CSCF 应回复
403 (Forbidden)响应,且不再转发该请求。这是对核心网元的保护机制,防止非法的或已释放会话的信令进入核心网。
4.3 释放过程中的冲突(481 Dialog/Transaction Does Not Exist)
当会话处于释放状态(例如,P-CSCF 正在向两侧发送 BYE,或会话定时器已超时),此时如果 P-CSCF 再次收到与该会话相关的请求(如 UPDATE 或另一个 BYE):
- P-CSCF 动作:P-CSCF 应该中止该请求,并回送响应
481 (对话或者事务不存在)。 - S-CSCF 动作:同样,当 S-CSCF 发起会话释放时(如网络内部发起的释放 或会话定时器超时),如果又接收到该会话的其他请求消息,S-CSCF 应终止接受请求并返回一个
481响应。
5. P-CSCF 的会话释放与资源清理
SIP 会话的可靠释放是 IMS 网络的关键要求,任何残留的会话状态(“幽灵会话”)都可能导致资源泄漏和计费错误。
5.1 释放的触发与处理
会话释放由多种因素触发,P-CSCF 在其中扮演着清理者的角色:
| 释放触发源 | P-CSCF 动作 | S-CSCF 动作 | 来源 |
|---|---|---|---|
| 收到 BYE 请求 | 收到对应当前对话 BYE 请求的 2xx 响应时,应删除保存的所有与该对话相关的信息。 | 收到 BYE 的 2xx 响应时,应释放所有的与对话相关的信和多媒体会话相关的信息。 | |
| 内部原因 | 申请资源失败(如 NAT 端口申请失败、QoS 授权申请失败等)时,P-CSCF 应向 UE 发送 CANCEL 消息以释放会话,并包含原因值为 503 (Service Unavailable)。 | ||
| 会话超时 | 如果 P-CSCF 要求会话定时刷新,一旦会话定时器超时,P-CSCF 就应删除和这个会话相关的信息,并向主被叫两侧发送 BYE 请求。 | 会话定时器超时后,S-CSCF 应删掉所有与该对话相关的保存了的信息。 | |
| SA 删除 | 当用户的安全关联(SA)已经被删除,如果仍有和这个用户有关的对话处于活动状态,P-CSCF 应丢弃所有与这些对话相关的信息。 |
5.2 计费与承载释放的协同
会话释放也必须同步通知底层承载网络和计费系统:
- P-CSCF PCRF/PCF (STR):语音呼叫结束,UE 发送
BYE消息。P-CSCF 收到应用会话终止消息(即BYE)后,会向 PCRF 下发 **STR(Session-Termination-Request)**消息,请求释放承载会话。 - PCRF PGW (RAR):PCRF 收到 STR 后,会发送 RAR 消息(携带 REMOVE QoS Rules 指示)通知 PGW 删除专有承载。
- P-CSCF/S-CSCF CDF (ACR [Stop]):P-CSCF 和 S-CSCF 在收到
BYE请求后,会向各自的 CDF 发送 ACR [Stop] 消息,关闭会话 CDR。
6. 信令日志实战分析:P-CSCF 的异常处理
我们通过一个实际的异常场景,来观察 P-CSCF 如何执行其严格的校验和异常响应。
场景: 用户 A 在通话结束后(对话已通过 BYE 释放),错误地再次发送了一个与该对话标识相同的 UPDATE 请求。P-CSCF 已将该对话状态删除。
6.1 步骤 1:UE 发送 UPDATE 请求(属于已释放对话)
假设该 UPDATE 请求携带了 Call-ID=XYZ,From-tag=A1,To-tag=B1,这些标识对应一个已释放的会话。
UPDATE sip:pcscf.visited.net SIP/2.0
Via: SIP/2.0/UDP [UE_IP]:5060;branch=z9hG4bKerrortrans1
Call-ID: [email protected]
From: <sip:[email protected]>;tag=A1
To: <sip:[email protected]>;tag=B1
CSeq: 10 UPDATE
Route: <sip:scscf.home.net;lr> // 假设该 Route 列表与 Service-Route 匹配
Max-Forwards: 70
...
6.2 步骤 2:P-CSCF 收到请求并执行校验
P-CSCF 收到此 UPDATE 请求后,进行对话存在性检查。
- 检查 Dialogue ID:P-CSCF 搜索本地保存的会话状态信息(基于 Call-ID, A1, B1)。
- 结果:由于对话已被释放,P-CSCF 没有发现存在对应的对话。
6.3 步骤 3:P-CSCF 返回 403 Forbidden 响应
P-CSCF 终止请求处理,并向 UE 返回 403 Forbidden 响应。
SIP/2.0 403 Forbidden
Via: SIP/2.0/UDP [UE_IP]:5060;branch=z9hG4bKerrortrans1;received=[UE_IP];rport=5060
From: <sip:[email protected]>;tag=A1
To: <sip:[email protected]>;tag=B1
Call-ID: [email protected]
CSeq: 10 UPDATE
Content-Length: 0
分析要点: P-CSCF 拒绝转发该请求。如果该请求是发生在 P-CSCF 正在释放对话的过程中(例如,P-CSCF 刚刚向两侧发送 BYE),则 P-CSCF 应返回 481 Dialog/Transaction Does Not Exist。这种细微的差别体现了 P-CSCF 对会话状态机的精确控制。
7. 本章小结
P-CSCF 在 IMS 体系中充当着会话状态的严格守护者:
- 状态锚定:P-CSCF 维护着会话的完整上下文,包括
Contact、CSeq和Record-Route列表,并对所有后续请求进行校验和更新。 - 路由校验:对于目标刷新请求,P-CSCF 必须严格校验
Route列表是否与保存的Record-Route列表匹配,失败则返回400 Bad Request。 - 异常响应:
403 Forbidden:用于拒绝无法关联到任何已知会话的非法请求。481 Dialog/Transaction Does Not Exist:用于终止在会话释放过程中发生的信令冲突。
- 资源清理:会话释放流程(如收到
BYE 2xx、会话超时、SA 删除)必须触发 P-CSCF 删除所有对话和多媒体会话相关的信息,并同步通知底层承载网(通过 STR 消息释放承载会话)和计费系统(通过 ACR [Stop] 关闭 CDR)。
工程师进阶思考 (FAQ)
Q1:IMS 呼叫中,P-CSCF 何时会返回 100 (Trying) 响应?它与 183 Session Progress 有何本质区别?
A1: P-CSCF 应给所有的 INVITE 请求回送 100 (Trying) 临时响应。P-CSCF 也可以对 reINVITE 请求返回 100 (Trying) 临时响应。
100 Trying:这是一个逐跳(hop-by-hop)的临时响应,用于通知 UAC 或下一跳代理请求已被接收且正在处理,目的是阻止 UAC 在 SIP 定时器 A 超时后重传INVITE。它不携带 SDP,不参与媒体协商。Proxy 不会转发100 Trying响应。183 Session Progress:这是一个端到端(end-to-end)的临时响应,通常携带 SDP Answer,用于早期媒体协商,并触发专用 QoS 流的建立。它往往需要100rel机制的保障,并通过PRACK进行确认。
Q2:在 P-CSCF 容灾接管的主叫流程中,如果终端在 Timer B 内未收到响应,终端应采取什么行动?在 S-CSCF 容灾接管的始发流程中,P-CSCF 又应如何处理?
A2:
- P-CSCF 容灾:某运营商规范要求,终端向已注册 P-CSCF/BAC1 发起
INVITE请求,如果在相应的定时器内Timer B没有收到 P-CSCF/BAC1 的响应消息,终端应结束当前呼叫,当前呼叫失败。随后,终端重新向优先级别次低的 P-CSCF/BAC2 发起初始注册流程,注册成功后,后续的INVITE请求按正常流程处理。 - S-CSCF 容灾:如果 P-CSCF/BAC 转发请求至 VoLTE 终端已注册的 S-CSCF1,但没有收到 S-CSCF1 返回的任何响应,P-CSCF/BAC 会启动 SIP 启发式链路检测,确认 S-CSCF1 故障。P-CSCF/BAC 此时应向 VoLTE 终端返回
504响应,并在消息体中 XML 的<alternative-service>的<type>设为restoration,<action>设为initial-registration,通知终端进行重新注册。
Q3:IMS 呼叫建立过程中,I-CSCF、P-CSCF 和 S-CSCF 各自创建的 CDR(话单)类型和触发时机有何不同?如何关联?
A3: 这三个 CSCF 都会创建 CDR,但类型和时机不同,它们通过 P-Charging-Vector 中的 ICID 进行关联。
| 网元 | CDR 类型 | 触发时机 | 消息发送 | 来源 |
|---|---|---|---|---|
| I-CSCF | 事件 CDR (ACR [Event]) | 收到 INVITE 消息后,进行 HSS Cx 查询后。 | Accounting Request [Event] | |
| P-CSCF | 会话 CDR (ACR [Start]) | 收到 INVITE 消息的 200 OK 最终响应后。 | Accounting Request [Start] | |
| S-CSCF | 会话 CDR (ACR [Start]) | 收到 INVITE 消息的 200 OK 最终响应后。 | Accounting Request [Start] |
会话修改(UPDATE/reINVITE)时,P-CSCF 和 S-CSCF 会发送 ACR [Interim] 消息,更新 CDR。会话释放(BYE)时,两者发送 ACR [Stop] 消息,关闭 CDR。