[sr-dev] git:master: modules_k/dialog: Provide new fix to prevent "unable to find

Timo Reimann timo.reimann at 1und1.de
Thu Aug 5 17:51:13 CEST 2010


Module: sip-router
Branch: master
Commit: d1693b2c64dfc44f0271bdd1c38315578ebe7135
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d1693b2c64dfc44f0271bdd1c38315578ebe7135

Author: Timo Reimann <timo.reimann at 1und1.de>
Committer: Timo Reimann <timo.reimann at 1und1.de>
Date:   Thu Aug  5 17:48:30 2010 +0200

modules_k/dialog: Provide new fix to prevent "unable to find
dialog" WARN messages caused by accessing a dialog in the
"deleted" state (often happens with simultaneous BYE requests when
both UAs hang up at the same time).

This commit uses a different approach where a "deleted" flag is
set in get_dlg() and lookup_dlg() which callers may evaluate.
Callers who only care about existing dialogs can ignore the flag
by passing a NULL argument.

The commit "replaces" 9b7f25d7 and follows up 0723496c.

---

 modules_k/dialog/dialog.c         |    4 ++--
 modules_k/dialog/dlg_handlers.c   |   20 +++++++++++++++++---
 modules_k/dialog/dlg_hash.c       |   22 +++++++++++++++++-----
 modules_k/dialog/dlg_hash.h       |    6 ++++--
 modules_k/dialog/dlg_req_within.c |    2 +-
 5 files changed, 41 insertions(+), 13 deletions(-)

diff --git a/modules_k/dialog/dialog.c b/modules_k/dialog/dialog.c
index f965a06..0ca60b4 100644
--- a/modules_k/dialog/dialog.c
+++ b/modules_k/dialog/dialog.c
@@ -1064,7 +1064,7 @@ static int w_dlg_get(struct sip_msg *msg, char *ci, char *ft, char *tt)
 		return -1;
 	}
 
-	dlg = get_dlg(&sc, &sf, &st, &dir);
+	dlg = get_dlg(&sc, &sf, &st, &dir, NULL);
 	if(dlg==NULL)
 		return -1;
 	current_dlg_pointer = dlg;
