You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Kamailio Python KEMI执行SIP注册时遇usrloc domain未找到错误

Kamailio Python KEMI执行SIP注册报错:usrloc domain [location] not found

问题描述

使用Python KEMI Interpreter执行简单SIP注册时触发错误,日志输出:

ERROR: register [api.c:44]: regapi_save(): usrloc domain [location] not found.

但改用Kamailio原生脚本编写注册逻辑时,注册流程可以正常完成。

配置与代码

kamailio.cfg 配置

#!KAMAILIO

debug=2
log_stderror=yes
fork=yes
children=2

memdbg=5
memlog=5

#!define DBURL "mysql://kamailio:xxxxxxxxx@localhost/kamailio"

loadmodule "auth.so"
loadmodule "auth_db.so"
loadmodule "db_mysql.so"
loadmodule "debugger.so"
loadmodule "tm.so"
loadmodule "tmx.so"
loadmodule "pv.so"
loadmodule "textops.so"
loadmodule "sl.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "ctl.so"
loadmodule "kex.so"
loadmodule "jsonrpcs.so"
loadmodule "nathelper.so"
loadmodule "siputils.so"
loadmodule "rr.so"
loadmodule "xlog.so"
loadmodule "maxfwd.so"
loadmodule "pv_headers.so"
loadmodule "acc.so"
loadmodule "kemix.so"
loadmodule "regex.so"
loadmodule "sanity.so"
loadmodule "path.so"

modparam("xlog", "force_color", 1)
modparam("xlog", "prefix", "-xlog: ")

loadmodule "app_python3.so"
modparam("app_python3", "load", "/etc/kamailio/kemi.py")
cfgengine "python"          

modparam("auth_db", "db_url", DBURL);

modparam("usrloc", "db_url", DBURL);
modparam("usrloc", "db_mode", 1);

// 注释掉的原生脚本注册逻辑(可正常工作)
// request_route {
//         if (is_method("REGISTER")) {
//                 route(AUTH);
//         }
// }

// route[AUTH] {
//             xlog("L_INFO", "
fd =  $fd
ru = $ru
uri = $var(uri)
");
//             if (!auth_check("$fd", "subscriber", "1")) {
//                     force_rport();
//                     auth_challenge("$fd", "1");
//                     exit;
//             }
//             force_rport();
//             save("location");
//             exit;
// }

kemi.py 核心代码

def mod_init():
    KSR.info("===== from Python mod init\n")
    return kamailio()

class kamailio:
    def __init__(self):
        KSR.info('===== kamailio.__init__\n')
        self.db = DataBase()

    def child_init(self, rank):
        KSR.info('===== kamailio.child_init(%d)\n' % rank)
        return 0

    def ksr_request_route(self, msg):
        if KSR.is_method("REGISTER"):
            fd = KSR.pv.get("$fd")
            KSR.info("\nfd = %s" % fd+"\n")

            is_registered = KSR.auth_db.auth_check(fd, "subscriber", 1)
            if is_registered < 0:
                KSR.force_rport()
                auth_challenge = KSR.auth.auth_challenge(fd, 1)
                exit()
                
            KSR.force_rport()
            if not KSR.registrar.save("location", 0x01):
                KSR.sl.sl_reply_error()
            return 1

问题原因与解决方案

1. 错误根源

Python KEMI的registrar.saveAPI参数定义与原生Kamailio脚本的save()函数存在差异:

  • 原生脚本中save("location")是约定俗成的用法,实际是指定使用usrloc模块存储注册信息;
  • 但Python KEMI的registrar.save第一个参数要求传入usrloc的域(domain),而不是模块标识。传入"location"会被当作不存在的域,因此触发错误。

2. 修复步骤

(1)修正registrar.save的参数

将调用中的第一个参数改为空字符串(表示使用请求SIP URI中的域名作为usrloc域),或直接传入你的Kamailio服务器域名:

# 原代码
# if not KSR.registrar.save("location", 0x01):
# 修改后
if not KSR.registrar.save("", 0x01):

(2)替换错误的exit()调用

代码中使用Python内置的exit()会直接终止Kamailio子进程,需改用KEMI提供的KSR.exit():

# 原代码
# exit()
# 修改后
KSR.exit()

修复后的完整ksr_request_route方法

def ksr_request_route(self, msg):
    if KSR.is_method("REGISTER"):
        fd = KSR.pv.get("$fd")
        KSR.info("\nfd = %s\n" % fd)

        is_registered = KSR.auth_db.auth_check(fd, "subscriber", 1)
        if is_registered < 0:
            KSR.force_rport()
            KSR.auth.auth_challenge(fd, 1)
            KSR.exit()
            
        KSR.force_rport()
        if not KSR.registrar.save("", 0x01):
            KSR.sl.sl_reply_error()
        return 1

完成以上修改后,SIP注册流程即可正常执行。

内容的提问来源于stack exchange,提问作者KPA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 07:19:58