|
|
|
@ -0,0 +1,122 @@ |
|
|
|
######## Presence NAT ######## |
|
|
|
|
|
|
|
modparam("htable", "htable", "keepalive=>size=32;autoexpire=3600;initval=0;") |
|
|
|
|
|
|
|
#!trydef KZ_PRESENCE_KEEPALIVE_UDP_ONLY 0 |
|
|
|
#!trydef PRESENCE_NAT_TIMERS 4 |
|
|
|
#!trydef PRESENCE_NAT_INTERVAL 30 |
|
|
|
#!trydef PRESENCE_NAT_SKIP_REGISTERED 1 |
|
|
|
#!trydef PRESENCE_NAT_FROM_URI sip:keepalive@MY_HOSTNAME |
|
|
|
#!trydef PRESENCE_NAT_TIMEOUT 3500 |
|
|
|
|
|
|
|
#!substdef "!PRESENCE_NAT_S_FROM_URI!sip:keepalive@MY_HOSTNAME!g" |
|
|
|
#!substdef "!PRESENCE_NAT_S_TIMERS!$def(PRESENCE_NAT_TIMERS)!g" |
|
|
|
|
|
|
|
kazoo.presence_keepalive_udp_only = KZ_PRESENCE_KEEPALIVE_UDP_ONLY descr "should we keepalive nat phones for udp only" |
|
|
|
kazoo.presence_keepalive_skip_registered = PRESENCE_NAT_SKIP_REGISTERED descr "skip if there's a registered contact from same ip/port (avoids multiple pings)" |
|
|
|
|
|
|
|
modparam("rtimer", "timer", "name=presence_nat_timer;interval=1;mode=PRESENCE_NAT_S_TIMERS;") |
|
|
|
modparam("rtimer", "exec", "timer=presence_nat_timer;route=PRESENCE_NAT_TIMER") |
|
|
|
|
|
|
|
####### Presence Logic ######## |
|
|
|
|
|
|
|
route[PRESENCE_NAT] |
|
|
|
{ |
|
|
|
#!ifdef NAT_TRAVERSAL_ROLE |
|
|
|
if (isflagset(FLT_NATS)) { |
|
|
|
$xavp(regcfg=>match_received) = $su; |
|
|
|
if(!( ($sel(cfg_get.kazoo.presence_keepalive_udp_only) == 1 && $proto != "udp") |
|
|
|
|| ($proto == "ws" || $proto == "wss") |
|
|
|
#!ifdef REGISTRAR_ROLE |
|
|
|
|| ($sel(cfg_get.kazoo.presence_keepalive_skip_registered) == 1 && registered("location", "$rz:$Au", 2, 1) == 1) |
|
|
|
#!endif |
|
|
|
)) { |
|
|
|
$var(slot) = $(subs(contact){s.corehash, PRESENCE_NAT_S_TIMERS}); |
|
|
|
$var(sql) = $_s(INSERT OR IGNORE INTO presence_nat (contact, local_contact, slot) values("$subs(contact)", "$subs(local_contact)", $var(slot))); |
|
|
|
mq_add("presence_last_notity", "$ci", "$var(sql)"); |
|
|
|
} |
|
|
|
} |
|
|
|
#!endif |
|
|
|
|
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
route[PRESENCE_NAT_TIMER] |
|
|
|
{ |
|
|
|
$var(Query) = $_s(UPDATE presence_nat SET selected = 1 WHERE slot = $rtimer_worker AND selected = 0 AND time_sent < datetime('now', '-$def(PRESENCE_NAT_INTERVAL) seconds')); |
|
|
|
$var(sqlres) = sql_query("cb", "$var(Query)"); |
|
|
|
if($var(sqlres) < 0) { |
|
|
|
xlog("L_ERROR", "$rtimer_worker|log|error running query : $var(Query)\n"); |
|
|
|
} else { |
|
|
|
$var(nrows) = $sqlrows(cb); |
|
|
|
xlog("L_DEBUG", "$rtimer_worker|log|selected $var(nrows) endpoints to ping\n"); |
|
|
|
} |
|
|
|
|
|
|
|
$var(Query) = $_s(SELECT id, contact, local_contact from presence_nat WHERE slot = $rtimer_worker AND selected = 1); |
|
|
|
xlog("L_DEBUG", "$rtimer_worker|timer|SQL => $var(Query)\n"); |
|
|
|
if (sql_xquery("cb", "$var(Query)", "ra") == 1) |
|
|
|
{ |
|
|
|
while($xavp(ra) != $null) { |
|
|
|
$var(loop) = 0; |
|
|
|
while($xavp(ra) != $null && $var(loop) < MAX_WHILE_LOOPS) { |
|
|
|
route(PRESENCE_NAT_PING); |
|
|
|
pv_unset("$xavp(ra)"); |
|
|
|
$var(loop) = $var(loop) + 1; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
$var(Query) = $_s(UPDATE presence_nat SET selected = 2 WHERE slot = $rtimer_worker AND selected = 1); |
|
|
|
$var(sqlres) = sql_query("cb", "$var(Query)"); |
|
|
|
if($var(sqlres) < 0) { |
|
|
|
xlog("L_ERROR", "$rtimer_worker|log|error running query : $var(Query)\n"); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
route[PRESENCE_NAT_PING] |
|
|
|
{ |
|
|
|
$var(CallId) = $uuid(g); |
|
|
|
xlog("L_DEBUG", "$var(CallId)|$rtimer_worker|timer|SENDING PING FROM $(xavp(ra=>local_contact){uri.tosocket}) TO => $xavp(ra=>contact)\n"); |
|
|
|
t_uac_send("OPTIONS", "$xavp(ra=>contact)", "", "$(xavp(ra=>local_contact){uri.tosocket})", "CSeq: 1 OPTIONS\r\nFrom: PRESENCE_NAT_S_FROM_URI\r\nTo: $xavp(ra=>contact);nat_id=$xavp(ra=>id)\r\nContact: <$xavp(ra=>local_contact)>\r\nCall-ID: $var(CallId)\r\n", ""); |
|
|
|
} |
|
|
|
|
|
|
|
onreply_route[PRESENCE_NAT_REPLY] |
|
|
|
{ |
|
|
|
xlog("L_DEBUG", "$ci|nat|NAT REPLY $(tu{nameaddr.uri})\n"); |
|
|
|
$var(Query) = $_s(UPDATE presence_nat SET selected = 0, time_sent = datetime('now') WHERE id = $(tu{uri.param,nat_id});); |
|
|
|
xlog("L_DEBUG", "$ci|nat|NAT UPDATE SQL => '$var(Query)'\n"); |
|
|
|
mq_add("presence_last_notity", "$uuid(g)", "$var(Query)"); |
|
|
|
} |
|
|
|
|
|
|
|
failure_route[PRESENCE_NAT_FAULT] |
|
|
|
{ |
|
|
|
xlog("L_WARNING", "$ci|nat|received error $T_reply_code $T_reply_reason from $(tu{nameaddr.uri})\n"); |
|
|
|
$var(Query) = $_s(DELETE FROM presence_nat WHERE id = $(tu{uri.param,nat_id});); |
|
|
|
xlog("L_DEBUG", "$ci|nat|NAT REMOVE SQL => '$var(Query)'\n"); |
|
|
|
mq_add("presence_last_notity", "$uuid(g)", "$var(Query)"); |
|
|
|
} |
|
|
|
|
|
|
|
route[PRESENCE_LOCAL_REQ_NAT] |
|
|
|
{ |
|
|
|
#!ifdef NAT_TRAVERSAL_ROLE |
|
|
|
if($rm == "OPTIONS" && $fu == "PRESENCE_NAT_S_FROM_URI") { |
|
|
|
t_on_reply("PRESENCE_NAT_REPLY"); |
|
|
|
t_on_failure("PRESENCE_NAT_FAULT"); |
|
|
|
t_set_fr(0, PRESENCE_NAT_TIMEOUT); |
|
|
|
handle_ruri_alias(); |
|
|
|
record_route(); |
|
|
|
} |
|
|
|
#!endif |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
route[PRESENCE_NAT_ON_REGISTRATION] |
|
|
|
{ |
|
|
|
#!ifdef NAT_TRAVERSAL_ROLE |
|
|
|
$var(Query) = $_s(DELETE FROM presence_nat WHERE contact like "$xavp(ulrcd=>contact)%";); |
|
|
|
mq_add("presence_last_notity", "$uuid(g)", "$var(Query)"); |
|
|
|
#!endif |
|
|
|
return; |
|
|
|
} |