@@ -1351,7 +1351,7 @@ static void rpc_end_dlg_entry_id(rpc_t *rpc, void *c) {
 
 	if (rpc->scan(c, "ddS", &h_entry, &h_id, &rpc_extra_hdrs) < 2) return;
 
-	dlg = lookup_dlg(h_entry, h_id);
+	dlg = lookup_dlg(h_entry, h_id, NULL);
 	if(dlg){
 		dlg_bye_all(dlg, (rpc_extra_hdrs.len>0)?&rpc_extra_hdrs:NULL);
 		unref_dlg(dlg, 1);
diff --git a/modules_k/dialog/dlg_handlers.c b/modules_k/dialog/dlg_handlers.c
index 1e9a1b3..ef1e23f 100644
--- a/modules_k/dialog/dlg_handlers.c
+++ b/modules_k/dialog/dlg_handlers.c
@@ -542,6 +542,7 @@ void dlg_onreq(struct cell* t, int type, struct tmcb_params *param)
 	str ftag;
 	str ttag;
 	unsigned int dir;
+	unsigned int del;
 	struct sip_msg *req = param->req;
 
 	if((req->flags&dlg_flag)!=dlg_flag)
@@ -565,7 +566,11 @@ void dlg_onreq(struct cell* t, int type, struct tmcb_params *param)
 		LM_WARN("pre-matching failed\n");
 		return;
 	}
-	dlg = get_dlg(&callid, &ftag, &ttag, &dir);
+	dlg = get_dlg(&callid, &ftag, &ttag, &dir, &del);
+	if (del == 1) {
+		LM_DBG("dialog marked for deletion, ignoring\n");
+		return;
+	}
 	if (!dlg){
 		LM_DBG("Callid '%.*s' not found, must be a new dialog\n",
 				req->callid->body.len, req->callid->body.s);
@@ -837,6 +842,7 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
 	str val, callid, ftag, ttag;
 	int h_entry, h_id, new_state, old_state, unref, event, timeout;
 	unsigned int dir;
+	unsigned int del;
 	int ret = 0;
 
 	if (current_dlg_pointer!=NULL)
@@ -865,7 +871,11 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
 			if ( parse_dlg_rr_param( val.s, val.s+val.len, &h_entry, &h_id)<0 )
 				return;
 
-			dlg = lookup_dlg( h_entry, h_id);
+			dlg = lookup_dlg( h_entry, h_id, &del);
+			if (del == 1) {
+				LM_DBG("dialog marked for deletion, ignoring\n");
+				return;
+			}
 			if (dlg==0) {
 				LM_WARN("unable to find dialog for %.*s "
 					"with route param '%.*s' [%u:%u]\n",
@@ -913,7 +923,11 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
 			return;
 		/* TODO - try to use the RR dir detection to speed up here the
 		 * search -bogdan */
-		dlg = get_dlg(&callid, &ftag, &ttag, &dir);
+		dlg = get_dlg(&callid, &ftag, &ttag, &dir, &del);
+		if (del == 1) {
+			LM_DBG("dialog marked for deletion, ignoring\n");
+			return;
+		}
 		if (!dlg){
 			LM_DBG("Callid '%.*s' not found\n",
 				req->callid->body.len, req->callid->body.s);
diff --git a/modules_k/dialog/dlg_hash.c b/modules_k/dialog/dlg_hash.c
index 6df21e3..58332a6 100644
--- a/modules_k/dialog/dlg_hash.c
+++ b/modules_k/dialog/dlg_hash.c
@@ -362,11 +362,14 @@ error:
  * \param h_id id of the hash table entry
  * \return dialog on success, NULL on failure
  */
-struct dlg_cell* lookup_dlg( unsigned int h_entry, unsigned int h_id)
+struct dlg_cell* lookup_dlg( unsigned int h_entry, unsigned int h_id, unsigned int *del)
 {
 	struct dlg_cell *dlg;
 	struct dlg_entry *d_entry;
 
+	if (del != NULL)
+		*del = 0;
+ 
 	if (h_entry>=d_table->size)
 		goto not_found;
 
@@ -377,6 +380,8 @@ struct dlg_cell* lookup_dlg( unsigned int h_entry, unsigned int h_id)
 	for( dlg=d_entry->first ; dlg ; dlg=dlg->next ) {
 		if (dlg->h_id == h_id) {
 			if (dlg->state==DLG_STATE_DELETED) {
+				if (del != NULL)
+					*del = 1;
 				dlg_unlock( d_table, d_entry);
 				goto not_found;
 			}
@@ -405,11 +410,15 @@ not_found:
  * \return dialog structure on success, NULL on failure
  */
 static inline struct dlg_cell* internal_get_dlg(unsigned int h_entry,
-						str *callid, str *ftag, str *ttag, unsigned int *dir)
+						str *callid, str *ftag, str *ttag, unsigned int *dir,
+						unsigned int *del)
 {
 	struct dlg_cell *dlg;
 	struct dlg_entry *d_entry;
 
+	if (del != NULL)
+		*del = 0;
+
 	d_entry = &(d_table->entries[h_entry]);
 
 	dlg_lock( d_table, d_entry);
@@ -418,6 +427,8 @@ static inline struct dlg_cell* internal_get_dlg(unsigned int h_entry,
 		/* Check callid / fromtag / totag */
 		if (match_dialog( dlg, callid, ftag, ttag, dir)==1) {
 			if (dlg->state==DLG_STATE_DELETED) {
+				if (del != NULL)
+					*del = 1;
 				dlg_unlock( d_table, d_entry);
 				goto not_found;
 			}
@@ -453,14 +464,15 @@ not_found:
  * \param dir direction
  * \return dialog structure on success, NULL on failure
  */
-struct dlg_cell* get_dlg( str *callid, str *ftag, str *ttag, unsigned int *dir)
+struct dlg_cell* get_dlg( str *callid, str *ftag, str *ttag, unsigned int *dir,
+		unsigned int *del)
 {
 	struct dlg_cell *dlg;
 
 	if ((dlg = internal_get_dlg(core_hash(callid, ftag->len?ftag:0,
-			d_table->size), callid, ftag, ttag, dir)) == 0 &&
+			d_table->size), callid, ftag, ttag, dir, del)) == 0 &&
 			(dlg = internal_get_dlg(core_hash(callid, ttag->len
-			?ttag:0, d_table->size), callid, ftag, ttag, dir)) == 0) {
+			?ttag:0, d_table->size), callid, ftag, ttag, dir, del)) == 0) {
 		LM_DBG("no dialog callid='%.*s' found\n", callid->len, callid->s);
 		return 0;
 	}
diff --git a/modules_k/dialog/dlg_hash.h b/modules_k/dialog/dlg_hash.h
index 889a318..e555837 100644
--- a/modules_k/dialog/dlg_hash.h
+++ b/modules_k/dialog/dlg_hash.h
@@ -243,9 +243,10 @@ int dlg_update_cseq(struct dlg_cell *dlg, unsigned int leg, str *cseq);
  * \brief Lookup a dialog in the global list
  * \param h_entry number of the hash table entry
  * \param h_id id of the hash table entry
+ * \param del unless null, flag that is set if dialog is in "deleted" state
  * \return dialog on success, NULL on failure
  */
-struct dlg_cell* lookup_dlg( unsigned int h_entry, unsigned int h_id);
+struct dlg_cell* lookup_dlg( unsigned int h_entry, unsigned int h_id, unsigned int *del);
 
 
 /*!
@@ -260,9 +261,10 @@ struct dlg_cell* lookup_dlg( unsigned int h_entry, unsigned int h_id);
  * \param ftag from tag
  * \param ttag to tag
  * \param dir direction
+ * \param del unless null, flag that is set if dialog is in "deleted" state
  * \return dialog structure on success, NULL on failure
  */
-struct dlg_cell* get_dlg(str *callid, str *ftag, str *ttag, unsigned int *dir);
+struct dlg_cell* get_dlg(str *callid, str *ftag, str *ttag, unsigned int *dir, unsigned int *del);
 
 
 /*!
diff --git a/modules_k/dialog/dlg_req_within.c b/modules_k/dialog/dlg_req_within.c
index aae12fd..3b6c57d 100644
--- a/modules_k/dialog/dlg_req_within.c
+++ b/modules_k/dialog/dlg_req_within.c
@@ -317,7 +317,7 @@ struct mi_root * mi_terminate_dlg(struct mi_root *cmd_tree, void *param ){
 
 	LM_DBG("h_entry %u h_id %u\n", h_entry, h_id);
 
-	dlg = lookup_dlg(h_entry, h_id);
+	dlg = lookup_dlg(h_entry, h_id, NULL);
 
 	// lookup_dlg has incremented the reference count
 




More information about the sr-dev mailing list