Kamailio的学习

目录

一.概述

二.配置文件

1.全局参数部分

2.模块设置部分

3.路由区块部分

4.伪变量

三.架构

1.总述

2.核心

3.模块

4.SIP消息处理

四.底层实现

1.多进程模型

(1)进程表数据结构模型

(2)进程创建流程

(3)进程间通信IPC机制

2.Epoll多路复用机制

(1)io_wait_h数据结构

(2)初始化函数

(3)资源清理

3.共享内存

(1)底层机制

4.锁定系统

(1)多平台锁定支持

(2)高级锁定功能

一.概述

Kamailio是一款SIP服务器。它可以在高并发环境中,做SIP呼叫的均衡负载处理,是多进程模式(使用fork)。Kamailio支持异步的TCP、UDP、SCTP、TLS、WebSocket,支持WebRTC,支持IPv4和IPv6,支持异步操作,支持负载均衡、主备用路由(Fail-Over),支持AAA(记账、鉴权和授权),支持很多SQL和noSQL数据库后端如MySQL、PostgreSQL、Oracle、Redis、MongoDB等,支持消息队列如RabbitMQ、Kafka等,支持JSON-RPC和XML-RPC控制协议以及SNMP监控等诸多特性。

二.配置文件

kamailio.cfg的结构可以分为三个部分,分别是全局参数、模块设置、路由区块。

1. 全局参数部分

name=value

