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")

。。。

细节不再提供,别再等了

相关推荐
xixixi777771 天前
App反诈骗:一场面向移动生态的深度安全战争(接上文短信反诈)
安全·信息与通信·通信·电话反诈
无名3875 天前
FusionPBX Debian 12 安装
运维·debian·通信
交换机路由器测试之路7 天前
什么是网络直径
网络·以太网·交换机·通信
无名38710 天前
RTPEngine 官方自带的 perl 测试程序
开发语言·perl·通信
xixixi7777710 天前
讲一下卫星移动通信网络(系统架构、核心技术与协议挑战及应用场景和战略价值)
网络·学习·安全·信息与通信·通信·卫星通信
xixixi7777711 天前
移动通信的基石——公共陆地移动网络
大数据·网络·安全·通信·plmn
xixixi7777711 天前
解析常见的通信流量和流量分析
运维·开发语言·网络·安全·php·通信·流量
无名38711 天前
用 Gemini 2.5 Pro 产生 RTPEngine perl 测试程序
通信
闲人编程12 天前
WebSocket实时通信协议深度解析
网络·websocket·网络协议·安全·通信·codecapsule