Kamailio usrloc 细节测试

版本 kamailio 5.7.x

IP 地址 192.168.43.68

窥视 usrloc 细节,重点是内存跟数据库的同步

慢慢测试,慢慢写


ul.rm vs ul.rm_contact

这二个不一样,比如 eyebeam 以 1000 注册,同时 microsip 也以 1000 注册

执行 ul.rm location 1000@192.168.43.68

就把 eyebeam 和 microsip 都删除掉了

ul.rm_contact 可以按需删除,比如只删除 eybeam

下面是例子:

eyebeam 注册,

ul.dump 得知 Address: sip:1000@192.168.43.68:57492;rinstance=020b7ff3f71cb288

ul.rm_contact location 1000@192.168.43.68 sip:1000@192.168.43.68:57492;rinstance=020b7ff3f71cb288

就成功删除了 eyebeam


ul.rm 和删表

ul.rm 之后内存里面已经找不到 eyebeam, 但 location 表是不是马上就删除 eybeam?

配置下面几个参数,进行测试:

modparam("usrloc", "timer_interval", 3600) # 这么大仅仅 是为了测试,生产上不建议

modparam("usrloc", "timer_procs", 1)

modparam("usrloc", "use_domain", MULTIDOMAIN)

modparam("usrloc", "db_url", DBURL)

modparam("usrloc", "db_mode", 1)

modparam("usrloc", "db_timer_clean", 1)

modparam("usrloc", "handle_lost_tcp", 1)

modparam("usrloc", "close_expired_tcp", 1)

结果是 ul.rm 之后, location 表马上就删除了 eyebeam


注册过期和删表

eybeam 用 tcp 方式注册

之后在任务管理器里面删除 eyebeam

测试的结果是 ul.dump 等到过期后 Expires 的值是 expired,但 location 表里面照样有 eyebeam, 要等到 timer_interval 到期才会自动删表

在路由里面处理注册过期事件,调用 ul.rm_contact 才能起到删表的目的(ul.flush也可,强迫缓存写表)

到底要怎样做,回头再补充

基本的思路是:

检查 save 返回值,如果是新注册,就要记录下来

加载 tcpops 模块,tcp 事件里面,如果是 close 或者是 reset, 调用 ul.rm_contact

当然,如果是 udp 注册,就要使能 usrloc 的 ka_mode 参数(这个暂时不做测试,我的客户主要用 JsSIP)


路由处理

usrloc 模块同上

loadmodule "tcpops.so"

loadmodule "htable.so"

loadmodule "jansson.so"

modparam("registrar", "method_filtering", 1)

/* uncomment the next line to disable parallel forking via location */

modparam("registrar", "append_branches", 0)

/* uncomment the next line not to allow more than 10 contacts per AOR */

modparam("registrar", "max_contacts", 10)

/* max value for expires of registrations */

modparam("registrar", "max_expires", 3600)

/* set it to 1 to enable GRUU */

modparam("registrar", "gruu_enabled", 0)

/* set it to 0 to disable Path handling */

modparam("registrar", "use_path", 1)

/* save Path even if not listed in Supported header */

modparam("registrar", "path_mode", 0)

modparam("registrar", "xavp_cfg", "reg")

modparam("registrar", "xavp_rcd", "ulrcd")

modparam("registrar", "case_sensitive", 1)

modparam("registrar", "xavp_rcd_mask", 0)

modparam("htable", "htable", "tcpusrloc=>size=8;autoexpire=3600;")

Handle SIP registrations

route[REGISTRAR] {

if (!is_method("REGISTER")) return;

if(isflagset(FLT_NATS)) {

setbflag(FLB_NATB);

#!ifdef WITH_NATSIPPING

do SIP NAT pinging

setbflag(FLB_NATSIPPING);

#!endif

}

if (!save("location")) {

sl_reply_error();

}

if ((rc == 1) \|\| (rc == 2)){

xnotice("ruid = $xavp(ulrcd[0]=>ruid)\n");

xnotice("contact = $xavp(ulrcd[0]=>contact)\n");

if(reg_fetch_contacts("location", "$fu", "caller")){

$avp(i) = 0;

while(avp(i) \< (ulc(caller=>count))){

#xnotice("i=$avp(i)\n");

xnotice("$xavp(ulrcd[0]=>ruid)\n");

xnotice("(ulc(caller=\>ruid)\[avp(i)])");

if(xavp(ulrcd\[0\]=\>ruid) == (ulc(caller=>ruid)[$avp(i)])) {

avp(aor) = _s(fU@fd);

avp(conid) = (ulc(caller=>conid)[$avp(i)]);

if (avp(conid) == null) {

xnotice("udpconn\n");

} else {

avp(k) = avp(conid);

avp(v) = _s({"contact": "xavp(ulrcd\[0\]=\>contact)", "aor": "avp(aor)"});

sht(tcpusrloc=\>avp(k)) = $avp(v);

xnotice("tcpconn\n");

}

}

avp(i) = avp(i) + 1;

}

reg_free_contacts("caller");

} else {

xerr("reg_fetch_contacts err\n");

}

}

exit;

}

