kamailio的配置文件kamailio.cfg的中文解释
【代码】kamailio的配置文件kamailio.cfg的中文解释。
·
#!KAMAILIO
#
# Kamailio SIP 服务器 v6.0 - 默认配置脚本
# - 网站: https://www.kamailio.org
# - GitHub: https://github.com/kamailio/kamailio
#
# 关于此文件的问题,请发送邮件至: <sr-users@lists.kamailio.org>
#
# 参考 Kamailio 核心 Cookbook: https://www.kamailio.org/wikidocs/
# 以了解可能的语句、函数和参数的解释。
#
# 注意:注释可以是:
# - 以 # 开头的行,但不包括预处理指令,
# 预处理指令以 #! 开头,例如 #!define, #!ifdef, #!endif, #!else, #!trydef,
# #!subst, #!substdef 等。
# - 以 // 开头的行
# - 包含在 /* */ 之间的块
# 注意:此配置执行对称的 SIP 信令
# - 它将回复发送到请求的源地址
# - 删除对称 SIP 信令的 force_rport() 使用
#
# 可以使用 '#!define WITH_FEATURE' 指令启用多个功能:
#
# *** 要运行调试模式:
# - 定义 WITH_DEBUG
# - 调试级别增加到 3,日志仍然发送到 syslog
# - 加载调试器模块,并启用 cfgtrace
#
# *** 启用 MySQL:
# - 定义 WITH_MYSQL
#
# *** 启用认证执行:
# - 启用 mysql
# - 定义 WITH_AUTH
# - 使用 'kamctl' 或 'kamcli' 添加用户
#
# *** 启用 IP 认证执行:
# - 启用 mysql
# - 启用认证
# - 定义 WITH_IPAUTH
# - 向 'address' 表中添加 ID 为 1 的 IP 地址
#
# *** 启用持久用户位置执行:
# - 启用 mysql
# - 定义 WITH_USRLOCDB
#
# *** 启用 Presence 服务器执行:
# - 启用 mysql
# - 定义 WITH_PRESENCE
# - 如果配置中修改了标头或正文,Presence 处理必须使用这些内容:
# - 定义 WITH_MSGREBUILD
#
# *** 启用 NAT 穿透执行:
# - 定义 WITH_NAT
# - NAT SIP OPTIONS keepalives 选项:WITH_NATSIPPING
# - 安装 RTPProxy: http://www.rtpproxy.org
# - 启动 RTPProxy:
# rtpproxy -l _your_public_ip_ -s udp:localhost:7722
#
# *** 使用 RTPEngine(替代 RTPProxy)进行 NAT 穿透执行:
# - 定义 WITH_RTPENGINE
# - 安装 RTPEngine: https://github.com/sipwise/rtpengine
# - 启动 RTPEngine:
# rtpengine --listen-ng=127.0.0.1:2223 ...
#
# *** 启用 PSTN 网关路由执行:
# - 定义 WITH_PSTN
# - 设置 pstn.gw_ip 的值
# - 检查 route[PSTN] 中的正则表达式路由条件
#
# *** 启用数据库别名查找执行:
# - 启用 mysql
# - 定义 WITH_ALIASDB
#
# *** 启用快速拨号查找执行:
# - 启用 mysql
# - 定义 WITH_SPEEDDIAL
#
# *** 启用多域支持执行:
# - 启用 mysql
# - 定义 WITH_MULTIDOMAIN
#
# *** 启用 TLS 支持执行:
# - 根据需要调整 CFGDIR/tls.cfg
# - 定义 WITH_TLS
#
# *** 启用 JSONRPC over HTTP(S) 支持执行:
# - 定义 WITH_JSONRPC
# - 根据访问策略调整 event_route[xhttp:request]
#
# *** 启用防洪检测执行:
# - 根据需要调整 pike 和 htable=>ipban 设置(默认是
# 如果 2 秒内请求超过 16 次,则阻止,并且禁止 300 秒)
# - 定义 WITH_ANTIFLOOD
#
# *** 启用 htable 模块执行:
# - 定义 WITH_HTABLE
#
# *** 阻止 3XX 重定向回复执行:
# - 定义 WITH_BLOCK3XX
#
# *** 阻止 401 和 407 认证回复执行:
# - 定义 WITH_BLOCK401407
#
# *** 启用语音信箱路由执行:
# - 定义 WITH_VOICEMAIL
# - 设置 voicemail.srv_ip 的值
# - 调整 voicemail.srv_port 的值
# 第二段
# *** 要增强计费功能执行:
# - 启用 mysql
# - 定义 WITH_ACCDB
# - 向数据库添加以下列
#!ifdef ACCDB_COMMENT
ALTER TABLE acc ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';
# 向 acc 表添加 src_user 列,类型为 VARCHAR(64),默认为空字符串
ALTER TABLE acc ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';
# 向 acc 表添加 src_domain 列,类型为 VARCHAR(128),默认为空字符串
ALTER TABLE acc ADD COLUMN src_ip varchar(64) NOT NULL default '';
# 向 acc 表添加 src_ip 列,类型为 VARCHAR(64),默认为空字符串
ALTER TABLE acc ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';
# 向 acc 表添加 dst_ouser 列,类型为 VARCHAR(64),默认为空字符串
ALTER TABLE acc ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';
# 向 acc 表添加 dst_user 列,类型为 VARCHAR(64),默认为空字符串
ALTER TABLE acc ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';
# 向 acc 表添加 dst_domain 列,类型为 VARCHAR(128),默认为空字符串
ALTER TABLE missed_calls ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';
# 向 missed_calls 表添加 src_user 列,类型为 VARCHAR(64),默认为空字符串
ALTER TABLE missed_calls ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT ''; # 向 missed_calls 表添加 src_domain 列,类型为 VARCHAR(128),默认为空字符串
ALTER TABLE missed_calls ADD COLUMN src_ip varchar(64) NOT NULL default '';
# 向 missed_calls 表添加 src_ip 列,类型为 VARCHAR(64),默认为空字符串
ALTER TABLE missed_calls ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';
# 向 missed_calls 表添加 dst_ouser 列,类型为 VARCHAR(64),默认为空字符串
ALTER TABLE missed_calls ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';
# 向 missed_calls 表添加 dst_user 列,类型为 VARCHAR(64),默认为空字符串
ALTER TABLE missed_calls ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT ''; # 向 missed_calls 表添加 dst_domain 列,类型为 VARCHAR(128),默认为空字符串
#!endif
####### 如果存在本地配置,则包含本地配置文件 #########
import_file "kamailio-local.cfg"
# 如果 kamailio-local.cfg 存在,则导入该文件作为配置的一部分
# 第三段
####### 定义的值 #########
# *** 值定义 - 在配置中稍后使用的 ID
#!ifdef WITH_DEBUG
#!define DBGLEVEL 3
# 如果启用了调试,设置调试级别为 3
#!else
#!define DBGLEVEL 2
# 如果没有启用调试,设置调试级别为 2
#!endif
#!ifdef WITH_MYSQL
# - 数据库 URL - 用于通过模块连接到数据库服务器,
# 例如:auth_db, acc, usrloc 等模块。
#!trydef DBURL "mysql://kamailio:kamailiorw@localhost/kamailio"
# 如果启用 MySQL,定义数据库连接 URL
#!endif
#!ifdef WITH_MULTIDOMAIN
# - 'use_domain' 参数的值
#!define MULTIDOMAIN 1
# 启用多域支持时,将 MULTIDOMAIN 设置为 1
#!else
#!define MULTIDOMAIN 0
# 启用多域支持时,将 MULTIDOMAIN 设置为 0
#!endif
#!ifdef WITH_ANTIFLOOD
# - 用于存储被阻止的 IP 地址的哈希表 'ipban'
#!trydef WITH_HTABLE
# 如果启用防洪功能,尝试定义 HTABLE 模块
#!endif
# - 标志
# FLT_ - 每个事务(消息)的标志
#!define FLT_ACC 1
# 账户标志
#!define FLT_ACCMISSED 2
# 漏接账户标志
#!define FLT_ACCFAILED 3
# 账户失败标志
#!define FLT_NATS 5
# NAT 标志
# FLB_ - 每个分支的标志
#!define FLB_NATB 6
# NAT 分支标志
#!define FLB_NATSIPPING 7
# NAT SIP 保活分支标志
####### 全局参数 #########
/* 日志级别: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR, ... */
debug=DBGLEVEL
# 设置调试日志级别,值从定义的 DBGLEVEL 取
/* 设置为 'yes' 以将日志消息打印到终端,或者使用 '-E' CLI 选项 */
log_stderror=no
# 禁用将日志消息打印到终端
memdbg=5
# 设置内存调试级别为 5
memlog=5
# 设置内存日志级别为 5
log_facility=LOG_LOCAL0
# 设置日志设施为 LOG_LOCAL0
log_prefix="{$mt $hdr(CSeq) $ci} "
# 设置日志前缀格式
/* 每个 UDP 套接字的 SIP 路由进程数
* - 如果未显式设置,值会继承到 tcp_children 和 sctp_children */
children=8
# 设置每个 UDP 套接字的 SIP 路由进程数为 8
/* 取消注释以下行以禁用 TCP(默认启用) */
# disable_tcp=yes
# 禁用 TCP(默认情况下是启用的)
/* 所有 TCP/TLS 套接字的 SIP 路由进程数 */
# tcp_children=8
# 设置 TCP 套接字的 SIP 路由进程数为 8
/* UDP 接收模式:
* - 0: 多进程(默认)
* - 1: 使用异步工作组 'udp' 的多线程
* - 2: 每个套接字的配置(请参见核心 Cookbook) */
# async_workers_group="name=udp;workers=8"
# 设置 UDP 的异步工作组
# udp_receiver_mode = 1
# 设置为多线程模式
/* 取消注释以下行以禁用基于 IP 的反向 DNS 发现本地别名(默认启用) */
# auto_aliases=no
# 禁用自动发现本地别名
/* 添加本地域别名 - 可以多次设置 */
# alias="sip.mydomain.com"
# 设置本地域别名
/* 监听套接字 - 如果未设置,则 Kamailio 会绑定到所有本地 IP 地址
* - 基本原型(完整原型请参见 Wiki - Core Cookbook):
* listen=[proto]:[localip]:[lport] advertise [publicip]:[pport]
* - 可以多次设置以添加更多要监听的套接字 */
# listen=udp:10.0.0.10:5060
# 设置监听套接字为指定的本地 IP 和端口
/* 没有流量时 TCP 连接的生命周期
* - 稍高于注册过期时间,以适应 NAT 后的 UA */
tcp_connection_lifetime=3605
# 设置 TCP 连接的生命周期为 3605 秒
/* TCP 连接的上限(包括 TLS 连接) */
tcp_max_connections=2048
# 设置 TCP 连接的最大数量为 2048
/* 每个 IP 地址的 TCP 连接上限 - 默认 1024 */
#tcp_accept_iplimit=1024
# 设置每个 IP 地址的最大连接数
#!ifdef WITH_JSONRPC
tcp_accept_no_cl=yes
# 如果启用 JSONRPC,设置为不接受客户端连接
#!endif
#!ifdef WITH_TLS
enable_tls=yes
# 启用 TLS 支持
/* TLS 连接的上限 */
tls_max_connections=2048
# 设置 TLS 连接的最大数量为 2048
/* OpenSSL 3 集成
* 调用 libssl3 的函数可以在临时线程中执行
* 0: 禁用线程调用
* 1: 仅对进程 #0 使用线程执行器
* 2: 不使用线程执行器,但使用 atfork 处理程序将线程本地变量重置为 NULL */
tls_threads_mode=2
# 设置 OpenSSL 3 集成的线程模式为 2
#!endif
/* 设置为 yes 以启用 sctp 并加载 sctp.so 模块 */
enable_sctp=no
# 禁用 SCTP 支持
# 第四段
####### 自定义参数 #########
/* 这些参数可以通过 RPC 接口在运行时修改
* - 参见 'cfg_rpc' 模块的文档。
*
* 格式: group.id = value 'desc' 描述
* 访问方式: $sel(cfg_get.group.id) 或 @cfg_get.group.id */
#!ifdef WITH_PSTN
/* PSTN 网关路由
*
* - pstn.gw_ip: 有效的 IP 地址或主机名,示例:
* pstn.gw_ip = "10.0.0.101" desc "我的 PSTN 网关地址"
*
* - 默认值为空,以避免错误路由 */
pstn.gw_ip = "" desc "PSTN 网关地址"
# 设置 PSTN 网关的 IP 地址
pstn.gw_port = "" desc "PSTN 网关端口"
# 设置 PSTN 网关的端口
#!endif
#!ifdef WITH_VOICEMAIL
/* 语音邮件路由(用于离线、忙线或无应答情况)
*
* - 默认情况下,语音邮件服务器的 IP 地址为空,以避免错误路由 */
voicemail.srv_ip = "" desc "语音邮件服务器 IP 地址"
# 设置语音邮件服务器的 IP 地址
voicemail.srv_port = "5060" desc "语音邮件服务器端口"
# 设置语音邮件服务器的端口,默认为 5060
#!endif
####### 模块部分 ########
/* 设置模块的路径位置 */
# mpath="/usr/local/lib/kamailio/modules/"
# 设置模块路径
# 使用 OpenSSL 启用 TLS 时,建议首先加载此模块
# 以确保 OpenSSL 被正确初始化
#!ifdef WITH_TLS
loadmodule "tls.so"
# 如果启用了 TLS,加载 tls.so 模块
#!endif
#!ifdef WITH_MYSQL
loadmodule "db_mysql.so"
# 如果启用了 MySQL,加载 db_mysql.so 模块
#!endif
#!ifdef WITH_JSONRPC
loadmodule "xhttp.so"
# 如果启用了 JSONRPC,加载 xhttp.so 模块
#!endif
loadmodule "jsonrpcs.so"
loadmodule "kex.so"
loadmodule "corex.so"
loadmodule "tm.so"
loadmodule "tmx.so"
loadmodule "sl.so"
loadmodule "rr.so"
loadmodule "pv.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "textopsx.so"
loadmodule "siputils.so"
loadmodule "xlog.so"
loadmodule "sanity.so"
loadmodule "ctl.so"
loadmodule "cfg_rpc.so"
loadmodule "acc.so"
loadmodule "counters.so"
loadmodule "dlgs.so"
#!ifdef WITH_AUTH
loadmodule "auth.so"
# 如果启用了认证功能,加载 auth.so 模块
loadmodule "auth_db.so"
# 如果启用了认证功能,加载 auth_db.so 模块
#!ifdef WITH_IPAUTH
loadmodule "permissions.so"
# 如果启用了 IP 认证,加载 permissions.so 模块
#!endif
#!endif
#!ifdef WITH_ALIASDB
loadmodule "alias_db.so"
# 如果启用了别名数据库,加载 alias_db.so 模块
#!endif
#!ifdef WITH_SPEEDDIAL
loadmodule "speeddial.so"
# 如果启用了快速拨号,加载 speeddial.so 模块
#!endif
#!ifdef WITH_MULTIDOMAIN
loadmodule "domain.so"
# 如果启用了多域支持,加载 domain.so 模块
#!endif
#!ifdef WITH_PRESENCE
loadmodule "presence.so"
# 如果启用了存在性支持,加载 presence.so 模块
loadmodule "presence_xml.so"
# 如果启用了存在性支持,加载 presence_xml.so 模块
#!endif
#!ifdef WITH_NAT
loadmodule "nathelper.so"
# 如果启用了 NAT 辅助,加载 nathelper.so 模块
#!ifdef WITH_RTPENGINE
loadmodule "rtpengine.so"
# 如果启用了 RTPEngine,加载 rtpengine.so 模块
#!else
loadmodule "rtpproxy.so"
# 否则加载 rtpproxy.so 模块
#!endif
#!endif
#!ifdef WITH_HTABLE
loadmodule "htable.so"
# 如果启用了哈希表功能,加载 htable.so 模块
#!endif
#!ifdef WITH_ANTIFLOOD
loadmodule "pike.so"
# 如果启用了防洪功能,加载 pike.so 模块
#!endif
#!ifdef WITH_DEBUG
loadmodule "debugger.so"
# 如果启用了调试功能,加载 debugger.so 模块
#!endif
# 第五段
# ----------------- 设置模块特定参数 ---------------
# ----- jsonrpcs 参数 -----
modparam("jsonrpcs", "pretty_format", 1)
# 启用 JSON RPC 的漂亮格式输出
/* 设置 RPC fifo 控制文件路径 */
# modparam("jsonrpcs", "fifo_name", "/run/kamailio/kamailio_rpc.fifo")
/* 设置 RPC unix 套接字控制文件路径 */
# modparam("jsonrpcs", "dgram_socket", "/run/kamailio/kamailio_rpc.sock")
#!ifdef WITH_JSONRPC
modparam("jsonrpcs", "transport", 7)
# 设置 JSON RPC 的传输协议为 7 (通常是 UDP)
#!endif
# ----- ctl 参数 -----
/* 设置 RPC unix 套接字控制文件路径 */
# modparam("ctl", "binrpc", "unix:/run/kamailio/kamailio_ctl")
# ----- sanity 参数 -----
modparam("sanity", "autodrop", 0)
# 禁用自动丢弃检查
# ----- tm 参数 -----
# 自动丢弃之前串行分支
modparam("tm", "failure_reply_mode", 3)
# 设置失败回复模式为 3
# 默认重传超时:30秒
modparam("tm", "fr_timer", 30000)
# 设置重传定时器为 30秒
# 默认 INVITE 重传超时:1xx 消息后 120秒
modparam("tm", "fr_inv_timer", 120000)
# 设置 INVITE 重传定时器为 120秒
# ----- rr 参数 -----
# 设置下一个参数为 1 以便将值添加到 ;lr 参数(有助于某些 UA)
modparam("rr", "enable_full_lr", 0)
# 禁用完整的 lr 参数
# 不将 from tag 附加到路由记录(这个脚本中不需要)
modparam("rr", "append_fromtag", 0)
# 禁用 from tag 的附加
# ----- dlgs 参数 -----
modparam("dlgs", "timer_interval", 10)
# 设置对话定时器间隔为 10秒
modparam("dlgs", "init_lifetime", 180)
# 设置对话初始化生命周期为 180秒
modparam("dlgs", "active_lifetime", 7200)
# 设置活动对话生命周期为 7200秒
modparam("dlgs", "finish_lifetime", 10)
# 设置结束对话生命周期为 10秒
# ----- registrar 参数 -----
modparam("registrar", "method_filtering", 1)
# 启用方法过滤
/* 取消下面的注释以禁用通过位置进行并行分叉 */
# modparam("registrar", "append_branches", 0)
# 禁止每个 AOR 超过 10 个联系人
# modparam("registrar", "max_contacts", 10)
# 设置最大注册过期时间为 3600秒
modparam("registrar", "max_expires", 3600)
# 启用 GRUU(Globally Routable User Agent URI)
modparam("registrar", "gruu_enabled", 0)
# 禁用 Path 处理
modparam("registrar", "use_path", 1)
# 即使不在 Supported 头中列出,也保存 Path
modparam("registrar", "path_mode", 0)
# ----- acc 参数 -----
/* 需要计费的特殊事件? */
modparam("acc", "early_media", 0)
# 禁用早期媒体计费
modparam("acc", "report_ack", 0)
# 禁用 ACK 报告
modparam("acc", "report_cancels", 0)
# 禁用取消请求报告
/* 默认情况下,我们不调整顺序请求的方向。
* 如果启用此参数,请确保在 "rr" 模块中启用 "append_fromtag"
*/
modparam("acc", "detect_direction", 0)
# 禁用请求方向检测
/* 计费触发器(标志) */
modparam("acc", "log_flag", FLT_ACC)
# 记录计费事件
modparam("acc", "log_missed_flag", FLT_ACCMISSED)
# 记录未接通事件
modparam("acc", "log_extra",
# 记录额外的日志信息
"src_user=$fU;src_domain=$fd;src_ip=$si;"
"dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
modparam("acc", "failed_transaction_flag", FLT_ACCFAILED)
# 记录失败事务
/* 增强的数据库计费(如果启用数据库) */
#!ifdef WITH_ACCDB
modparam("acc", "db_flag", FLT_ACC)
# 启用数据库计费标志
modparam("acc", "db_missed_flag", FLT_ACCMISSED)
# 启用数据库未接通标志
modparam("acc", "db_url", DBURL)
# 设置数据库 URL
modparam("acc", "db_extra",
# 记录额外的数据库日志信息
"src_user=$fU;src_domain=$fd;src_ip=$si;"
"dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
#!endif
# ----- usrloc 参数 -----
modparam("usrloc", "timer_interval", 60)
# 设置用户位置定时器间隔为 60秒
modparam("usrloc", "timer_procs", 1)
# 设置用户位置处理进程数为 1
modparam("usrloc", "use_domain", MULTIDOMAIN)
# 启用多域支持
/* 启用数据库持久化存储位置条目 */
#!ifdef WITH_USRLOCDB
modparam("usrloc", "db_url", DBURL)
# 设置数据库 URL
modparam("usrloc", "db_mode", 2)
# 设置数据库模式
#!endif
# ----- auth_db 参数 -----
#!ifdef WITH_AUTH
modparam("auth_db", "db_url", DBURL)
# 设置认证数据库 URL
modparam("auth_db", "calculate_ha1", yes)
# 启用 HA1 计算
modparam("auth_db", "password_column", "password")
# 设置密码列名为 "password"
modparam("auth_db", "load_credentials", "")
# 加载凭证
modparam("auth_db", "use_domain", MULTIDOMAIN)
# 启用多域支持
#!endif
# ----- permissions 参数 -----
#!ifdef WITH_IPAUTH
modparam("permissions", "db_url", DBURL)
# 设置权限数据库 URL
modparam("permissions", "load_backends", 1)
# 加载后端数据库
#!endif
# ----- alias_db 参数 -----
#!ifdef WITH_ALIASDB
modparam("alias_db", "db_url", DBURL)
# 设置别名数据库 URL
modparam("alias_db", "use_domain", MULTIDOMAIN)
# 启用多域支持
#!endif
# ----- speeddial 参数 -----
#!ifdef WITH_SPEEDDIAL
modparam("speeddial", "db_url", DBURL)
# 设置快速拨号数据库 URL
modparam("speeddial", "use_domain", MULTIDOMAIN)
# 启用多域支持
#!endif
# ----- domain 参数 -----
#!ifdef WITH_MULTIDOMAIN
modparam("domain", "db_url", DBURL)
# 设置多域数据库 URL
/* 注册回调函数以匹配自己与域列表的条件 */
modparam("domain", "register_myself", 1)
# 启用自己注册功能
#!endif
#!ifdef WITH_PRESENCE
# ----- presence 参数 -----
modparam("presence", "db_url", DBURL)
# 设置存在性数据库 URL
# ----- presence_xml 参数 -----
modparam("presence_xml", "db_url", DBURL)
# 设置存在性 XML 数据库 URL
modparam("presence_xml", "force_active", 1)
# 强制存在性为活动状态
#!endif
#!ifdef WITH_NAT
#!ifdef WITH_RTPENGINE
# ----- rtpengine 参数 -----
modparam("rtpengine", "rtpengine_sock", "udp:127.0.0.1:2223")
# 设置 RTP 引擎套接字
#!else
# ----- rtpproxy 参数 -----
modparam("rtpproxy", "rtpproxy_sock", "udp:127.0.0.1:7722")
# 设置 RTP 代理套接字
#!endif
# ----- nathelper 参数 -----
modparam("nathelper", "natping_interval", 30)
# 设置 NAT ping 间隔为 30秒
modparam("nathelper", "ping_nated_only", 1)
# 仅 ping 被 NAT 的 IP
modparam("nathelper", "sipping_bflag", FLB_NATSIPPING)
# 启用 NAT ping 标志
modparam("nathelper", "sipping_from", "sip:pinger@kamailio.org")
# 设置 NAT ping 来源地址
# 其他模块需要的 NAT 穿越参数
modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)")
# 处理接收的 AVP
modparam("usrloc", "nat_bflag", FLB_NATB) # 设置 NAT 标志
#!endif
#!ifdef WITH_TLS
# ----- tls 参数 -----
modparam("tls", "config", "/usr/local/etc/kamailio/tls.cfg")
# 设置 TLS 配置文件路径
#!endif
#!ifdef WITH_ANTIFLOOD
# ----- pike 参数 -----
modparam("pike", "sampling_time_unit", 2)
# 设置采样时间单位为 2秒
modparam("pike", "reqs_density_per_unit", 16)
# 设置每单位时间请求密度为 16
modparam("pike", "remove_latency", 4)
# 设置移除延迟为 4
#!endif
#!ifdef WITH_HTABLE
# ----- htable 参数 -----
#!ifdef WITH_ANTIFLOOD
/* 设置 IP 封禁哈希表,自动过期时间为 5 分钟 */
modparam("htable", "htable", "ipban=>size=8;autoexpire=300;")
#!endif
#!endif
#!ifdef WITH_DEBUG
# ----- debugger 参数 -----
modparam("debugger", "cfgtrace", 1)
# 启用配置追踪
modparam("debugger", "log_level_name", "exec")
# 设置调试日志级别为 exec
#!endif
# 第六段
####### 路由逻辑 ########
/* 主SIP请求路由逻辑
* - 处理任何传入的SIP请求都从此路由开始
* - 注意:这与 route { ... } 相同 */
request_route {
# 每个请求的初步检查
route(REQINIT);
# NAT检测
route(NATDETECT);
# 处理CANCEL请求
if (is_method("CANCEL")) {
dlgs_update();
if (t_check_trans()) {
route(RELAY);
}
exit;
}
# 处理重传请求
if (!is_method("ACK")) {
if(t_precheck_trans()) {
t_check_trans();
exit;
}
t_check_trans();
}
# 处理SIP对话中的请求
route(WITHINDLG);
### 仅处理初始请求(没有To标签)
# 认证
route(AUTH);
# 对话形成请求的路由记录(如果它们被路由)
# - 删除预加载的Route头
remove_hf("Route");
if (is_method("INVITE|SUBSCRIBE|REFER")) {
record_route();
}
# 仅对INVITE请求进行计费
if (is_method("INVITE")) {
setflag(FLT_ACC); # 启动计费
}
# 分发请求到外部域
route(SIPOUT);
### 处理本地域的请求
# 处理与Presence相关的请求
route(PRESENCE);
# 处理注册请求
route(REGISTRAR);
# 如果请求中没有用户名,返回地址不完整
if ($rU==$null) {
sl_send_reply("484", "Address Incomplete");
exit;
}
# 初始化INVITE请求的对话
if(is_method("INVITE")) {
dlgs_init("$fu", "$tu", "srcip=$si");
}
# 分发到PSTN目的地
route(PSTN);
# 用户位置服务
route(LOCATION);
return;
}
# 第七段
# 请求转发的包装器
route[RELAY] {
# 为转发的请求启用额外的事件路由
# - 串行分叉,RTP转发处理等
if (is_method("INVITE|BYE|SUBSCRIBE|UPDATE")) {
if(!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH");
}
if (is_method("INVITE|SUBSCRIBE|UPDATE")) {
if(!t_is_set("onreply_route")) t_on_reply("MANAGE_REPLY");
}
if (is_method("INVITE")) {
if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE");
}
# 转发请求,如果失败则返回错误
if (!t_relay()) {
sl_reply_error();
}
exit;
}
# 每个SIP请求的初步检查
route[REQINIT] {
# 不连接用于发送回复
set_reply_no_connect();
# 强制对称信令
# - 将回复发送回请求的源地址
force_rport();
#!ifdef WITH_ANTIFLOOD
# 同一IP的洪泛检测及短时间流量封禁
# 确保排除可信的对等方,如PSTN网关
# - 本地主机排除(例如,环回到自身)
if(src_ip!=myself) {
if($sht(ipban=>$si)!=$null) {
# IP已被封禁
xdbg("请求来自已封禁的IP - $rm from $fu (IP:$si:$sp)\n");
exit;
}
if (!pike_check_req()) {
xalert("警告: Pike 阻止请求 $rm from $fu (IP:$si:$sp)\n");
$sht(ipban=>$si) = 1;
exit;
}
}
#!endif
# 针对扫描器进行静默丢弃 - 若要回复,可以取消注释下一行
if($ua =~ "friendly|scanner|sipcli|sipvicious|VaxSIPUserAgent|pplsip") {
# sl_send_reply("200", "OK");
exit;
}
# 如果最大跳数超限,则返回“Too Many Hops”
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483", "Too Many Hops");
exit;
}
# OPTIONS请求且目标URI为本地地址且没有用户名时,返回“Keepalive”
if(is_method("OPTIONS") && uri==myself && $rU==$null) {
sl_send_reply("200", "Keepalive");
exit;
}
# 如果请求不合法,则记录日志并丢弃
if(!sanity_check("17895", "7")) {
xlog("请求来自非法SIP地址 $si:$sp\n");
exit;
}
}
# 处理SIP对话中的请求
route[WITHINDLG] {
# 如果没有To标签,则不处理
if (!has_totag()) return;
# 对话中的顺序请求应该按照record-routing指定的路径处理
if (loose_route()) {
route(DLGURI);
dlgs_update();
if (is_method("BYE")) {
setflag(FLT_ACC); # 进行计费...
setflag(FLT_ACCFAILED); # ... 即使事务失败也要计费
} else if ( is_method("ACK") ) {
# ACK是无状态转发
route(NATMANAGE);
} else if ( is_method("NOTIFY|REFER") ) {
# 为对话中的NOTIFY和REFER请求添加Record-Route(RFC6665,RFC3515)
record_route();
}
route(RELAY);
exit;
}
# 处理对话中的SUBSCRIBE请求
if (is_method("SUBSCRIBE") && uri == myself) {
route(PRESENCE);
exit;
}
# 处理ACK请求
if ( is_method("ACK") ) {
if ( t_check_trans() ) {
# 无松散路由,但有状态ACK;
# 必须是487后的ACK请求
# 或上游服务器返回404等
route(RELAY);
exit;
} else {
# 没有匹配的事务的ACK请求...忽略并丢弃
exit;
}
}
# 如果无法匹配到请求,返回404
sl_send_reply("404", "Not here");
exit;
}
# 第八段
# 处理SIP注册请求
route[REGISTRAR] {
# 如果请求不是REGISTER方法,则不做处理
if (!is_method("REGISTER")) return;
# 如果存在NAT标志,设置NAT相关标志
if(isflagset(FLT_NATS)) {
setbflag(FLB_NATB);
#!ifdef WITH_NATSIPPING
# 执行SIP NAT ping操作
setbflag(FLB_NATSIPPING);
#!endif
}
# 保存位置,如果保存失败,回复错误
if (!save("location")) {
sl_reply_error();
}
exit;
}
# 用户位置服务
route[LOCATION] {
#!ifdef WITH_SPEEDDIAL
# 查找短号拨号 - 2位数字的分机号
if($rU=~"^[0-9][0-9]$") {
if(sd_lookup("speed_dial")) {
route(SIPOUT);
}
}
#!endif
#!ifdef WITH_ALIASDB
# 在数据库中查找别名
if(alias_db_lookup("dbaliases")) {
route(SIPOUT);
}
#!endif
# 将请求的用户名保存在$avp(oexten)
$avp(oexten) = $rU;
# 查找用户位置,如果查找失败,转至语音信箱
if (!lookup("location")) {
$var(rc) = $rc;
route(TOVOICEMAIL);
t_newtran();
# 根据返回值进行相应处理
switch ($var(rc)) {
case -1:
case -3:
send_reply("404", "Not Found"); # 找不到用户
exit;
case -2:
send_reply("405", "Method Not Allowed"); # 方法不允许
exit;
}
}
# 如果是INVITE请求,设置未接来电标志
if (is_method("INVITE")) {
setflag(FLT_ACCMISSED);
}
# 转发请求
route(RELAY);
exit;
}
# 用户状态服务处理
route[PRESENCE] {
# 如果请求不是PUBLISH或SUBSCRIBE方法,则不做处理
if(!is_method("PUBLISH|SUBSCRIBE")) return;
# 如果是SUBSCRIBE且事件类型为message-summary,转发到语音信箱
if(is_method("SUBSCRIBE") && $hdr(Event)=="message-summary") {
route(TOVOICEMAIL);
# 如果没有配置语音信箱服务器,返回404
sl_send_reply("404", "No voicemail service");
exit;
}
#!ifdef WITH_PRESENCE
#!ifdef WITH_MSGREBUILD
# 如果请求头或消息体被修改,应用更改
msg_apply_changes();
#!endif
# 如果不能创建新事务,回复错误
if (!t_newtran()) {
sl_reply_error();
exit;
}
# 如果是PUBLISH请求,处理发布
if(is_method("PUBLISH")) {
handle_publish();
t_release();
} else if(is_method("SUBSCRIBE")) {
# 如果是SUBSCRIBE请求,处理订阅
handle_subscribe();
t_release();
}
exit;
#!endif
# 如果启用了presence功能,上面部分将不会执行
# 如果是PUBLISH请求或没有用户名,返回404
if (is_method("PUBLISH") || $rU==$null) {
sl_send_reply("404", "Not here");
exit;
}
return;
}
# 第九段
# IP授权和用户认证
route[AUTH] {
#!ifdef WITH_AUTH
#!ifdef WITH_IPAUTH
# 如果请求不是REGISTER且源IP地址被允许,则跳过认证
if((!is_method("REGISTER")) && allow_source_address()) {
# 源IP地址允许
return;
}
#!endif
# 如果是REGISTER请求或者来源URI是本地URI,进行认证
if (is_method("REGISTER") || from_uri==myself) {
# 进行认证检查
if (!auth_check("$fd", "subscriber", "1")) {
auth_challenge("$fd", "0");
exit;
}
# 用户通过认证 - 删除认证头
if(!is_method("REGISTER|PUBLISH"))
consume_credentials();
}
# 如果来电者不是本地订阅者,检查是否呼叫本地目标,否者拒绝
if (from_uri!=myself && uri!=myself) {
sl_send_reply("403", "Not relaying");
exit;
}
#!else
# 未启用认证 - 不允许转发到外部网络
if(uri!=myself) {
sl_send_reply("403", "Not relaying");
exit;
}
#!endif
return;
}
# 来电者NAT检测
route[NATDETECT] {
#!ifdef WITH_NAT
# 如果是NAT用户代理测试
if (nat_uac_test("19")) {
# 如果是REGISTER请求,处理NAT相关注册
if (is_method("REGISTER")) {
fix_nated_register();
} else {
# 如果是第一个跳点,设置联系别名
if(is_first_hop()) {
set_contact_alias();
}
}
setflag(FLT_NATS); # 设置NAT标志
}
#!endif
return;
}
# RTP转发管理和NAT穿越的信令更新
route[NATMANAGE] {
#!ifdef WITH_NAT
# 如果是请求,检查是否为NAT请求
if (is_request()) {
if(has_totag()) {
if(check_route_param("nat=yes")) {
setbflag(FLB_NATB); # 设置NAT标志
}
}
}
# 如果没有设置NAT标志,则不做处理
if (!(isflagset(FLT_NATS) || isbflagset(FLB_NATB))) return;
#!ifdef WITH_RTPENGINE
# 如果是NAT用户代理测试,使用rtpengine管理RTP流
if(nat_uac_test("8")) {
rtpengine_manage("SIP-source-address replace-origin replace-session-connection");
} else {
rtpengine_manage("replace-origin replace-session-connection");
}
#!else
# 如果是NAT用户代理测试,使用rtpproxy管理RTP流
if(nat_uac_test("8")) {
rtpproxy_manage("co");
} else {
rtpproxy_manage("cor");
}
#!endif
# 如果是请求,检查是否需要添加NAT标志
if (is_request()) {
if (!has_totag()) {
if(t_is_branch_route()) {
add_rr_param(";nat=yes");
}
}
}
# 如果是响应,处理NAT穿越相关的设置
if (is_reply()) {
if(isbflagset(FLB_NATB)) {
if(is_first_hop())
set_contact_alias();
}
}
# 如果设置了NAT标志,处理NAT穿越请求
if(isbflagset(FLB_NATB)) {
# 不在涉及NAT穿越的对话中发送连接消息
if (is_request()) {
if(has_totag()) {
set_forward_no_connect();
}
}
}
#!endif
return;
}
# 对话请求URI更新
route[DLGURI] {
#!ifdef WITH_NAT
# 如果没有设置DSTURI,处理URI别名
if(!isdsturiset()) {
handle_ruri_alias();
}
#!endif
return;
}
# 路由到外部域
route[SIPOUT] {
# 如果URI是本地的,则不做处理
if (uri==myself) return;
# 在请求头中添加P-Hint
append_hf("P-Hint: outbound\r\n");
route(RELAY);
exit;
}
# PSTN网关路由
route[PSTN] {
#!ifdef WITH_PSTN
# 检查PSTN网关IP是否定义
if (strempty($sel(cfg_get.pstn.gw_ip))) {
xlog("SCRIPT: PSTN routing enabled but pstn.gw_ip not defined\n");
return;
}
# 路由到以'+'或'00'开头的PSTN号码(国际格式)
# - 更新条件以匹配您的PSTN路由规则
if(!($rU=~"^(\+|00)[1-9][0-9]{3,20}$")) return;
# 只允许本地用户拨打
if(from_uri!=myself) {
sl_send_reply("403", "Not Allowed");
exit;
}
# 为PSTN网关标准化目标号码
# - 将开头的00转换为+
if (starts_with("$rU", "00")) {
strip(2);
prefix("+");
}
# 如果PSTN网关端口未定义,使用默认端口
if (strempty($sel(cfg_get.pstn.gw_port))) {
$ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip);
} else {
$ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip) + ":" + $sel(cfg_get.pstn.gw_port);
}
route(RELAY);
exit;
#!endif
return;
}
# JSONRPC over HTTP(S) 路由
#!ifdef WITH_JSONRPC
event_route[xhttp:request] {
# 设置回复头
set_reply_close();
set_reply_no_connect();
# 仅允许来自本地主机的请求
if(src_ip!=127.0.0.1) {
xhttp_reply("403", "Forbidden", "text/html", "<html><body>Not allowed from $si</body></html>");
exit;
}
# 如果请求URI匹配RPC,分发JSONRPC请求
if ($hu =~ "^/RPC") {
jsonrpc_dispatch();
exit;
}
# 如果URL不匹配,返回错误
xhttp_reply("200", "OK", "text/html", "<html><body>Wrong URL $hu</body></html>");
exit;
}
#!endif
# 路由到语音信箱服务器
route[TOVOICEMAIL] {
#!ifdef WITH_VOICEMAIL
# 如果请求方法不是INVITE或SUBSCRIBE,跳过
if(!is_method("INVITE|SUBSCRIBE")) return;
# 检查语音信箱服务器IP是否定义
if (strempty($sel(cfg_get.voicemail.srv_ip))) {
xlog("SCRIPT: VoiceMail routing enabled but IP not defined\n");
return;
}
# 如果是INVITE请求,处理目标为语音信箱
if(is_method("INVITE")) {
if($avp(oexten)==$null) return;
$ru = "sip:" + $avp(oexten) + "@" + $sel(cfg_get.voicemail.srv_ip) + ":" + $sel(cfg_get.voicemail.srv_port);
} else {
if($rU==$null) return;
$ru = "sip:" + $rU + "@" + $sel(cfg_get.voicemail.srv_ip) + ":" + $sel(cfg_get.voicemail.srv_port);
}
route(RELAY);
exit;
#!endif
return;
}
# 管理外部分支
branch_route[MANAGE_BRANCH] {
# 打印新分支的调试信息
xdbg("new branch [$T_branch_idx] to $ru\n");
route(NATMANAGE);
return;
}
# 管理传入回复
reply_route {
# 检查回复是否符合预期
if(!sanity_check("17604", "6")) {
xlog("Malformed SIP response from $si:$sp\n");
drop;
}
return;
}
# 管理事务上下文中的回复
onreply_route[MANAGE_REPLY] {
# 打印回复调试信息
xdbg("incoming reply\n");
# 如果回复状态码为2xx或1xx,处理NAT管理
if(status=~"[12][0-9][0-9]") {
route(NATMANAGE);
}
return;
}
# 管理失败路由情况
failure_route[MANAGE_FAILURE] {
# 处理NAT管理
route(NATMANAGE);
# 如果事务被取消,退出
if (t_is_canceled()) exit;
#!ifdef WITH_BLOCK3XX
# 基于3xx回复阻止呼叫重定向
if (t_check_status("3[0-9][0-9]")) {
t_reply("404", "Not found");
exit;
}
#!endif
#!ifdef WITH_BLOCK401407
# 基于401和407回复阻止呼叫重定向
if (t_check_status("401|407")) {
t_reply("404", "Not found");
exit;
}
#!endif
#!ifdef WITH_VOICEMAIL
# 串行分叉
# - 在忙音或无应答时转发到语音信箱
if (t_check_status("486|408")) {
$du = $null;
route(TOVOICEMAIL);
exit;
}
#!endif
return;
}
更多推荐




所有评论(0)