Module: sip-router
Branch: master
Commit: 36845cc575f36a62d88b0e10826c04d63edbd536
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=36845cc…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: Sun Aug 19 13:01:36 2012 +0200
usrloc(k): keep time of the last keepalive for natted UDP contacts
- new field in the contact structure to keep the timestamp when that
conctact was refreshed by keepalive or registration update
- it is taken in cosideration to remove contacts that don't reply to nat
ping requests, so it works only together with nathelper module
- when an UDP contact is not resposive for an interval of time, the
contact is set to expire is 10 seconds. This process takes place in
the function that fetches the list of contacts for nat pinging
- last_modified and last_keepalive are exported to mi and rpc list
commands
---
modules_k/usrloc/dlist.c | 71 +++++++++++++++++++++++++++++++++++++++++++
modules_k/usrloc/ucontact.c | 2 +
modules_k/usrloc/ul_mi.c | 15 +++++++++
modules_k/usrloc/ul_mod.c | 1 +
modules_k/usrloc/ul_mod.h | 7 ++++
modules_k/usrloc/ul_rpc.c | 16 ++++++++++
modules_k/usrloc/usrloc.c | 20 +++++++++---
modules_k/usrloc/usrloc.h | 10 ++++++
8 files changed, 137 insertions(+), 5 deletions(-)
diff --git a/modules_k/usrloc/dlist.c b/modules_k/usrloc/dlist.c
index 2f55ce7..3cc520d 100644
--- a/modules_k/usrloc/dlist.c
+++ b/modules_k/usrloc/dlist.c
@@ -307,6 +307,12 @@ static inline int get_all_mem_ucontacts(void *buf, int len, unsigned
int flags,
int i = 0;
cp = buf;
shortage = 0;
+ time_t tnow = 0;
+
+
+ if(ul_keepalive_timeout>0)
+ tnow = time(NULL);
+
/* Reserve space for terminating 0000 */
len -= sizeof(c->c.len);
@@ -333,6 +339,22 @@ static inline int get_all_mem_ucontacts(void *buf, int len, unsigned
int flags,
*/
if ((c->cflags & flags) != flags)
continue;
+
+ if(ul_keepalive_timeout>0 && c->last_keepalive>0)
+ {
+ if((c->cflags & nat_bflag) != 0 && c->sock!=NULL
+ && c->sock->proto==PROTO_UDP)
+ {
+ if(c->last_keepalive+ul_keepalive_timeout < tnow)
+ {
+ /* set contact as expired in 10s */
+ if(c->expires > tnow + 10)
+ c->expires = tnow + 10;
+ continue;
+ }
+ }
+ }
+
if (c->received.s) {
needed = (int)(sizeof(c->received.len)
+ c->received.len
@@ -457,6 +479,55 @@ int get_all_ucontacts(void *buf, int len, unsigned int flags,
+/**
+ *
+ */
+int ul_refresh_keepalive(unsigned int _aorhash, str *_ruid)
+{
+ dlist_t *p;
+ urecord_t *r;
+ ucontact_t *c;
+ int i;
+
+ /* todo: get location domain via param */
+
+ for (p = root; p != NULL; p = p->next)
+ {
+ i = _aorhash&(p->d->size-1);
+ lock_ulslot(p->d, i);
+ if(p->d->table[i].n<=0)
+ {
+ unlock_ulslot(p->d, i);
+ continue;
+ }
+ for (r = p->d->table[i].first; r != NULL; r = r->next)
+ {
+ if(r->aorhash==_aorhash)
+ {
+ for (c = r->contacts; c != NULL; c = c->next)
+ {
+ if (c->c.len <= 0 || c->ruid.len<=0)
+ continue;
+ if(c->ruid.len==_ruid->len
+ && !memcmp(c->ruid.s, _ruid->s, _ruid->len))
+ {
+ /* found */
+ c->last_keepalive = time(NULL);
+ LM_DBG("updated keepalive for [%.*s:%u] to %u\n",
+ _ruid->len, _ruid->s, _aorhash,
+ (unsigned int)c->last_keepalive);
+ unlock_ulslot(p->d, i);
+ return 0;
+ }
+ }
+ }
+ }
+ unlock_ulslot(p->d, i);
+ }
+
+ return 0;
+}
+
/*!
* \brief Create a new domain structure
* \return 0 if everything went OK, otherwise value < 0 is returned
diff --git a/modules_k/usrloc/ucontact.c b/modules_k/usrloc/ucontact.c
index ac76e9b..dba66be 100644
--- a/modules_k/usrloc/ucontact.c
+++ b/modules_k/usrloc/ucontact.c
@@ -96,6 +96,7 @@ ucontact_t* new_ucontact(str* _dom, str* _aor, str* _contact,
ucontact_info_t* _
c->methods = _ci->methods;
c->reg_id = _ci->reg_id;
c->last_modified = _ci->last_modified;
+ c->last_keepalive = _ci->last_modified;
return c;
error:
@@ -250,6 +251,7 @@ int mem_update_ucontact(ucontact_t* _c, ucontact_info_t* _ci)
_c->cseq = _ci->cseq;
_c->methods = _ci->methods;
_c->last_modified = _ci->last_modified;
+ _c->last_keepalive = _ci->last_modified;
_c->flags = _ci->flags;
_c->cflags = _ci->cflags;
diff --git a/modules_k/usrloc/ul_mi.c b/modules_k/usrloc/ul_mi.c
index ca7c71a..66c85ca 100644
--- a/modules_k/usrloc/ul_mi.c
+++ b/modules_k/usrloc/ul_mi.c
@@ -259,6 +259,21 @@ static inline int mi_add_aor_node(struct mi_node *parent, urecord_t*
r, time_t t
node = add_mi_node_child( cnode, MI_DUP_VALUE, "Reg-Id", 6, p, len);
if (node==0)
return -1;
+
+ /* last keepalive */
+ p = int2str((unsigned long)c->last_keepalive, &len);
+ node = add_mi_node_child( cnode, MI_DUP_VALUE, "Last-Keepalive",
+ 14, p, len);
+ if (node==0)
+ return -1;
+
+ /* last modified */
+ p = int2str((unsigned long)c->last_modified, &len);
+ node = add_mi_node_child( cnode, MI_DUP_VALUE, "Last-Modified",
+ 13, p, len);
+ if (node==0)
+ return -1;
+
} /* for */
return 0;
diff --git a/modules_k/usrloc/ul_mod.c b/modules_k/usrloc/ul_mod.c
index a6e7ebd..7b6af79 100644
--- a/modules_k/usrloc/ul_mod.c
+++ b/modules_k/usrloc/ul_mod.c
@@ -108,6 +108,7 @@ extern int ul_locks_no;
int ul_db_update_as_insert = 0;
int ul_timer_procs = 0;
int ul_db_check_update = 0;
+int ul_keepalive_timeout = 0;
/* sruid to get internal uid for mi/rpc commands */
sruid_t _ul_sruid;
diff --git a/modules_k/usrloc/ul_mod.h b/modules_k/usrloc/ul_mod.h
index 30b8885..e10b2c8 100644
--- a/modules_k/usrloc/ul_mod.h
+++ b/modules_k/usrloc/ul_mod.h
@@ -74,6 +74,13 @@ extern int ul_fetch_rows;
extern int ul_hash_size;
extern int ul_db_update_as_insert;
extern int ul_db_check_update;
+extern int ul_keepalive_timeout;
+
+/*! nat branch flag */
+extern unsigned int nat_bflag;
+/*! flag to protect against wrong initialization */
+extern unsigned int init_flag;
+
extern db1_con_t* ul_dbh; /* Database connection handle */
extern db_func_t ul_dbf;
diff --git a/modules_k/usrloc/ul_rpc.c b/modules_k/usrloc/ul_rpc.c
index 49cae17..38c1a61 100644
--- a/modules_k/usrloc/ul_rpc.c
+++ b/modules_k/usrloc/ul_rpc.c
@@ -287,6 +287,22 @@ static void ul_rpc_dump(rpc_t* rpc, void* ctx)
"Internal error adding reg_id");
return;
}
+ if(rpc->struct_add(vh, "d",
+ "Last-Keepalive", (int)c->last_keepalive)<0)
+ {
+ unlock_ulslot( dom, i);
+ rpc->fault(ctx, 500,
+ "Internal error adding reg_id");
+ return;
+ }
+ if(rpc->struct_add(vh, "d",
+ "Last-Modified", (int)c->last_modified)<0)
+ {
+ unlock_ulslot( dom, i);
+ rpc->fault(ctx, 500,
+ "Internal error adding reg_id");
+ return;
+ }
}
}
diff --git a/modules_k/usrloc/usrloc.c b/modules_k/usrloc/usrloc.c
index 8c3408f..ba0ec1a 100644
--- a/modules_k/usrloc/usrloc.c
+++ b/modules_k/usrloc/usrloc.c
@@ -41,11 +41,6 @@
#include "../../sr_module.h"
#include "ul_mod.h"
-/*! nat branch flag */
-extern unsigned int nat_bflag;
-/*! flag to protect against wrong initialization */
-extern unsigned int init_flag;
-
/*!
* \brief usrloc module API export bind function
@@ -83,9 +78,24 @@ int bind_usrloc(usrloc_api_t* api)
api->get_urecord_by_ruid = get_urecord_by_ruid;
api->get_ucontact_by_instance = get_ucontact_by_instance;
+ api->set_keepalive_timeout = ul_set_keepalive_timeout;
+ api->refresh_keepalive = ul_refresh_keepalive;
+
api->use_domain = use_domain;
api->db_mode = db_mode;
api->nat_flag = nat_bflag;
return 0;
}
+
+/**
+ *
+ */
+int ul_set_keepalive_timeout(int _to)
+{
+ int oto;
+
+ oto = ul_keepalive_timeout;
+ ul_keepalive_timeout = _to;
+ return oto;
+}
diff --git a/modules_k/usrloc/usrloc.h b/modules_k/usrloc/usrloc.h
index bfd225a..214ac92 100644
--- a/modules_k/usrloc/usrloc.h
+++ b/modules_k/usrloc/usrloc.h
@@ -83,6 +83,7 @@ typedef struct ucontact {
str user_agent; /*!< User-Agent header field */
struct socket_info *sock; /*!< received socket */
time_t last_modified; /*!< When the record was last modified */
+ time_t last_keepalive; /*!< last keepalive timestamp */
unsigned int methods; /*!< Supported methods */
str instance; /*!< SIP instance value - gruu */
unsigned int reg_id; /*!< reg-id parameters */
@@ -170,6 +171,12 @@ typedef int (*get_udomain_t)(const char* _n, udomain_t** _d);
typedef unsigned int (*ul_get_aorhash_t)(str *_aor);
unsigned int ul_get_aorhash(str *_aor);
+typedef int (*ul_set_keepalive_timeout_t)(int _to);
+int ul_set_keepalive_timeout(int _to);
+
+typedef int (*ul_refresh_keepalive_t)(unsigned int _aorhash, str *_ruid);
+int ul_refresh_keepalive(unsigned int _aorhash, str *_ruid);
+
/*! usrloc API export structure */
typedef struct usrloc_api {
int use_domain; /*! use_domain module parameter */
@@ -198,6 +205,9 @@ typedef struct usrloc_api {
register_ulcb_t register_ulcb;
ul_get_aorhash_t get_aorhash;
+
+ ul_set_keepalive_timeout_t set_keepalive_timeout;
+ ul_refresh_keepalive_t refresh_keepalive;
} usrloc_api_t;