Kamailio 5.8.3与rtpengine双网卡SBC集成要点
本文档总结了将Kamailio 5.8.3与rtpengine(配置为双网卡模式)集成以实现SIP+RTP媒体流转发(包括音视频和RTCP)的关键配置要点和最佳实践。用户场景包括:无NAT、公私网双向呼叫、通过dispatcher模块对公私网两侧的多网关进行负载均衡。
1. Kamailio rtpengine模块核心配置与使用
1.1. 模块加载与参数
loadmodule "rtpengine.so"
modparam("rtpengine", "rtpengine_sock", "udp:127.0.0.1:22222") # 与rtpengine的NG协议通信地址和端口
# 根据rtpengine mr13.1.1.6的配置,NG监听在127.0.0.1:22222
# 可选参数,根据需要调整:
# modparam("rtpengine", "rtpengine_tout_ms", 1000) # rtpengine请求超时时间 (毫秒)
# modparam("rtpengine", "rtpengine_retr", 5) # rtpengine请求重试次数
# modparam("rtpengine", "hash_table_size", 2048) # 内部哈希表大小
# modparam("rtpengine", "setid_avp", "$avp(rtpengine_setid)") # 如果使用多个rtpengine set
1.2. 核心函数调用
rtpengine_offer([flags])
: 在处理初始INVITE时调用,用于协商媒体。rtpengine_answer([flags])
: 在处理2xx响应时调用,用于确认媒体协商。rtpengine_delete([flags])
: 在处理BYE或会话结束时调用,用于释放rtpengine资源。rtpengine_manage([flags])
: 一个更通用的函数,可以替代rtpengine_offer
和rtpengine_answer
,并提供更多灵活性。通常建议使用rtpengine_manage
。
1.3. 关键Flags(用于rtpengine_manage
等函数)
rtpengine的强大之处在于通过flags精细控制其行为。对于双网卡场景,核心是告知rtpengine媒体流的“方向”或应使用的接口。
- 指定接口/方向:
- rtpengine侧配置了逻辑接口名,例如
interface = public/PUBLIC_IP!PUBLIC_IP
和interface = private/PRIVATE_IP!PRIVATE_IP
。 - Kamailio需要通过flags告诉rtpengine使用哪个逻辑接口。常用的方法是利用
direction=public
、direction=private
这样的自定义标记,并在rtpengine的rtpengine_offer
/rtpengine_answer
/rtpengine_manage
的flags参数中传递。例如:
- 对于来自公网的呼叫,发往私网的媒体描述,应指示rtpengine使用其“私网”接口:
rtpengine_manage("direction=public direction=private ...")
- 对于来自私网的呼叫,发往公网的媒体描述,应指示rtpengine使用其“公网”接口:
rtpengine_manage("direction=private direction=public ...")
- 另一种方式是直接在flags中指定IP地址,例如
internal-ip=PRIVATE_IP external-ip=PUBLIC_IP
,但这通常不如使用逻辑接口名灵活。 - 重要:Kamailio脚本需要有逻辑来判断呼叫的来源和去向,以便设置正确的
direction
flag。
- 媒体类型支持 (音视频):
- rtpengine默认会尝试处理SDP中描述的所有媒体流(音频和视频)。
- 确保SDP中正确描述了音视频媒体行 (
m=audio ...
,m=video ...
)。 - Flags示例:
RTP/AVP
(标准RTP),RTP/SAVP
(SRTP, 如果需要加密)。
- RTCP支持:
- rtpengine会自动处理与RTP流配对的RTCP流。
rtcp-mux-offer
,rtcp-mux-answer
,rtcp-mux-require
: 用于处理RTCP与RTP在同一端口复用的情况 (RFC 5761)。如果终端支持,建议启用以节省端口资源。
- 例如:
rtpengine_manage("rtcp-mux-offer ...")
- NAT处理 (用户场景为无NAT,但相关flags仍需注意):
trust-address
: 信任SDP中的连接地址。replace-origin
: 替换SDP中o=行中的地址。replace-session-connection
: 替换会话级c=行中的地址。- 在无NAT直连IP场景,这些替换标志通常也需要,以确保SDP中的IP地址是rtpengine的接口地址。
- 编解码器协商:
- rtpengine可以进行编解码器过滤和转码(如果配置了转码模块)。
- Flags:
codec-strip=all
,codec-mask=all,!PCMA,!PCMU
,codec-transcode=PCMA
等。 - 用户场景未明确要求转码,但如果需要,rtpengine具备此能力。
- 示例组合Flag (根据呼叫方向调整):
rtpengine_manage("trust-address replace-origin replace-session-connection direction=public direction=private RTP/AVP rtcp-mux-offer")
rtpengine_manage("trust-address replace-origin replace-session-connection direction=private direction=public RTP/AVP rtcp-mux-answer")
2. Kamailio dispatcher模块配置
用户需要在公网和私网两侧都通过dispatcher对多个网关进行负载均衡。
2.1. 定义Dispatcher Set
需要在kamailio.cfg
的全局部分或dispatcher
模块加载时定义网关组。
loadmodule "dispatcher.so"
# 定义公网网关组 (set id 1)
modparam("dispatcher", "list_file", "/etc/kamailio/dispatcher_public.list")
# 或者直接在配置文件中定义:
# modparam("dispatcher", "set_uri", "1 sip:gw_public1.example.com:5060")
# modparam("dispatcher", "set_uri", "1 sip:gw_public2.example.com:5060")
# 定义私网网关组 (set id 2)
modparam("dispatcher", "list_file", "/etc/kamailio/dispatcher_private.list")
# 或者直接在配置文件中定义:
# modparam("dispatcher", "set_uri", "2 sip:gw_private1.internal:5060")
# modparam("dispatcher", "set_uri", "2 sip:gw_private2.internal:5060")
dispatcher_public.list
文件示例:
1 sip:public_gw1_ip:5060
1 sip:public_gw2_ip:5060 flags=ap # a for active, p for PINGs
dispatcher_private.list
文件示例:
2 sip:private_gw1_ip:5060
2 sip:private_gw2_ip:5060
2.2. 选择网关
在路由逻辑中,使用ds_select_dst()
或ds_select_domain()
选择目标网关。
# 呼叫发往公网
if (is_from_private()) { # 自定义逻辑判断是否来自私网
ds_select_dst("1", "4"); # 选择公网网关组 (set 1), 算法4 (round-robin)
if ($rc < 0 || $ru == $null) {
send_reply("503", "Service Unavailable - No Public Gateway");
exit;
}
# $du 会被设置为选中的网关URI
t_set_destination_uri($du);
# ... 后续路由和rtpengine_manage调用 (direction=public)
}
# 呼叫发往私网
if (is_from_public()) { # 自定义逻辑判断是否来自公网
ds_select_dst("2", "4"); # 选择私网网关组 (set 2), 算法4 (round-robin)
if ($rc < 0 || $ru == $null) {
send_reply("503", "Service Unavailable - No Private Gateway");
exit;
}
# $du 会被设置为选中的网关URI
t_set_destination_uri($du);
# ... 后续路由和rtpengine_manage调用 (direction=private)
}
3. Kamailio路由逻辑中的双网卡处理
Kamailio需要能够区分流量的来源(公网/私网)和去向,以便:
- 选择正确的dispatcher网关组。
- 为
rtpengine_manage
设置正确的direction
flag。
3.1. 识别接口/网络
- 可以使用
if ($si == "PUBLIC_KAM_IP" && $sp == 5060)
或if (src_ip == "PRIVATE_KAM_IP")
等条件判断SIP包到达的Kamailio接口。 - 或者通过自定义的
is_from_public()
/is_from_private()
函数,基于源IP地址或其他头部信息进行判断。
3.2. 示例路由块结构
request_route {
# ... 初始处理 (max_forwards, sanity checks etc.)
if (is_from_public()) { # 假设这是来自公网的呼叫
xlog("L_INFO", "Call from Public to Private Network\n");
# 目标是私网
ds_select_dst("2", "4"); # 选择私网网关组
if ($rc < 0 || $ru == $null) {
send_reply("503", "No Private Gateway Available");
exit;
}
t_set_destination_uri($du);
if (has_body("application/sdp")) {
rtpengine_manage("trust-address replace-origin replace-session-connection direction=private RTP/AVP rtcp-mux-offer");
}
route(RELAY_TO_PRIVATE);
} else if (is_from_private()) { # 假设这是来自私网的呼叫
xlog("L_INFO", "Call from Private to Public Network\n");
# 目标是公网
ds_select_dst("1", "4"); # 选择公网网关组
if ($rc < 0 || $ru == $null) {
send_reply("503", "No Public Gateway Available");
exit;
}
t_set_destination_uri($du);
if (has_body("application/sdp")) {
rtpengine_manage("trust-address replace-origin replace-session-connection direction=public RTP/AVP rtcp-mux-offer");
}
route(RELAY_TO_PUBLIC);
} else {
xlog("L_WARN", "Call from unknown source, dropping.\n");
send_reply("403", "Forbidden - Unknown Source");
exit;
}
}
route[RELAY_TO_PRIVATE] {
# ... 可能的额外处理
if (!t_relay()) {
sl_reply_error();
}
exit;
}
route[RELAY_TO_PUBLIC] {
# ... 可能的额外处理
if (!t_relay()) {
sl_reply_error();
}
exit;
}
# 对于响应的处理
onreply_route {
if (status=~"^[12]") {
if (has_body("application/sdp")) {
# 需要判断响应的方向来设置正确的direction flag
# 这通常基于事务状态或自定义的标志
if (is_reply_to_public_originated_call()) { # 伪代码,需要实现逻辑
rtpengine_manage("trust-address replace-origin replace-session-connection direction=private direction=public RTP/AVP rtcp-mux-answer");
} else if (is_reply_to_private_originated_call()) { # 伪代码
rtpengine_manage("trust-address replace-origin replace-session-connection direction=public direction=private RTP/AVP rtcp-mux-answer");
}
}
}
# ... 其他响应处理
}
branch_route[MANAGE_FAILURE] {
xlog("L_ERR", "Failed to manage rtpengine for branch\n");
}
failure_route[MANAGE_FAILURE] {
xlog("L_ERR", "Failed to manage rtpengine for request\n");
}
4. 其他注意事项
- Kamailio版本:用户指定5.8.3。上述模块和参数在此版本中应可用。建议查阅Kamailio 5.8.x的官方文档确认细节。
- SDP处理:确保
rtpengine_manage
在SDP存在时被调用,并且在请求和响应路径中都被正确处理。 - 错误处理:
rtpengine_manage
调用失败时,应有适当的错误处理逻辑。 - RTCP:rtpengine会自动处理RTCP。
rtcp-mux
flags是推荐的最佳实践。 - 安全性:虽然用户未明确要求,但生产环境中应考虑SIP信令的认证和授权,以及可能的TLS加密。
- 调试:充分利用Kamailio的
xlog
和rtpengine的日志进行调试。
这份总结将作为起草Kamailio配置文件的基础。
空空如常
求真得真
Kamailio 5.8.3与rtpengine双网卡SBC集成要点的更多相关文章
- 烂泥:VMWare Workation双网卡配置IP地址
本文由ilanniweb提供友情赞助,首发于烂泥行天下 想要获得更多的文章,可以关注我的微信ilanniweb 前几天给一个客户做远程项目实施,客户那边的服务器是Windows OS的,我们这边的业务 ...
- Linux下双网卡绑定bond0
一:原理: linux操作系统下双网卡绑定有七种模式.现在一般的企业都会使用双网卡接入,这样既能添加网络带宽,同时又能做相应的冗余,可以说是好处多多.而一般企业都会使用linux操作系统下自带的网卡绑 ...
- Linux 双网卡绑定
Linux 双网卡绑定 Linux 双网卡绑定双网卡绑定的常用模式:mode1:active-backup 模式,即主备模式.mode0:round-broin 模式,即负载均衡模式(需要交换机配置聚 ...
- Windows Server 2008 双网卡同时上内外网 不能正常使用
Windows server 2008 32位下,双网卡同时上内外网,并提供VPN服务,遇见的奇怪问题 1.服务器配置 2.网络配置 以太网适配器 内部连接: 连接特定的 DNS 后缀 . . . . ...
- CentOS 7使用nmcli配置双网卡聚合
进入CentOS 7以后,网络方面变化比较大,例如eth0不见了,ifconfig不见了,其原因是网络服务全部都由NetworkManager管理了,下面记录下今天下午用nmcli配置的网卡聚合,网络 ...
- VirtualBox双网卡搭建Linux虚拟实验环境
VirtualBox中有如下几种网络连接方式: NAT(NAT到宿主机IP地址) NAT Network (NAT到宿主机所在的网段,即使用相同的网关和掩码) Bridged Adapter Inte ...
- ubuntu 双线双网卡双IP实现方式
昨天金桥机房上架了一台多玩的测试机,系统是ubuntu9.04 X64的系统,母机IBM X336机器.用户需求是双线,故采用一个网卡配置电信地址,另一个网卡配置联通地址,安装好系统后配置好IP发现联 ...
- (转)深度分析Linux下双网卡绑定七种模式
现在一般的企业都会 使用双网卡接入,这样既能添加网络带宽,同时又能做相应的冗余,可以说是好处多多.而一般企业都会使用linux操作系统下自带的网卡绑定模式,当然现在 网卡产商也会出一些针对window ...
- 烂泥:openvpn双网卡客户端与内网机器通信
本文由ilanniweb提供友情赞助,首发于烂泥行天下 想要获得更多的文章,可以关注我的微信ilanniweb. 前段时间写了一篇有关openvpn搭建与内网机器通信的文章,那篇文章是基于服务器单网卡 ...
- linux 双网卡实现
linux实现双网卡,在虚拟机中创建一个新网卡,NAT方式连接,其中eth0设置为连接外网,目前eth0为自动分配状态,所以将代码注释掉了,eth1设置为连接内网.
随机推荐
- Tomcat知识点整理
从学习起就开始接触tomcat, 解压, 点击运行, 然后放文件夹里面会自动部署, 可以通过ip访问. 在这里主要记录一些tomcat相关的知识点 配置文件解析(留位置) server.xml/web ...
- 解决VSCODE进行C代码编辑时结构体成员不可见或不提示的问题
在使用VSCODE进行C代码编辑时,结构体成员有时可见,光标放到成员上时,系统会提示结构体成员对应的注释信息,但是有时候却不行. 经过测试,发现有如下规律:以test.c test.h include ...
- ApplicationContext 接口的实现类
ClassPathXmlApplicationContext: 它是从类的根路径下加载配置文件 推荐使用这种 FileSystemXmlApplicationContext: 它是从磁盘路径上加载配置 ...
- MySQL插入异常:SQL state [HY000]; error code [1366]-----(utf8mb4)
发现爬虫软件,爬取数据不及时,查询服务器日志发现异常: SQL state [HY000]; error code [1366] java.sql.SQLException: Incorrect st ...
- 为什么 Java 中某些新生代和老年代的垃圾收集器不能组合使用?
为什么 Java 中某些新生代和老年代的垃圾收集器不能组合使用? 在 JVM 中,新生代和老年代的垃圾收集器是分工协作的.然而,并非所有的新生代和老年代垃圾收集器都能任意组合使用,这是由于它们的设计目 ...
- Web前端开发规范手册(有点老,仅供参考)
一.规范目的 1.1 概述 为提高团队协作效率, 便于后台人员添加功能及前端后期优化维护, 输出高质量的文档, 特制订此文档. 本规范文档一经确认, 前端开发人员必须按本文档规范进行前台页面开发. 本 ...
- AXUI - 极致原生体验的零依赖的国产 Web UI 框架,欢迎体验和共建!
AXUI:专注于快速交付的国产 Web UI 框架 在日常的前端开发中,是否遇到过以下场景: 灵感乍现,希望快速通过一点代码实现原型或功能展示: 完全个人项目,开发方式自由,追求高效与便捷: 项目目标 ...
- centos 7.8下载地址
随着7.9版本的正式版本的发布,7.8.2003版本逐渐被各大镜像站替换,取消. 7.8.2003版本的可以自行在华中科技大学的镜像站下载,这个地址也可能随时会失效,如果失效了同学们可以自行百度搜寻. ...
- 【安装】Windows下安装Anaconda、pytorch,以及修改pip默认安装路径
写在最前: 如果不打算用conda创建并管理虚拟环境,可以不装Anaconda,随便找个python安装包一路next就行. 文章目录 Windows下安装Anaconda PS:之后的步骤同样适用于 ...
- 【记录】MATLAB矩阵的批量元素修改方式,与Python的NumPy对比
文章目录 二维矩阵 操作 1. 将数组大于0的数全部加1 2. 删除元素 ①删除单个元素 ②删除一列元素 3. 添加一行或多行 ①添加一行 ②添加多行 4. 获取行/列数 5. 格式化输出数组 结构数 ...