You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

136 lines
4.9 KiB

######## 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");
$uac_req(method)="OPTIONS";
$uac_req(hdrs) = "X-TM-Local: PRESENCE_ROUTE_NAT_PING\r\nX-TM-Contact: " + $xavp(ra=>local_contact) + "\r\n";
$uac_req(turi) = $xavp(ra=>contact);
$uac_req(ruri) = $xavp(ra=>contact);
$uac_req(furi) = $_s(PRESENCE_NAT_S_FROM_URI;nat_id=$xavp(ra=>id));
$uac_req(ouri) = "sip:127.0.0.1:5090;transport=tcp";
$uac_req(callid) = $var(CallId);
uac_req_send();
}
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 = $(fu{uri.param,nat_id}););
xlog("L_DEBUG", "$ci|nat|NAT UPDATE SQL => '$var(Query)'\n");
mq_add("presence_last_notity", "$uuid(g)", "$var(Query)");
t_drop();
}
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 = $(fu{uri.param,nat_id}););
xlog("L_DEBUG", "$ci|nat|NAT REMOVE SQL => '$var(Query)'\n");
mq_add("presence_last_notity", "$uuid(g)", "$var(Query)");
t_drop();
}
route[PRESENCE_ROUTE_NAT_PING]
{
$fs = $(hdr(X-TM-Contact){uri.tosocket});
remove_hf_re("^X-TM-Contact");
force_rport();
handle_ruri_alias();
record_route();
xlog("L_DEBUG", "$ci|local|sending nat keepalive from $fu to $ru => $du => $tu\n");
t_on_reply("PRESENCE_NAT_REPLY");
t_on_failure("PRESENCE_NAT_FAULT");
t_set_fr(0, PRESENCE_NAT_TIMEOUT);
t_relay();
}
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;
}