Kamailio SIP脚本编程核心概念总结
变量含义是否自动设置$ruRequest-URI(请求目标)✅ 自动解析$duDestination URI(转发目标)❌ 需手动设置$fuFrom URI(主叫)✅ 自动解析$tuTo URI(被叫显示)✅ 自动解析$si来源IP地址✅ 自动设置$sp来源端口✅ 自动设置有状态与无状态分离t_relay()用于完整事务处理,forward()用于简单转发目标确定多样化:从明确指定到自
一、有状态与无状态转发的区分
1. 在请求处理中区分
-
有状态转发:显示调用
t_relay()或t_newtran(),创建事务状态,支持重传、超时处理 -
无状态转发:调用
forward(),简单转发SIP请求,不创建事务状态 -
不转发/拒绝:调用
drop或exit终止处理,可配合sl_send_reply()发送拒绝响应
2. 在响应处理中区分
-
有状态处理:在
onreply_route中调用t_reply()修改响应,关联特定事务 -
默认处理:Kamailio自动发现匹配的transaction对象并进行转发
-
无状态处理:使用
sl_send_reply()立即发送响应,不关联事务
二、核心函数功能解析
请求处理函数
|
函数 |
状态 |
功能 |
典型场景 |
|---|---|---|---|
|
|
有状态 |
创建事务状态,转发请求到下一目的地 |
INVITE、BYE等需要状态跟踪的呼叫 |
|
|
无状态 |
简单转发SIP请求,不维护状态 |
OPTIONS探测、特定场景快速转发 |
|
|
无状态 |
立即发送响应,不关联事务 |
认证失败、方法不支持等错误响应 |
|
|
- |
终止当前消息处理 |
处理完成、错误退出 |
响应处理函数
|
函数 |
状态 |
功能 |
使用位置 |
|---|---|---|---|
|
|
有状态 |
发送与特定事务关联的SIP响应 |
|
|
自动转发 |
有状态 |
Kamailio自动匹配事务并转发响应 |
系统自动处理 |
判断函数
|
函数 |
功能 |
返回值 |
|---|---|---|
|
|
判断具体请求或响应方法 |
布尔值 |
|
|
判断是否为有状态事务 |
布尔值 |
|
|
判断是否配置了响应路由 |
布尔值 |
|
|
判断是否为负面响应 |
布尔值 |
三、转发目标确定机制
1. sl_send_reply()
-
不需要寻找目标:直接回复给请求来源
-
自动使用:
$si(来源IP)和$sp(来源端口) -
示例:
sl_send_reply("401", "Unauthorized")
2. forward()
-
明确指定目标:
-
在函数参数中:
forward("udp:192.168.1.100:5060") -
通过
$du变量:$du = "sip:target@domain:5060"; forward()
-
3. t_relay()
-
通过
$du指定:$du = "sip:192.168.1.100:5060"; t_relay() -
通过
$ru的目标域:自动解析域名,DNS查询SIP服务器 -
负载均衡模块:
lb_start()或ds_select_dst()自动设置$du
4. t_reply()在 onreply_route中
-
目标自动确定:由事务管理器(tm模块)自动确定
-
不手动指定:只决定回复内容,不控制转发目标
-
返回路径:
-
SIP Via头机制:响应沿Via链自动返回
-
事务状态:tm模块记录原始请求来源信息
-
四、有状态与无状态模式对比
1. 无状态模式(不使用tm模块)
|
特性 |
说明 |
|---|---|
|
事务跟踪 |
无事务状态,tm模块不介入 |
|
响应匹配 |
Via头自动匹配 |
|
目标确定 |
完全依赖Via头机制 |
|
函数调用 |
不能调用 |
|
性能 |
高,无状态管理开销 |
|
可靠性 |
低,无重传机制 |
|
典型场景 |
OPTIONS探测、简单转发 |
示例:
route {
if (is_method("OPTIONS")) {
forward("udp:monitor.server:5060");
exit;
}
}
2. 有状态模式(使用tm模块)
|
特性 |
说明 |
|---|---|
|
事务跟踪 |
完整事务状态管理 |
|
响应匹配 |
事务branch参数匹配 |
|
目标确定 |
事务状态 + Via头共同确定 |
|
函数调用 |
可调用 |
|
性能 |
中,有状态管理开销 |
|
可靠性 |
高,支持重传、超时 |
|
典型场景 |
INVITE、BYE等呼叫控制 |
示例:
route {
t_on_reply("MY_REPLY_ROUTE");
t_relay(); # 创建事务
}
onreply_route[MY_REPLY_ROUTE] {
t_reply("488", "Modified"); # 修改响应
}
五、tm模块工作机制
1. 事务创建时
int t_newtran(struct sip_msg* msg) {
// 保存来源信息
trans->uac_sock = msg->rcv; // 接收socket
trans->via1 = msg->via1; // 保存Via头
trans->branch = msg->branch; // 保存branch参数
}
2. 响应匹配时
struct tm_transaction* t_check_trans() {
// 通过Via的branch参数匹配事务
// 返回对应的事务结构
}
3. 响应发送时
int t_reply(struct sip_msg* msg, int code, char* reason) {
// 从匹配事务获取:
// 1. 目标地址 (uac_sock)
// 2. 原始Via头
// 3. 发送socket信息
// 构造并发送响应
}
六、关键变量说明
预定义变量
|
变量 |
含义 |
是否自动设置 |
|---|---|---|
|
|
Request-URI(请求目标) |
✅ 自动解析 |
|
|
Destination URI(转发目标) |
❌ 需手动设置 |
|
|
From URI(主叫) |
✅ 自动解析 |
|
|
To URI(被叫显示) |
✅ 自动解析 |
|
|
来源IP地址 |
✅ 自动设置 |
|
|
来源端口 |
✅ 自动设置 |
七、最佳实践建议
1. 请求处理选择
-
需要状态跟踪:使用
t_relay()+ tm模块 -
简单快速转发:使用
forward() -
立即错误响应:使用
sl_send_reply()+exit
2. 响应处理选择
-
需要修改响应:在
onreply_route中使用t_reply() -
只需记录日志:在
onreply_route中记录但不修改 -
无状态场景:让响应自动透传
3. 目标设置策略
-
固定目标:直接设置
$du = "sip:target:port" -
动态路由:使用负载均衡模块
-
域名解析:依赖DNS SRV/NAPTR记录
-
响应返回:依赖Via头/事务状态,不手动设置
八、总结
Kamailio通过不同的函数和模式提供了灵活的SIP消息处理能力:
-
有状态与无状态分离:
t_relay()用于完整事务处理,forward()用于简单转发 -
目标确定多样化:从明确指定到自动发现,适应不同场景需求
-
响应处理自动化:通过Via头和事务状态,实现响应的自动正确返回
-
模块化设计:tm模块提供完整的事务管理,无状态模式提供高性能简单转发
更多推荐

所有评论(0)