Browse Source

presence nat

4.3
lazedo 7 years ago
committed by Luis Azedo
parent
commit
4cad20d6d4
9 changed files with 171 additions and 35 deletions
  1. +3
    -0
      kamailio/db_scripts/db_extra_check.sql
  2. +10
    -0
      kamailio/db_scripts/db_init_presence_nat.sql
  3. +12
    -1
      kamailio/db_scripts/db_kazoo-specific
  4. +2
    -1
      kamailio/default.cfg
  5. +1
    -1
      kamailio/nat-traversal-role.cfg
  6. +122
    -0
      kamailio/presence-nat.cfg
  7. +3
    -1
      kamailio/presence-notify.cfg
  8. +14
    -31
      kamailio/presence-role.cfg
  9. +4
    -0
      kamailio/registrar-role.cfg

+ 3
- 0
kamailio/db_scripts/db_extra_check.sql View File

@ -23,4 +23,7 @@ KazooDB -db ${DB_CURRENT_DB} "drop table if exists tmp_probe;"
KazooDB -db ${DB_CURRENT_DB} "create table tmp_probe as select distinct a.event, a.presentity_uri, cast(2 as integer) action from presentities a inner join active_watchers b on a.presentity_uri = b.presentity_uri and a.event = b.event where state in('early', 'confirmed', 'onthephone', 'busy');"
KazooDB -db ${DB_CURRENT_DB} "delete from presentity where id in(select id from presentities where state in('early', 'confirmed', 'onthephone', 'busy'));"
## presence nat
KazooDB -db ${DB_CURRENT_DB} "delete from presence_nat where id in(select id from presence_nat a where not exists (select id from active_watchers b where b.contact = a.contact));"
}

+ 10
- 0
kamailio/db_scripts/db_init_presence_nat.sql View File

@ -0,0 +1,10 @@
CREATE TABLE if not exists presence_nat (
id INTEGER PRIMARY KEY NOT NULL,
contact VARCHAR(2048) NOT NULL COLLATE NOCASE,
local_contact VARCHAR(32) NOT NULL COLLATE NOCASE,
time_inserted timestamp DEFAULT CURRENT_TIMESTAMP,
time_sent timestamp DEFAULT CURRENT_TIMESTAMP,
slot INTEGER NOT NULL,
selected INTEGER DEFAULT 0,
CONSTRAINT presence_nat_idx UNIQUE (contact)
);

+ 12
- 1
kamailio/db_scripts/db_kazoo-specific View File

@ -41,7 +41,18 @@ CREATE TABLE active_watchers_log (
user_agent VARCHAR(255) DEFAULT '' COLLATE NOCASE,
CONSTRAINT active_watchers_active_watchers_log_idx UNIQUE (presentity_uri, watcher_username, watcher_domain, event)
);
CREATE TABLE presence_nat (
id INTEGER PRIMARY KEY NOT NULL,
contact VARCHAR(2048) NOT NULL COLLATE NOCASE,
local_contact VARCHAR(128) NOT NULL COLLATE NOCASE,
time_inserted timestamp DEFAULT CURRENT_TIMESTAMP,
time_sent timestamp DEFAULT CURRENT_TIMESTAMP,
slot INTEGER NOT NULL,
selected INTEGER DEFAULT 0,
CONSTRAINT presence_nat_idx UNIQUE (contact)
);
create view presentities as select id, cast(printf("sip:%s@%s",username,domain) as varchar(64)) presentity_uri ,
username, domain, event, cast(substr(etag, instr(etag,"@")+1) as varchar(64)) callid,
datetime(received_time, 'unixepoch') as received,


+ 2
- 1
kamailio/default.cfg View File

@ -940,8 +940,9 @@ event_route[tm:local-request]
#!endif
#!ifdef PRESENCE_ROLE
route(PRESENCE_LOCAL_NOTIFY);
route(PRESENCE_LOCAL_REQUEST);
#!endif
}
event_route[evrexec:DEFERRED_INIT]


+ 1
- 1
kamailio/nat-traversal-role.cfg View File

@ -4,7 +4,7 @@ loadmodule "nathelper.so"
#!trydef NATHELPER_LOADED
#!endif
modparam("nathelper", "received_avp", "$avp(AVP_RECV_PARAM)")
modparam("nathelper", "sipping_from", "sip:registrar-check@MY_HOSTNAME")
modparam("nathelper", "sipping_from", "sip:registrar@MY_HOSTNAME")
#!ifdef WEBSOCKETS_ROLE
#!trydef KZ_NAT_DETECT 83


+ 122
- 0
kamailio/presence-nat.cfg View File

@ -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;
}

+ 3
- 1
kamailio/presence-notify.cfg View File

