Thanks community for all replies.
I did the second try. Result is in the attachment.
This time a did it in the way proposed by Daniel-Constantin Mierla.
All job is done in timer process when it iterates through all
registrations looking for expired ones.
It works for all database modes except DB_ONLY.
I'm not sure about tcpconn_get() / tcpconn_put() functions.
tcpconn_get() increments ref counter, but there are several function to
decrement it: tcpconn_put(), tcpconn_chld_put() and
atomic_dec_and_test(). When I was looking for examples in other modules
I saw that tcp_read.c uses tcpconn_chld_put(), but forward.h and
msg_translator.c uses only tcpconn_get() without decrementing ref
counter at all.
It would be great if somebody more experienced shed some light on this.
diff -uNpr kamailio-4.0.3/ip_addr.h sshfs_kamailio-4.0.3/ip_addr.h
--- kamailio-4.0.3/ip_addr.h 2013-08-15 16:42:39.000000000 +0300
+++ sshfs_kamailio-4.0.3/ip_addr.h 2013-08-28 18:28:08.000000000 +0300
@@ -142,6 +142,7 @@ struct receive_info{
struct socket_info* bind_address; /* sock_info structure on which
the msg was received*/
char proto;
+ int tcpconn_id; /* tcp_connnection->id */
#ifdef USE_COMP
short comp; /* compression */
#endif
diff -uNpr kamailio-4.0.3/modules/registrar/save.c sshfs_kamailio-4.0.3/modules/registrar/save.c
--- kamailio-4.0.3/modules/registrar/save.c 2013-08-15 16:42:39.000000000 +0300
+++ sshfs_kamailio-4.0.3/modules/registrar/save.c 2013-08-29 01:44:11.000000000 +0300
@@ -259,6 +259,14 @@ static inline ucontact_info_t* pack_ci(
ci.sock = _m->rcv.bind_address;
}
+ /* set tcp connection id */
+ if (_m->rcv.proto==PROTO_TCP || _m->rcv.proto==PROTO_TLS
+ || _m->rcv.proto==PROTO_WS || _m->rcv.proto==PROTO_WSS) {
+ ci.tcpconn_id = _m->rcv.tcpconn_id;
+ } else {
+ ci.tcpconn_id = -1;
+ }
+
/* additional info from message */
if (parse_headers(_m, HDR_USERAGENT_F, 0) != -1 && _m->user_agent &&
_m->user_agent->body.len>0 && _m->user_agent->body.len<UA_MAX_SIZE) {
@@ -488,7 +496,7 @@ static inline int insert_contacts(struct
/* hack to work with buggy clients having many contacts with same
* address in one REGISTER - increase CSeq to detect if there was
- * one alredy added, then update */
+ * one already added, then update */
ci->cseq++;
if ( r->contacts==0
|| ul.get_ucontact_by_instance(r, &_c->uri, ci, &c) != 0) {
diff -uNpr kamailio-4.0.3/modules/usrloc/ucontact.c sshfs_kamailio-4.0.3/modules/usrloc/ucontact.c
--- kamailio-4.0.3/modules/usrloc/ucontact.c 2013-08-15 16:42:39.000000000 +0300
+++ sshfs_kamailio-4.0.3/modules/usrloc/ucontact.c 2013-08-29 01:49:56.000000000 +0300
@@ -135,6 +135,7 @@ ucontact_t* new_ucontact(str* _dom, str*
c->reg_id = _ci->reg_id;
c->last_modified = _ci->last_modified;
c->last_keepalive = _ci->last_modified;
+ c->tcpconn_id = _ci->tcpconn_id;
#ifdef WITH_XAVP
ucontact_xavp_store(c);
#endif
diff -uNpr kamailio-4.0.3/modules/usrloc/ul_mod.c sshfs_kamailio-4.0.3/modules/usrloc/ul_mod.c
--- kamailio-4.0.3/modules/usrloc/ul_mod.c 2013-08-15 16:42:39.000000000 +0300
+++ sshfs_kamailio-4.0.3/modules/usrloc/ul_mod.c 2013-08-29 13:04:13.000000000 +0300
@@ -161,6 +161,7 @@ int timer_interval = 60; /*!< Timer
int db_mode = 0; /*!< Database sync scheme: 0-no db, 1-write through, 2-write back, 3-only db */
int use_domain = 0; /*!< Whether usrloc should use domain part of aor */
int desc_time_order = 0; /*!< By default do not enable timestamp ordering */
+int handle_lost_tcp = 0;
int ul_fetch_rows = 2000; /*!< number of rows to fetch from result */
int ul_hash_size = 9;
@@ -214,6 +215,7 @@ static param_export_t params[] = {
{"fetch_rows", INT_PARAM, &ul_fetch_rows },
{"hash_size", INT_PARAM, &ul_hash_size },
{"nat_bflag", INT_PARAM, &nat_bflag },
+ {"handle_lost_tcp", INT_PARAM, &handle_lost_tcp },
{"preload", STR_PARAM|USE_FUNC_PARAM, (void*)ul_preload_param},
{"db_update_as_insert", INT_PARAM, &ul_db_update_as_insert},
{"timer_procs", INT_PARAM, &ul_timer_procs},
@@ -387,6 +389,10 @@ static int mod_init(void)
return -1;
}
}
+
+ if (handle_lost_tcp && db_mode == DB_ONLY)
+ LM_WARN("handle_lost_tcp option makes nothing in DB_ONLY mode\n");
+
init_flag = 1;
return 0;
diff -uNpr kamailio-4.0.3/modules/usrloc/ul_mod.h sshfs_kamailio-4.0.3/modules/usrloc/ul_mod.h
--- kamailio-4.0.3/modules/usrloc/ul_mod.h 2013-08-15 16:42:38.000000000 +0300
+++ sshfs_kamailio-4.0.3/modules/usrloc/ul_mod.h 2013-08-29 02:06:38.000000000 +0300
@@ -84,6 +84,7 @@ extern int ul_hash_size;
extern int ul_db_update_as_insert;
extern int ul_db_check_update;
extern int ul_keepalive_timeout;
+extern int handle_lost_tcp;
/*! nat branch flag */
extern unsigned int nat_bflag;
diff -uNpr kamailio-4.0.3/modules/usrloc/urecord.c sshfs_kamailio-4.0.3/modules/usrloc/urecord.c
--- kamailio-4.0.3/modules/usrloc/urecord.c 2013-08-15 16:42:39.000000000 +0300
+++ sshfs_kamailio-4.0.3/modules/usrloc/urecord.c 2013-08-29 13:01:02.000000000 +0300
@@ -40,6 +40,7 @@
#include "../../dprint.h"
#include "../../ut.h"
#include "../../hashes.h"
+#include "../../tcp_conn.h"
#include "ul_mod.h"
#include "usrloc.h"
#include "utime.h"
@@ -221,6 +222,26 @@ void mem_delete_ucontact(urecord_t* _r,
free_ucontact(_c);
}
+static inline int is_valid_tcpconn(ucontact_t *c)
+{
+ if (c->tcpconn_id == -1)
+ return 0; /* tcpconn_id is not present */
+ else
+ return 1; /* valid tcpconn_id */
+}
+
+static inline int is_tcp_alive(ucontact_t *c)
+{
+ struct tcp_connection *con = NULL;
+ int rc = 0;
+
+ if ((con = tcpconn_get(c->tcpconn_id, 0, 0, 0, 0))) {
+ tcpconn_put(con); /* refcnt-- */
+ rc = 1;
+ }
+
+ return rc;
+}
/*!
* \brief Expires timer for NO_DB db_mode
@@ -236,6 +257,11 @@ static inline void nodb_timer(urecord_t*
ptr = _r->contacts;
while(ptr) {
+ if (handle_lost_tcp && is_valid_tcpconn(ptr) && !is_tcp_alive(ptr)) {
+ LM_DBG("tcp connection has been lost, expiring contact %.*s\n", ptr->c.len, ptr->c.s);
+ ptr->expires = UL_EXPIRED_TIME;
+ }
+
if (!VALID_CONTACT(ptr, act_time)) {
/* run callbacks for EXPIRE event */
if (exists_ulcb_type(UL_CONTACT_EXPIRE))
@@ -296,7 +322,6 @@ static inline void wt_timer(urecord_t* _
}
}
-
/*!
* \brief Write-back timer, used for WRITE_BACK db_mode
*
@@ -316,6 +341,11 @@ static inline void wb_timer(urecord_t* _
ptr = _r->contacts;
while(ptr) {
+ if (handle_lost_tcp && is_valid_tcpconn(ptr) && !is_tcp_alive(ptr)) {
+ LM_DBG("tcp connection has been lost, expiring contact %.*s\n", ptr->c.len, ptr->c.s);
+ ptr->expires = UL_EXPIRED_TIME;
+ }
+
if (!VALID_CONTACT(ptr, act_time)) {
/* run callbacks for EXPIRE event */
if (exists_ulcb_type(UL_CONTACT_EXPIRE)) {
diff -uNpr kamailio-4.0.3/modules/usrloc/usrloc.h sshfs_kamailio-4.0.3/modules/usrloc/usrloc.h
--- kamailio-4.0.3/modules/usrloc/usrloc.h 2013-08-15 16:42:39.000000000 +0300
+++ sshfs_kamailio-4.0.3/modules/usrloc/usrloc.h 2013-08-28 19:19:27.000000000 +0300
@@ -90,6 +90,7 @@ typedef struct ucontact {
unsigned int methods; /*!< Supported methods */
str instance; /*!< SIP instance value - gruu */
unsigned int reg_id; /*!< reg-id parameters */
+ int tcpconn_id; /* unique tcp connection id */
#ifdef WITH_XAVP
sr_xavp_t * xavp; /*!< per contact xavps */
#endif
@@ -115,6 +116,7 @@ typedef struct ucontact_info {
unsigned int methods; /*!< supported methods */
str instance; /*!< SIP instance value - gruu */
unsigned int reg_id; /*!< reg-id parameters */
+ int tcpconn_id;
#ifdef WITH_XAVP
sr_xavp_t * xavp; /*!< per contact xavps */
#endif
diff -uNpr kamailio-4.0.3/tcp_main.c sshfs_kamailio-4.0.3/tcp_main.c
--- kamailio-4.0.3/tcp_main.c 2013-08-15 16:42:39.000000000 +0300
+++ sshfs_kamailio-4.0.3/tcp_main.c 2013-08-28 18:22:53.000000000 +0300
@@ -1102,6 +1102,7 @@ struct tcp_connection* tcpconn_new(int s
DBG( "tcpconn_new: on port %d, type %d\n", c->rcv.src_port, type);
init_tcp_req(&c->req, (char*)c+sizeof(struct tcp_connection), rd_b_size);
c->id=(*connection_id)++;
+ c->rcv.tcpconn_id = c->id;
c->rcv.proto_reserved1=0; /* this will be filled before receive_message*/
c->rcv.proto_reserved2=0;
c->state=state;
_______________________________________________
SIP Express Router (SER) and Kamailio (OpenSER) - sr-users mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-users