Trying to implement calllimits with the dialog module I can reproduce a hanging dialog using a Linksys 962 by calling itself. When trying to answer the call the INVITES end in a 200 OK but the call is terminated [linksys.txt].
That might be a bug in the 962, but the bad part is the dialog will be kept in kamailio even though keep alives are enabled. OPTIONS are not being sent to detect this dead dialog. If this devices calls an other device (either registered to this kamailio or to the PSTN) KA work like configured (they are being send to this device). Severing the connection will be detected and the dialog will be removed. But when source and destination is the same device, no OPTIONS are sent.
About 1 hour later the dialog is still there:
# kamctl mi dlg_list dialog:: hash=3456:6742 state:: 3 ref_count:: 2 timestart:: 1371572203 timeout:: 68536211 callid:: 86a23723-4b71d5ad@localhost from_uri:: sip:anonymous@localhost from_tag:: 1736b8ab3ea801c5o0 caller_contact:: sip:+31880100781@10.0.34.226:17852 caller_cseq:: 102 caller_route_set:: caller_bind_addr:: udp:10.0.32.42:5060 callee_bind_addr:: udp:10.0.32.42:5060 to_uri:: sip:0880100781@10.0.32.42 to_tag:: 195218c1d50330b5i0 callee_contact:: sip:+31880100781@10.0.34.226:17852 callee_cseq:: 102 callee_route_set::
A part of syslog with debug=4 for above dialog is attached (not the same dialog as the attached linksys capture).
Relevant kamailio.cfg parts:
modparam("dialog","dlg_flag",4) modparam("dialog","hash_size",4096) modparam("dialog","enable_stats",1) modparam("dialog","db_url",DBURL) modparam("dialog","db_mode", 2) modparam("dialog","db_update_period", 15) modparam("dialog","profiles_with_value","channelsinbound;channelsoutbound") modparam("dialog","profiles_no_value", "all") modparam("dialog","dlg_match_mode", 1) modparam("dialog","send_bye", 1) modparam("dialog","default_timeout", 43200) modparam("dialog","ka_timer", 45) modparam("dialog","ka_interval", 45)
routes to DIALIOG in request_route for CANCEL and before route(SIPOUT)
request_route {
# per request initial checks route(REQINIT);
# NAT detection route(NATDETECT);
# CANCEL processing if (is_method("CANCEL")) { route(DIALOG);
if (t_check_trans()) { t_relay(); }
exit; } [...] route(DIALOG);
# dispatch requests to foreign domains route(SIPOUT);
routes to DIALOG within WITHINDLG
# Handle requests within SIP dialogs route[WITHINDLG] { if (has_totag()) { # sequential request withing a dialog should # take the path determined by record-routing if (loose_route()) { route(DLGURI); if (is_method("BYE")) { route(DIALOG); [...] route(RELAY); } else { route(DIALOG); [...] exit; } }
# active calls/dialog management route[DIALOG] { if (is_method("CANCEL|ACK|BYE") || (has_totag() && is_method("INVITE| BYE"))) { dlg_manage(); return; }
if (is_method("INVITE") && !has_totag()) { if($avp(dst_maxchannels)) { route(MAXCALLSINBOUND); }
if($avp(src_maxchannels)) { route(MAXCALLSOUTBOUND); }
dlg_manage(); } }
route[MAXCALLSOUTBOUND] { if(method=="INVITE") { if($au!=$null && $avp(src_maxchannels)>0) { $var(channelsinbound) = 0; $var(channelsoutbound) = 0; get_profile_size("channelsinbound", "$au", "$var(channelsinbound)"); get_profile_size("channelsoutbound", "$au", "$var(channelsoutbound)");
if(($var(channelsinbound)+$var(channelsoutbound))>=$avp(src_maxchannels)) { send_reply("403","Call limit reached"); exit; }
set_dlg_profile("channelsoutbound","$au"); dlg_set_property("ka-src"); } }
return; }
route[MAXCALLSINBOUND] { if(method=="INVITE") { if($avp(dst_maxchannels)>0) { $var(channelsinbound) = 0; $var(channelsoutbound) = 0; get_profile_size("channelsinbound", "$rU", "$var(channelsinbound)"); get_profile_size("channelsoutbound", "$rU", "$var(channelsoutbound)");
if(($var(channelsinbound)+$var(channelsoutbound))>=$avp(dst_maxchannels)) { route(CALLREDIRECT);
route(TOVOICEMAIL);
send_reply("486","Call limit reached"); exit; }
set_dlg_profile("channelsinbound","$rU"); dlg_set_property("ka-dst"); } }
return; }
version: kamailio 4.0.2 (x86_64/linux) flags: STATS: Off, USE_IPV6, USE_TCP, USE_TLS, TLS_HOOKS, USE_RAW_SOCKS, DISABLE_NAGLE, USE_MCAST, DNS_IP_HACK, SHM_MEM, SHM_MMAP, PKG_MALLOC, USE_FUTEX, FAST_LOCK-ADAPTIVE_WAIT, USE_DNS_CACHE, USE_DNS_FAILOVER, USE_NAPTR, USE_DST_BLACKLIST, HAVE_RESOLV_RES ADAPTIVE_WAIT_LOOPS=1024, MAX_RECV_BUFFER_SIZE 262144, MAX_LISTEN 16, MAX_URI_SIZE 1024, BUF_SIZE 65535, DEFAULT PKG_SIZE 4MB poll method support: poll, epoll_lt, epoll_et, sigio_rt, select. id: unknown compiled on 11:28:09 Jun 17 2013 with gcc 4.7.2