@ -17,7 +17,7 @@ modparam("htable", "htable", "notify=>size=16;autoexpire=3600;updateexpire=1;ini
#!trydef PRESENCE_NOTIFY_INIT
#!trydef MAX_NOTIFY_ERROR 5
route[PRESENCE_LOCAL_NOTIFY]
route[PRESENCE_LOCAL_REQ_NOTIFY]
{
if($rm != "NOTIFY") {
return;
@ -202,6 +202,8 @@ route[PRESENCE_EXPIRED_REGISTRATION]
$var(watcher) = $_s(sip:$ulc(exp=>aor));
$var(watcher_username) = $(var(watcher){uri.user});
$var(watcher_domain) = $(var(watcher){uri.host});
$var(Query) = $_s(DELETE FROM presence_nat where contact in(select distinct contact from active_watchers WHERE watcher_username = "$var(watcher_username)" and watcher_domain = "$var(watcher_domain)"););
mq_add("presence_last_notity", "$uuid(g)", "$var(Query)");
$var(Query) = $_s(DELETE FROM active_watchers WHERE watcher_username = "$var(watcher_username)" and watcher_domain = "$var(watcher_domain)";);
mq_add("presence_last_notity", "$uuid(g)", "$var(Query)");
}


+ 14
- 31
kamailio/presence-role.cfg View File

@ -12,8 +12,7 @@
#!trydef KZ_PRESENCE_REQUEST_PROBE 1
#!trydef KZ_PRESENCE_NO_TARGETS_LOG_LEVEL L_DBG
modparam("htable", "htable", "p=>size=32;autoexpire=3600;")
modparam("htable", "htable", "first=>size=32;autoexpire=3600;initval =0;updateexpire=1;")
modparam("htable", "htable", "first=>size=32;autoexpire=3600;initval=0;")
loadmodule "presence.so"
loadmodule "presence_dialoginfo.so"
@ -53,17 +52,6 @@ modparam("presence", "cseq_offset", KZ_PRESENCE_CSEQ_OFFSET)
modparam("kazoo", "db_url", "KAZOO_DB_URL")
modparam("kazoo", "pua_mode", 1)
#!ifdef NAT_TRAVERSAL_ROLE
#!ifndef NAT_TRAVERSAL_LOADED
#!trydef NAT_TRAVERSAL_LOADED
loadmodule "nat_traversal.so"
#!endif
modparam("nat_traversal", "keepalive_method", "OPTIONS")
modparam("nat_traversal", "keepalive_from", "sip:presence-check@MY_HOSTNAME")
modparam("nat_traversal", "keepalive_state_file", "KAZOO_DATA_DIR/keep_alive_state")
modparam("nat_traversal", "keepalive_interval", 30)
#!endif
kazoo.presence_sync_amqp = KZ_PRESENCE_AMQP_PUBLISH descr "sync subscriptions to amqp"
kazoo.presence_request_probe = KZ_PRESENCE_REQUEST_PROBE descr "request probe for new subscriptions"
kazoo.presence_request_resubscribe_probe = KZ_PRESENCE_REQUEST_RESUBSCRIBE_PROBE descr "request probe for resubscriptions"
@ -75,23 +63,10 @@ kazoo.presence_no_targets_log_level = KZ_PRESENCE_NO_TARGETS_LOG_LEVEL descr "wh
#!include_file "presence-notify.cfg"
#!include_file "presence-reset.cfg"
#!include_file "presence-fast-pickup.cfg"
#!include_file "presence-nat.cfg"
####### Presence Logic ########
#!ifdef NAT_TRAVERSAL_ROLE
route[PRESENCE_NAT]
{
if (isflagset(FLT_NATS)) {
$xavp(regcfg=>match_received) = $su;
if(!( ($proto != "udp") ||
(registered("location", "$rz:$Au", 2, 1) == 1)
)) {
nat_keepalive();
}
}
}
#!endif
route[HANDLE_SUBSCRIBE]
{
if (!is_method("SUBSCRIBE")) {
@ -111,10 +86,6 @@ route[HANDLE_SUBSCRIBE]
exit;
}
#!ifdef NAT_TRAVERSAL_ROLE
route(PRESENCE_NAT);
#!endif
if(has_totag()) {
loose_route();
}
@ -190,6 +161,7 @@ route[HANDLE_NEW_SUBSCRIBE]
route(DELETE_DUPLICATED_SUBSCRIPTIONS);
route(SUBSCRIBE_AMQP);
route(REQUEST_PROBE);
route(PRESENCE_NAT);
} else {
xlog("L_INFO", "$ci|stop|error $T_reply_code for new $hdr(Event) subscription from $fU to $tU in realm $fd\n");
}
@ -544,4 +516,15 @@ route[PRESENCE_API_BINDINGS]
}
route[PRESENCE_LOCAL_REQUEST]
{
route(PRESENCE_LOCAL_REQ_NOTIFY);
route(PRESENCE_LOCAL_REQ_NAT);
}
route[PRESENCE_ON_REGISTRATION]
{
route(PRESENCE_NAT_ON_REGISTRATION);
}
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

+ 4
- 0
kamailio/registrar-role.cfg View File

@ -353,6 +353,10 @@ route[SAVE_LOCATION]
route(PUSHER_ON_REGISTRATION);
#!endif
#!ifdef PRESENCE_ROLE
route(PRESENCE_ON_REGISTRATION);
#!endif
exit;
}


Loading…
Cancel
Save