名称对应官方文档(https://www.kamailio.org/w/documentation/)中的核心参数,如果名称与核心参数不匹配的话,Kamailio无法启动。

值通常是整数、bool或字符串

Go 复制代码
log_facility=LOG_LOCAL0

children=4

disable_tcp=yes

alias="sip.mydomain.com"

listen=udp:10.0.0.10:5060

比如在上面的例子中,如果 Kamailio日志登录到syslog,你可以控制该设施进行日志记录。当你想把所有 Kamailio日志转到另一个日志时,这非常有用。LOG_LOCAL0是rsyslogd中的概念,就是日志流的分类,会根据这些分类导出到不同文件。默认值是LOG_DAEMON。

children=4 UDP接口的子接口数量(每个接口一组- ip:port)。缺省值为8。例如,如果你配置代理监听3个UDP端口,它将创建3xchildren processes子进程来处理传入的UDP消息。

disable_tcp=yes 用来调整TCP的行为,全局参数用于禁用SIP服务器中的TCP支持,默认值是no

alias="sip.mydomain.com" 别名就是域名,用于设置服务器的别名主机名,它可以设置多次,每个值都被添加到一个列表中,以便在选中"myself"时匹配主机名。有必要在别名定义中包含端口("port="或"listen="定义中使用的端口值,alias:5060=other.domain.com),否则loose_route()函数将无法按预期的方式工作。

listen=udp:10.0.0.10:5060 设置SIP服务器应该监听的网络地址。它可以是IP地址、主机名或网络接口id或协议、地址、端口的组合。该参数可以在同一个配置文件中多次设置,服务器监听指定的所有地址。如果省略了这个指令,SIP服务器就会监听所有指令接口

2.模块设置部分

包含加载模块和设置模块参数的指令。它包含指令loadmodule和modparam。在默认配置文件中,以设置模块路径的行开头(对mpath core参数的赋值)

loadmodule "debugger.so"

...

modparam("debugger", "cfgtrace", 1)

loadmodule "debugger.so" 启用kamailio的交互调试功能,实时跟踪SIP消息处理流程

modparam("debugger", "cfgtrace", 1) 启用配置跟踪,参数含义分别是模块名称、配置跟踪参数、启用跟踪。如果为0就是禁用跟踪

3.路由区块部分

包含了Kamailio处理的SIP流量的路由逻辑的路由块。唯一的强制路由块是request_route,它包含决定SIP请求路由的操作。

request_route {

per request initial checks

route(REQINIT);

...

}

branch_route[MANAGE_BRANCH] {

xdbg("new branch [T_branch_idx\] to ru\n");

route(NATMANAGE);

}

onreply_route[MANAGE_REPLY] {

if (has_totag()) {

route(IN_DIALOG_REPLY);

}

route(HANDLE_NAT_REPLY);

}

主请求路由(request_route):调用子路由REQINIT

分支路由(branch_route):调用子路由NATMANAGE

主响应路由(onreply_route)

"伪变量"一词用于指可以被赋予的特殊符号作不同脚本函数的参数,这些参数将被替换在函数执行之前的值,开头用字符"$"标记

$T_branch_idx 执行branch_route[]的分支的索引(第一个分支从1开始)。如果在branch_route[]块之外使用,则值为'0'。

$ru SIP请求的URI的引用,它是R/W变量(可以直接在配置文件中赋值给它)

4.伪变量

是Kamailio核心系统提供的变量,用于访问SIP消息、系统状态等信息。当Kamailio收到SIP消息时,会自动解析并填充这些变量,它覆盖SIP消息、网络、系统等各方面。

$ru = "sip:1001@192.168.1.100:5060" # 指定新的请求行

$rm = "INVITE" # 从 SIP 请求方法提取

$si = "192.168.1.50" # 从网络包提取源IP

第一个变量是可读可写的,请求URI,可以修改来改变SIP消息目的地

第二个和第三个都是只读变量,分别是请求方法和源IP地址,修改会导致错误

三.架构

1.总述

Kamailio采用模块化架构,从整体看主要分为核心和模块两大类。

图中为Kamailio 1.x架构

Kamailio v3.0.x(或更新版本)的架构进行了重构,把原本核心的数据库API、管理接口API移出,重构为内部库

假设有一个INVITE请求到达:

①接收:SIP TRANSPORT LAYER(SIP传输层)从INTERNET接收到UDP数据包(也可以是UDP/TCP/TLS/WSS)

②解析:SIP PARSER(SIP解析器)将其转换为内部结构sip_msg

③执行路由脚本:CONFIG INTERPRETER开始执行kamailio.cfg对应的路由逻辑(比如route{...})

④调用功能模块:在脚本执行中,遇到类似lookup("location")或ds_select_dst()的命令,就会通过MODULE INTERFACE调用对应的LOCATION MODULES或ROUTING MODULES

⑤访问数据:模块在需要查询用户或路由规则时,通过DB API调用DB DRIVER MODULES,从DB SERVER获取数据

⑥管理与监控:这时管理员通过WEB GUI发送一个"查看当前呼叫数"的命令,该命令通过MI TRANSPORT MODULES和MI API传递给核心,核心返回数据并在界面上展示。

⑦发送响应:最终,处理后的INVITE消息再通过SIP TRANSPORT LAYER​发送到网络。

演示:./register_test.sh 1 10.0.2.15:5060发起一个注册请求,查看日志进行分析:

①接收:SIP TRANSPORT LAYER接收数据包

Received SIP message,这是TCP传输层接收到的REGISTER请求。

②解析:SIP PARSER转换为内部结构

解析器逐行解析SIP消息,识别方法为REGISTER,URI等信息。

③执行路由脚本:CONFIG INTERPRETER

<script>标签表明正在执行kamailio.cfg中的路由脚本,这是配置解释器在执行。

④调用功能模块:MODULE INTERFACE

正在解析目标地址,是通过路由模块实现的。

⑤发送响应:SIP TRANSPORT LAYER

请求转发:

响应返回:

通过TCP传输层发送完整的SIP消息。

2.核心

核心包括内存管理器、SIP消息解析器、锁定系统、DNS和传输层管理、配置文件解析器和解释器、计时器API;内部库包括一些来自旧Kamailio核心的组件,数据库抽象层(DB API),管理接口(MI API),统计引擎等

3.模块

目前仓库中有超过150个模块,通过加载模块,可以获得以下功能:注册商和用户位置管理;计费、授权与认证;有状态处理-SIP事务管理;异步SIP请求处理

4.SIP消息处理

Kamailio配置文件的执行在收到来自网络SIP请求和SIP回复的处理流程不同。

(1)SIP请求处理

①所有请求都从传输层进入,执行主路由

②路由脚本决定三分之一:

立即回复并结束(认证失败、错误请求等)

简单无状态转发(高性能代理)

完整有状态处理(支持分支路由、失败处理等)

③最终都通过传输层发送响应或转发请求

(2)SIP回复处理

四.底层实现

1.多进程模型

(1)进程表数据结构模型

(2)进程创建流程

(3)进程间通信IPC机制

Unix域socket通信

文件描述符传递

子进程的sockfd[1]和父进程的sockfd[0]通信

通过"/opt/kamailio/sbin/kamcmd ps"查看kamailio的多进程

5375:主管理进程,启动和监控所有子进程

定时器进程组:有三个独立的定时器进程,分别处理不同精度的定时任务

5377:慢定时器

5378:主定时器,SIP事务超时处理、对话状态维护

5379:次级定时器,与主定时器配合,处理不同时间粒度的任务

5380:控制处理程序,处理kamcmd命令

5385:TCP主进程,监听TCP端口,接收TCP连接,将连接分配给工作进程

5381-5384:4个工作进程,从TCP连接读取SIP消息、解析SIP消息、执行路由脚本

(children参数可以在cfg文件中tcp_children进行配置)

2.Epoll多路复用机制

(1)io_wait_h数据结构

通用字段

epoll专用字段

(2)初始化函数

初始化调用时机

模式选择逻辑

内核版本>=2.5.66 默认使用水平触发

(3)资源清理

销毁函数

epoll销毁

3.共享内存

(1)底层机制

有两种共享内存的方式

第一种MMAP(内存映射)

MAP_ANON:创建匿名内存区域,不与任何文件关联;/dev/zero:特殊设备文件,提供全零的内存页

第二种System V SHM

shmget():创建或获取共享内存段

shmat():将共享内存附加到进程地址空间

IPC_PRIVATE:每次创建新的共享内存段

4.锁定系统

(1)多平台锁定支持

Futex,用户态快速路径,避免系统调用

FAST_LOCK,快速自旋锁,自选等待,低延迟。适用于高并发短临界区

Pthread互斥锁

POSIX信号量,需要跨进程锁定时,用于进程间同步

编译时根据目标平台自动选择最快的锁实现

(2)高级锁定功能

递归锁,同一进程可多次获取锁,记录持有者防止死锁

相关推荐
西岸行者4 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意4 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码4 天前
嵌入式学习路线
学习
毛小茛4 天前
计算机系统概论——校验码
学习
babe小鑫4 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms4 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下4 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。4 天前
2026.2.25监控学习
学习
im_AMBER4 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J4 天前
从“Hello World“ 开始 C++
c语言·c++·学习