eyebeam tcp 注册

kamcmd htable.dump tcpusrloc

{

entry: 55

size: 1

slot: {

{

name: 1

value: {"contact": "sip:1000@192.168.43.68:54071;transport=TCP;rinstance=e65785e1e29b4605", "aor": "1000@192.168.43.68"}

type: str

}

}

}

event_route[tcp:closed] {

xlog("L_INFO", "proto connection closed (conid)\n");

route(rm_contact);

}

event_route[tcp:timeout] {

xlog("L_INFO", "proto connection timed out (conid)\n");

route(rm_contact);

}

event_route[tcp:reset] {

xlog("L_INFO", "proto connection reset by peer (conid)\n");

route(rm_contact);

}

route[rm_contact] {

avp(k) = conid;

avp(j) = sht(tcpusrloc=>$avp(k));

if (avp(j) == null){

return;

}

xnotice("rm_contact, json = $avp(j)\n");

if (!jansson_get("contact", avp(j), "avp(contact)")) {

return;

}

xnotice("contact = $avp(contact)\n");

if (!jansson_get("aor", avp(j), "avp(aor)")) {

return;

}

xnotice("aor = $avp(aor)\n" );

rpc

jansson_set("string", "jsonrpc", "2.0", "$avp(req)");

jansson_set("string", "method", "ul.rm_contact", "$avp(req)");

$avp(params) = "[]";

jansson_append("string", "", "location", "$avp(params)");

jansson_append("string", "", "avp(aor)", "avp(params)");

jansson_append("string", "", "avp(contact)", "avp(params)");

jansson_set("array", "params", avp(params), "avp(req)");

xnotice("req = $avp(req)\n");

jsonrpc_exec("$avp(req)");

xinfo("code = $jsonrpl(code)\n");

xinfo("body = $jsonrpl(body)\n");

}

逻辑看起来没有问题,但实际执行起来,不对

req = {"jsonrpc":"2.0","method":"ul.rm_contact","params":["location","1000@192.168.43.61","sip:1000@192.168.43.68:60146;transport=TCP;rinstance=1d88e94f64296775"]}

<core> [db.c:489]: db_use_table(): invalid connection parameter

usrloc [ucontact.c:1602]: db_delete_ucontact_ruid(): sql use_table failed

usrloc [urecord.c:656]: delete_ucontact(): failed to remove contact from database

有可能 tcp事件路由里面不能调用 rpc, 我不太确定


引人 mqueue 模块,完美解决,哈哈

loadmodule "mqueue.so"

loadmodule "rtimer.so"

modparam("mqueue", "mqueue", "name=myq;size=20;")

modparam("rtimer", "timer", "name=nsqt;interval=1;mode=1;")

modparam("rtimer", "exec", "timer=nsqt;route=RUN_CDR_PUBLISH")

。。。

细节不再提供,别再等了

相关推荐
liulilittle1 天前
OPENPPP2 Code Analysis One
网络·c++·网络协议·信息与通信·通信
无名3872 天前
Kamailio registrar 模块 aor 大小写的问题
通信
liulilittle2 天前
XDP VNP虚拟以太网关(章节:一)
linux·服务器·开发语言·网络·c++·通信·xdp
liulilittle2 天前
OPENPPP2 Code Analysis Two
网络·c++·网络协议·信息与通信·通信
liulilittle2 天前
XDP VNP虚拟以太网关(章节:三)
网络·c++·网络协议·信息与通信·通信·xdp
liulilittle3 天前
XDP VNP虚拟以太网关(章节:二)
linux·服务器·网络·c++·通信·xdp
无名3878 天前
关于 RTP/AVPF 的简单讨论
通信
Deepoch9 天前
算法定义未来:Deepoc-M重构通信技术新生态
人工智能·通信·具身模型·deepoc
xixixi7777713 天前
进一步了解一下现代数字经济的核心动脉——DCI(数据中心互联 )
网络·数据库·安全·光通信·数据·通信·dci
SunkingYang16 天前
MFC进程间消息通信深度解析:SendMessage、PostMessage与SendNotifyMessage的底层实现与实战指南
c++·mfc·共享内存·通信·postmessage·sendmessage·进程间