严格路由 vs 松散路由
2026/7/23 18:50:37 网站建设 项目流程

Kamailio 里的“严格路由”和“松散路由”本质上是 SIP Route/Record-Route 机制的两种模式,分别来自较老的 RFC 2543 和较新的 RFC 3261。现在实际生产中几乎都使用松散路由。


1. 核心区别

对比项严格路由 Strict Routing松散路由 Loose Routing
标准来源旧 RFC 2543RFC 3261
Route URI 标识没有;lr参数;lr参数
Request-URI会被改成下一个代理的 URI保持为最终目标 URI
Route 头作用通过不断改写 R-URI 实现路由Route 头明确表示下一跳
是否推荐不推荐,主要为了兼容老设备推荐,现代 SIP 标准方式
Kamailio 常用处理函数一般不主动使用loose_route()
复杂度高,容易和 NAT、转发逻辑冲突简单清晰

2. 松散路由 Loose Routing

松散路由是现代 SIP 的标准做法。

典型 Record-Route 头类似:

Record-Route: <sip:proxy.example.com;lr>

关键点是 URI 里有:

;lr

lr代表 loose routing。

松散路由下的请求示例

假设 Kamailio 在初始 INVITE 中插入了:

Record-Route: <sip:kamailio.example.com;lr>

后续 BYE、ACK、re-INVITE 等 in-dialog 请求会带上:

Route: <sip:kamailio.example.com;lr>

但 Request-URI 仍然是最终目标,例如:

BYE sip:alice@192.168.1.100 SIP/2.0 Route: <sip:kamailio.example.com;lr>

也就是说:

Request-URI = 最终目标 Route = 经过哪些代理

Kamailio 收到后通常这样处理:

if (has_totag()) { if (loose_route()) { route(RELAY); exit; } }

loose_route()会检查 Route 头,如果发现自己在 Route 头里,就消费掉对应 Route,然后继续转发。


3. 严格路由 Strict Routing

严格路由是旧 SIP 规范里的方式。

Record-Route 头里没有;lr

Record-Route: <sip:proxy.example.com>

这种情况下,后续请求的 Request-URI 会被改成下一个代理地址,而真正的目标 URI 会被放到 Route 头的末尾。

严格路由下的请求示例

可能变成:

BYE sip:kamailio.example.com SIP/2.0 Route: <sip:alice@192.168.1.100>

也就是说:

Request-URI = 下一个代理 Route = 最终目标或后续路由集合

这种方式的问题是:

  1. Request-URI 不再表示最终目标;
  2. 代理需要反复改写 Request-URI;
  3. 和 NAT、注册 Contact、负载均衡逻辑更容易冲突;
  4. 配置和排错更复杂;
  5. 现代 SIP 设备基本不推荐这样用。

4. Kamailio 中怎么体现

Kamailio 里通常通过rr模块处理 Record-Route 和 Route。

常见配置:

loadmodule "rr.so" modparam("rr", "enable_full_lr", 0) modparam("rr", "append_fromtag", 1)

初始 INVITE 时让 Kamailio 留在信令路径中:

if (is_method("INVITE|SUBSCRIBE")) { record_route(); }

后续 in-dialog 请求:

if (has_totag()) { if (loose_route()) { route(RELAY); exit; } if (is_method("ACK")) { exit; } sl_send_reply("404", "Not here"); exit; }

这里的重点是:

loose_route()

虽然名字叫loose_route(),但 Kamailio 的rr模块在一定程度上也能兼容一些严格路由场景。不过在现代配置中,一般只需要按松散路由设计。


5. Record-Route 里的;lr

这是判断松散路由的核心。

松散路由

Record-Route: <sip:1.2.3.4;lr>

或者:

Record-Route: <sip:proxy.example.com;transport=udp;lr>

严格路由

Record-Route: <sip:1.2.3.4>

没有;lr,就可能被对端当成严格路由。


6. Kamailio 的enable_full_lr

Kamailio 的rr模块有一个参数:

modparam("rr", "enable_full_lr", 0)

默认情况下,Record-Route 可能类似:

Record-Route: <sip:proxy.example.com;lr>

如果设置为:

modparam("rr", "enable_full_lr", 1)

可能生成:

Record-Route: <sip:proxy.example.com;lr=on>

这是为了兼容某些有问题的 SIP 设备,它们可能不正确识别没有值的;lr参数。

一般情况下保持默认即可,除非遇到特定终端或运营商兼容性问题。


7. 实际使用建议

在 Kamailio 生产环境中,建议:

  1. 使用松散路由;
  2. 使用record_route()插入带;lr的 Record-Route;
  3. 使用loose_route()处理后续 in-dialog 请求;
  4. 不要主动生成没有;lr的 Record-Route;
  5. 严格路由只作为兼容旧设备考虑。

典型配置结构:

request_route { if (is_method("INVITE|SUBSCRIBE")) { record_route(); } if (has_totag()) { if (loose_route()) { route(RELAY); exit; } if (is_method("ACK")) { exit; } sl_send_reply("404", "Not here"); exit; } route(RELAY); } route[RELAY] { if (!t_relay()) { sl_reply_error(); } exit; }

8. 一句话总结

严格路由是旧式 SIP 路由方式,会通过改写 Request-URI 控制下一跳;松散路由是现代标准方式,通过Route头和;lr参数控制路由,Request-URI 保持最终目标。Kamailio 生产环境中基本都应该使用record_route()+loose_route()的松散路由模式。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询