Răsfoiți Sursa

dialog(k): refactored dlg ref counting

- dlg pointer is no longer stored in tm callbacks parameter and ref
  counting for these kind of needs was removed
- the internal id (hash entry, dlg id) is given now to tm callbacks. The
  callbacks will do dlg lookup to get the structure
- there are longer-time persistent ref counting for:
  * storing dlg structure in dialog hash table
  * keeping dlg in timer list
  * waiting for the reply of BYE to destroy dialog structure
- all the other ref countings are for short time, only for the period of
  doing specific processing
- the new ref counting is safer in relation with tm callbacks and avoids
  tight dependecy which may have been easily broken by future tm changes
(cherry picked from commit 9ba4ee25e32368a9c17c3f86784a52a97b748b93)
Daniel-Constantin Mierla 14 ani în urmă
părinte
comite
5bdee1ffe8

+ 67 - 35
modules_k/dialog/dialog.c

@@ -842,6 +842,7 @@ static int w_get_profile_size2(struct sip_msg *msg, char *profile, char *result)
 static int w_dlg_setflag(struct sip_msg *msg, char *flag, char *s2)
 {
 	dlg_ctx_t *dctx;
+	dlg_cell_t *d;
 	int val;
 
 	if(fixup_get_ivalue(msg, (gparam_p)flag, &val)!=0)
@@ -855,8 +856,11 @@ static int w_dlg_setflag(struct sip_msg *msg, char *flag, char *s2)
 		return -1;
 
 	dctx->flags |= 1<<val;
-	if(dctx->dlg)
-		dctx->dlg->sflags |= 1<<val;
+	d = dlg_get_by_iuid(&dctx->iuid);
+	if(d!=NULL) {
+		d->sflags |= 1<<val;
+		dlg_release(d);
+	}
 	return 1;
 }
 
@@ -864,6 +868,7 @@ static int w_dlg_setflag(struct sip_msg *msg, char *flag, char *s2)
 static int w_dlg_resetflag(struct sip_msg *msg, char *flag, str *s2)
 {
 	dlg_ctx_t *dctx;
+	dlg_cell_t *d;
 	int val;
 
 	if(fixup_get_ivalue(msg, (gparam_p)flag, &val)!=0)
@@ -878,8 +883,11 @@ static int w_dlg_resetflag(struct sip_msg *msg, char *flag, str *s2)
 		return -1;
 
 	dctx->flags &= ~(1<<val);
-	if(dctx->dlg)
-		dctx->dlg->sflags &= ~(1<<val);
+	d = dlg_get_by_iuid(&dctx->iuid);
+	if(d!=NULL) {
+		d->sflags &= ~(1<<val);
+		dlg_release(d);
+	}
 	return 1;
 }
 
@@ -887,7 +895,9 @@ static int w_dlg_resetflag(struct sip_msg *msg, char *flag, str *s2)
 static int w_dlg_isflagset(struct sip_msg *msg, char *flag, str *s2)
 {
 	dlg_ctx_t *dctx;
+	dlg_cell_t *d;
 	int val;
+	int ret;
 
 	if(fixup_get_ivalue(msg, (gparam_p)flag, &val)!=0)
 	{
@@ -900,8 +910,12 @@ static int w_dlg_isflagset(struct sip_msg *msg, char *flag, str *s2)
 	if ( (dctx=dlg_get_dlg_ctx())==NULL )
 		return -1;
 
-	if(dctx->dlg)
-		return (dctx->dlg->sflags&(1<<val))?1:-1;
+	d = dlg_get_by_iuid(&dctx->iuid);
+	if(d!=NULL) {
+		ret = (d->sflags&(1<<val))?1:-1;
+		dlg_release(d);
+		return ret;
+	}
 	return (dctx->flags&(1<<val))?1:-1;
 }
 
@@ -931,7 +945,7 @@ static int w_dlg_manage(struct sip_msg *msg, char *s1, char *s2)
 
 static int w_dlg_bye(struct sip_msg *msg, char *side, char *s2)
 {
-	struct dlg_cell *dlg;
+	dlg_cell_t *dlg = NULL;
 	int n;
 
 	dlg = dlg_get_ctx_dialog();
@@ -942,22 +956,30 @@ static int w_dlg_bye(struct sip_msg *msg, char *side, char *s2)
 	if(n==1)
 	{
 		if(dlg_bye(dlg, NULL, DLG_CALLER_LEG)!=0)
-			return -1;
-		return 1;
+			goto error;
+		goto done;
 	} else if(n==2) {
 		if(dlg_bye(dlg, NULL, DLG_CALLEE_LEG)!=0)
-			return -1;
-		return 1;
+			goto error;
+		goto done;
 	} else {
 		if(dlg_bye_all(dlg, NULL)!=0)
-			return -1;
-		return 1;
+			goto error;
+		goto done;
 	}
+
+done:
+	dlg_release(dlg);
+	return 1;
+
+error:
+	dlg_release(dlg);
+	return -1;
 }
 
 static int w_dlg_refer(struct sip_msg *msg, char *side, char *to)
 {
-	struct dlg_cell *dlg;
+	dlg_cell_t *dlg;
 	int n;
 	str st = {0,0};
 
@@ -970,22 +992,28 @@ static int w_dlg_refer(struct sip_msg *msg, char *side, char *to)
 	if(fixup_get_svalue(msg, (gparam_p)to, &st)!=0)
 	{
 		LM_ERR("unable to get To\n");
-		return -1;
+		goto error;
 	}
 	if(st.s==NULL || st.len == 0)
 	{
 		LM_ERR("invalid To parameter\n");
-		return -1;
+		goto error;
 	}
 	if(n==1)
 	{
 		if(dlg_transfer(dlg, &st, DLG_CALLER_LEG)!=0)
-			return -1;
+			goto error;
 	} else {
 		if(dlg_transfer(dlg, &st, DLG_CALLEE_LEG)!=0)
-			return -1;
+			goto error;
 	}
+
+	dlg_release(dlg);
 	return 1;
+
+error:
+	dlg_release(dlg);
+	return -1;
 }
 
 static int w_dlg_bridge(struct sip_msg *msg, char *from, char *to, char *op)
@@ -1097,7 +1125,7 @@ static int fixup_dlg_bridge(void** param, int param_no)
 
 static int w_dlg_get(struct sip_msg *msg, char *ci, char *ft, char *tt)
 {
-	struct dlg_cell *dlg = NULL;
+	dlg_cell_t *dlg = NULL;
 	str sc = {0,0};
 	str sf = {0,0};
 	str st = {0,0};
@@ -1143,10 +1171,11 @@ static int w_dlg_get(struct sip_msg *msg, char *ci, char *ft, char *tt)
 	dlg = get_dlg(&sc, &sf, &st, &dir);
 	if(dlg==NULL)
 		return -1;
-    /* set current dialog pointer - re-use ref increment from dlg_get() above */
-	current_dlg_pointer = dlg;
-	_dlg_ctx.dlg = dlg;
+    /* set shorcut to dialog internal unique id */
+	_dlg_ctx.iuid.h_entry = dlg->h_entry;
+	_dlg_ctx.iuid.h_id = dlg->h_id;
 	_dlg_ctx.dir = dir;
+	dlg_release(dlg);
 	return 1;
 }
 
@@ -1202,7 +1231,8 @@ struct mi_root * mi_dlg_bridge(struct mi_root *cmd_tree, void *param)
  * \param with_context if 1 then the dialog context will be also printed
  * \return 0 on success, -1 on failure
  */
-static inline void internal_rpc_print_dlg(rpc_t *rpc, void *c, struct dlg_cell *dlg, int with_context)
+static inline void internal_rpc_print_dlg(rpc_t *rpc, void *c, dlg_cell_t *dlg,
+		int with_context)
 {
 	rpc_cb_ctx_t rpc_cb;
 
@@ -1248,7 +1278,7 @@ static inline void internal_rpc_print_dlg(rpc_t *rpc, void *c, struct dlg_cell *
  */
 static void internal_rpc_print_dlgs(rpc_t *rpc, void *c, int with_context)
 {
-	struct dlg_cell *dlg;
+	dlg_cell_t *dlg;
 	unsigned int i;
 
 	for( i=0 ; i<d_table->size ; i++ ) {
@@ -1270,8 +1300,8 @@ static void internal_rpc_print_dlgs(rpc_t *rpc, void *c, int with_context)
  */
 static void internal_rpc_print_single_dlg(rpc_t *rpc, void *c, int with_context) {
 	str callid, from_tag;
-	struct dlg_entry *d_entry;
-	struct dlg_cell *dlg;
+	dlg_entry_t *d_entry;
+	dlg_cell_t *dlg;
 	unsigned int h_entry;
 
 	if (rpc->scan(c, ".S.S", &callid, &from_tag) < 2) return;
@@ -1296,9 +1326,10 @@ static void internal_rpc_print_single_dlg(rpc_t *rpc, void *c, int with_context)
  * \param profile_name the given profile
  * \param value the given profile value
  */
-static void internal_rpc_profile_get_size(rpc_t *rpc, void *c, str *profile_name, str *value) {
+static void internal_rpc_profile_get_size(rpc_t *rpc, void *c, str *profile_name,
+		str *value) {
 	unsigned int size;
-	struct dlg_profile_table *profile;
+	dlg_profile_table_t *profile;
 
 	profile = search_dlg_profile( profile_name );
 	if (!profile) {
@@ -1332,9 +1363,10 @@ static void internal_rpc_profile_get_size(rpc_t *rpc, void *c, str *profile_name
  * \param value the given profile value
  * \param with_context if 1 then the dialog context will be also printed
  */
-static void internal_rpc_profile_print_dlgs(rpc_t *rpc, void *c, str *profile_name, str *value) {
-	struct dlg_profile_table *profile;
-	struct dlg_profile_hash *ph;
+static void internal_rpc_profile_print_dlgs(rpc_t *rpc, void *c, str *profile_name,
+		str *value) {
+	dlg_profile_table_t *profile;
+	dlg_profile_hash_t *ph;
 	unsigned int i;
 
 	profile = search_dlg_profile( profile_name );
@@ -1385,7 +1417,7 @@ static void internal_rpc_profile_print_dlgs(rpc_t *rpc, void *c, str *profile_na
  * Wrapper around is_known_dlg().
  */
 
-static int w_is_known_dlg(struct sip_msg *msg) {
+static int w_is_known_dlg(sip_msg_t *msg) {
 	return	is_known_dlg(msg);
 }
 
@@ -1430,15 +1462,15 @@ static void rpc_print_dlg_ctx(rpc_t *rpc, void *c) {
 }
 static void rpc_end_dlg_entry_id(rpc_t *rpc, void *c) {
 	unsigned int h_entry, h_id;
-	struct dlg_cell * dlg = NULL;
+	dlg_cell_t * dlg = NULL;
 	str rpc_extra_hdrs = {NULL,0};
 
 	if (rpc->scan(c, "ddS", &h_entry, &h_id, &rpc_extra_hdrs) < 2) return;
 
-	dlg = lookup_dlg(h_entry, h_id);
+	dlg = dlg_lookup(h_entry, h_id);
 	if(dlg){
 		dlg_bye_all(dlg, (rpc_extra_hdrs.len>0)?&rpc_extra_hdrs:NULL);
-		unref_dlg(dlg, 1);
+		dlg_release(dlg);
 	}
 }
 static void rpc_profile_get_size(rpc_t *rpc, void *c) {

+ 4 - 4
modules_k/dialog/dlg_db_handler.c

@@ -103,7 +103,7 @@ extern int early_dlgs_cnt;
 	do{\
 		if (VAL_NULL((_values)+ (_index))) { \
 			if (_not_null) {\
-				if (_unref) unref_dlg(dlg,1);\
+				if (_unref) dlg_unref(dlg,1);\
 				goto next_dialog; \
 			} else { \
 				(_res).s = 0; \
@@ -392,7 +392,7 @@ static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows)
 			(dlg_set_leg_info( dlg, &to_tag, &rroute2, &contact2,
 			&cseq2, DLG_CALLEE_LEG)!=0) ) {
 				LM_ERR("dlg_set_leg_info failed\n");
-				unref_dlg(dlg,1);
+				dlg_unref(dlg,1);
 				continue;
 			}
 
@@ -410,10 +410,10 @@ static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows)
 					dlg->callid.len, dlg->callid.s,
 					dlg->tag[DLG_CALLER_LEG].len, dlg->tag[DLG_CALLER_LEG].s,
 					dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s);
-				unref_dlg(dlg,1);
+				dlg_unref(dlg,1);
 				continue;
 			}
-			ref_dlg(dlg,1);
+			dlg_ref(dlg,1);
 			LM_DBG("current dialog timeout is %u\n", dlg->tl.timeout);
 
 			dlg->lifetime = 0;

+ 202 - 185
modules_k/dialog/dlg_handlers.c

@@ -283,25 +283,66 @@ error0:
 	return -1;
 }
 
+/*!
+ * \brief Clone dialog internal unique id to shared memory
+ */
+dlg_iuid_t *dlg_get_iuid_shm_clone(dlg_cell_t *dlg)
+{
+	dlg_iuid_t *iuid = NULL;
+
+	if(dlg==NULL)
+		return NULL;
+
+	iuid = (dlg_iuid_t*)shm_malloc(sizeof(dlg_iuid_t));
+	if(iuid==NULL)
+	{
+		LM_ERR("failed to clone dialog iuid\n");
+		return NULL;
+	}
+
+	memset(iuid, 0, sizeof(dlg_iuid_t));
+	iuid->h_entry = dlg->h_entry;
+	iuid->h_id = dlg->h_id;
+
+	return iuid;
+}
+
+
+/*!
+ * \brief Free dialog internal unique id stored in shared memory
+ */
+static void dlg_iuid_sfree(void *iuid)
+{
+    if(iuid)
+		shm_free(iuid);
+}
+
+
 /*!
  * \brief Function that executes BYE reply callbacks
  * \param t transaction, unused
  * \param type type of the callback, should be TMCB_RESPONSE_FWDED
  * \param params saved dialog structure inside the callback
  */
-static void dlg_terminated_confirmed(struct cell* t,
-                                     int type,
+static void dlg_terminated_confirmed(tm_cell_t *t, int type,
                                      struct tmcb_params* params)
 {
+    dlg_cell_t *dlg = NULL;
+	dlg_iuid_t *iuid = NULL;
+
     if(!params || !params->req || !params->param)
     {
         LM_ERR("invalid parameters!\n");
         return;
     }
 
-    struct dlg_cell* dlg = (struct dlg_cell*)*params->param;
+	iuid = (dlg_iuid_t*)*params->param;
+	if(iuid==NULL)
+		return;
 
-    if(!dlg)
+    dlg = dlg_get_by_iuid(iuid);
+
+    if(dlg==NULL)
     {
         LM_ERR("failed to get dialog from params!\n");
         return;
@@ -313,6 +354,7 @@ static void dlg_terminated_confirmed(struct cell* t,
                       params->rpl,
                       DLG_DIR_UPSTREAM,
                       0);
+	dlg_release(dlg);
 }
 
 /*!
@@ -321,10 +363,10 @@ static void dlg_terminated_confirmed(struct cell* t,
  * \param dlg corresponding dialog
  * \param dir message direction
  */
-static void dlg_terminated(struct sip_msg* req,
-                           struct dlg_cell* dlg,
-                           unsigned int dir)
+static void dlg_terminated(sip_msg_t *req, dlg_cell_t *dlg, unsigned int dir)
 {
+	dlg_iuid_t *iuid = NULL;
+
     if(!req) {
         LM_ERR("request is empty!");
         return;
@@ -338,13 +380,17 @@ static void dlg_terminated(struct sip_msg* req,
     /* dialog terminated (BYE) */
     run_dlg_callbacks(DLGCB_TERMINATED, dlg, req, NULL, dir, 0);
 
+	iuid = dlg_get_iuid_shm_clone(dlg);
+	if(iuid==NULL)
+		return;
+
     /* register callback for the coresponding reply */
     if (d_tmb.register_tmcb(req,
                             0,
                             TMCB_RESPONSE_OUT,
                             dlg_terminated_confirmed,
-                            (void*) dlg,
-                            0 ) <= 0 ) {
+                            (void*)iuid,
+                            dlg_iuid_sfree) <= 0 ) {
         LM_ERR("cannot register response callback for BYE request\n");
         return;
     }
@@ -364,20 +410,25 @@ static void dlg_terminated(struct sip_msg* req,
  */
 static void dlg_onreply(struct cell* t, int type, struct tmcb_params *param)
 {
-    struct dlg_cell *dlg;
+    dlg_cell_t *dlg = NULL;
+	dlg_iuid_t *iuid = NULL;
     int new_state, old_state, unref, event;
     str tag;
-    struct sip_msg *req = param->req;
-	struct sip_msg *rpl = param->rpl;
+    sip_msg_t *req = param->req;
+	sip_msg_t *rpl = param->rpl;
 
-	dlg = (struct dlg_cell *)(*param->param);
-	if (shutdown_done || dlg==0)
+	if (shutdown_done)
+		return;
+	iuid = (dlg_iuid_t*)(*param->param);
+	dlg = dlg_get_by_iuid(iuid);
+	if(dlg==0)
 		return;
 
+	unref = 0;
 	if (type==TMCB_RESPONSE_FWDED) {
 		/* The state does not change, but the msg is mutable in this callback*/
 		run_dlg_callbacks(DLGCB_RESPONSE_FWDED, dlg, req, rpl, DLG_DIR_UPSTREAM, 0);
-		return;
+		goto done;
 	}
 
 	if (type==TMCB_DESTROY)
@@ -395,7 +446,7 @@ static void dlg_onreply(struct cell* t, int type, struct tmcb_params *param)
 		run_dlg_callbacks(DLGCB_EARLY, dlg, req, rpl, DLG_DIR_UPSTREAM, 0);
 		if (old_state!=DLG_STATE_EARLY)
 			if_update_stat(dlg_enable_stats, early_dlgs, 1);
-		return;
+		goto done;
 	}
 
 	if (new_state==DLG_STATE_CONFIRMED_NA &&
@@ -444,7 +495,8 @@ static void dlg_onreply(struct cell* t, int type, struct tmcb_params *param)
 				dlg->tag[DLG_CALLER_LEG].len, dlg->tag[DLG_CALLER_LEG].s,
 				dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s);
 		} else {
-			ref_dlg(dlg,1);
+			/* dialog pointer inserted in timer list */
+			dlg_ref(dlg, 1);
 		}
 
 		/* dialog confirmed (ACK pending) */
@@ -453,9 +505,9 @@ static void dlg_onreply(struct cell* t, int type, struct tmcb_params *param)
 		if (old_state==DLG_STATE_EARLY)
 			if_update_stat(dlg_enable_stats, early_dlgs, -1);
 
-		if (unref) unref_dlg(dlg,unref);
+		if (unref) dlg_unref(dlg, unref);
 		if_update_stat(dlg_enable_stats, active_dlgs, 1);
-		return;
+		goto done;
 	}
 
 	if ( old_state!=DLG_STATE_DELETED && new_state==DLG_STATE_DELETED ) {
@@ -464,17 +516,20 @@ static void dlg_onreply(struct cell* t, int type, struct tmcb_params *param)
 		run_dlg_callbacks( DLGCB_FAILED, dlg, req, rpl, DLG_DIR_UPSTREAM, 0);
 		/* do unref */
 		if (unref)
-			unref_dlg(dlg,unref);
+			dlg_unref(dlg, unref);
 		if (old_state==DLG_STATE_EARLY)
 			if_update_stat(dlg_enable_stats, early_dlgs, -1);
 
 		if_update_stat(dlg_enable_stats, failed_dlgs, 1);
 
-		return;
+		goto done;
 	}
 
-	if (unref) unref_dlg(dlg,unref);
+	if (unref) dlg_unref(dlg, unref);
 
+done:
+	/* unref due to dlg_get_by_iuid() */
+	dlg_release(dlg);
 	return;
 }
 
@@ -491,10 +546,14 @@ static void dlg_onreply(struct cell* t, int type, struct tmcb_params *param)
 static void dlg_seq_onreply_helper(struct cell* t, int type,
 		struct tmcb_params *param, const int direction)
 {
-	struct dlg_cell *dlg;
+	dlg_cell_t *dlg = NULL;
+	dlg_iuid_t *iuid = NULL;
 
-	dlg = (struct dlg_cell *)(*param->param);
-	if (shutdown_done || dlg==0)
+	if (shutdown_done)
+		return;
+	iuid = (dlg_iuid_t*)(*param->param);
+	dlg = dlg_get_by_iuid(iuid);
+	if (dlg==0)
 		return;
 
 	if (type==TMCB_RESPONSE_FWDED)
@@ -505,8 +564,8 @@ static void dlg_seq_onreply_helper(struct cell* t, int type,
 		                   param->rpl,
 		                   direction,
 		                   0);
-		return;
 	}
+	dlg_release(dlg);
 
 	return;
 }
@@ -612,26 +671,31 @@ static inline int pre_match_parse( struct sip_msg *req, str *callid,
 void dlg_onreq(struct cell* t, int type, struct tmcb_params *param)
 {
 	sip_msg_t *req = param->req;
+	dlg_cell_t *dlg = NULL;
 
 	if(req->first_line.u.request.method_value != METHOD_INVITE)
 		return;
 
-	if (current_dlg_pointer!=NULL) {
+	dlg = dlg_get_ctx_dialog();
+
+	if (dlg!=NULL) {
 		if (!initial_cbs_inscript) {
 			if (spiral_detected == 1)
-				run_dlg_callbacks( DLGCB_SPIRALED, current_dlg_pointer,
+				run_dlg_callbacks( DLGCB_SPIRALED, dlg,
 						req, NULL, DLG_DIR_DOWNSTREAM, 0);
 			else if (spiral_detected == 0)
-				run_create_callbacks( current_dlg_pointer, req);
+				run_create_callbacks(dlg, req);
 		}
 	}
-	if (current_dlg_pointer==NULL) {
+	if (dlg==NULL) {
 		if((req->flags&dlg_flag)!=dlg_flag)
 			return;
 		dlg_new_dialog(req, t, 1);
+		dlg = dlg_get_ctx_dialog();
 	}
-	if (current_dlg_pointer!=NULL) {
-		dlg_set_tm_callbacks(t, req, current_dlg_pointer, spiral_detected);
+	if (dlg!=NULL) {
+		dlg_set_tm_callbacks(t, req, dlg, spiral_detected);
+		dlg_release(dlg);
 	}
 }
 
@@ -641,98 +705,15 @@ void dlg_onreq(struct cell* t, int type, struct tmcb_params *param)
  * \see dlg_onreq
  * \param dialog unreferenced dialog
  */
-static void unref_new_dialog(void *dialog)
+static void unref_new_dialog(void *iuid)
 {
 	struct tmcb_params p;
 
 	memset(&p, 0, sizeof(struct tmcb_params));
-	p.param = (void*)&dialog;
+	p.param = (void*)&iuid;
 	dlg_onreply(0, TMCB_DESTROY, &p);
 }
 
-/*!
- * \brief Unreference a dialog (small wrapper to take care of shutdown)
- * \see unref_dlg
- * \param dialog unreferenced dialog
- */
-static void unreference_dialog(void *dialog)
-{
-    // if the dialog table is gone, it means the system is shutting down.
-    if (!dialog || !d_table)
-        return;
-    unref_dlg((struct dlg_cell*)dialog, 1);
-}
-
-/*!
- * \brief Dummy callback just to keep the compiler happy
- * \param t unused
- * \param type unused
- * \param param unused
- */
-void dlg_tmcb_dummy(struct cell* t, int type, struct tmcb_params *param)
-{
-	return;
-}
-
-/*!
- * \brief Register a transaction on a dialog
- * \param msg SIP message
- * \param t registered transaction
- * \param dlg dialog to which the transaction should registered
- */
-static int store_dlg_in_tm(struct sip_msg* msg,
-                            struct cell* t,
-                            struct dlg_cell *dlg)
-{
-    if( !msg || msg == FAKED_REPLY || !t || !dlg)
-    {
-        LM_ERR("invalid parameter msg(%p), t(%p), dlg(%p)\n", msg, t, dlg);
-        return -1;
-    }
-
-    if(get_dialog_from_tm(t))
-    {
-        LM_NOTICE("dialog %p is already set for this transaction!\n",dlg);
-        return 1;
-    }
-
-	// facilitate referencing of dialog through TMCB_MAX
-    if( d_tmb.register_tmcb (msg,
-                             t,
-                             TMCB_MAX,
-                             dlg_tmcb_dummy,
-                             (void*)dlg, unreference_dialog)<0 )
-    {
-        LM_ERR("failed cache in T the shortcut to dlg %p\n",dlg);
-        return -3;
-    }
-
-	// registering succeeded, we must increase the reference counter
-    ref_dlg(dlg, 1);
-
-	return 0;
-}
-
-/*!
- * \brief Callback to register a transaction on a dialog
- * \param t transaction, unused
- * \param type type of the entered callback
- * \param param saved dialog structure in the callback
- */
-static void store_dlg_in_tm_cb (struct cell* t,
-                                int type,
-                                struct tmcb_params *param)
-{
-    struct dlg_cell *dlg = (struct dlg_cell *)(*param->param);
-
-    struct sip_msg* msg = param->rpl;
-    if (msg == NULL || msg == FAKED_REPLY)
-    {
-        msg = param->req;
-    }
-
-    store_dlg_in_tm (msg, t, dlg);
-}
 
 /*!
  * \brief Create a new dialog from a sip message
@@ -750,7 +731,7 @@ static void store_dlg_in_tm_cb (struct cell* t,
  */ 
 int dlg_new_dialog(struct sip_msg *req, struct cell *t, const int run_initial_cbs)
 {
-	struct dlg_cell *dlg;
+	dlg_cell_t *dlg;
 	str s;
 	str callid;
     str ftag;
@@ -758,8 +739,11 @@ int dlg_new_dialog(struct sip_msg *req, struct cell *t, const int run_initial_cb
     str req_uri;
     unsigned int dir;
 
-    if(current_dlg_pointer != NULL)
+	dlg = dlg_get_ctx_dialog();
+    if(dlg != NULL) {
+		dlg_release(dlg);
         return -1;
+	}
 
 	if(req->first_line.u.request.method_value != METHOD_INVITE)
 		return -1;
@@ -796,7 +780,7 @@ int dlg_new_dialog(struct sip_msg *req, struct cell *t, const int run_initial_cb
                 run_dlg_callbacks( DLGCB_SPIRALED, dlg, req, NULL,
 						DLG_DIR_DOWNSTREAM, 0);
             /* get_dlg() has incremented the ref count by 1
-			 * - it's ok, dlg will be used to set current_dialog_pointer */
+			 * - it's ok, dlg will be unref at the end of function */
             goto finish;
         }
     }
@@ -826,7 +810,7 @@ int dlg_new_dialog(struct sip_msg *req, struct cell *t, const int run_initial_cb
 	/* Populate initial varlist: */
 	dlg->vars = get_local_varlist_pointer(req, 1);
 
-	link_dlg(dlg,0);
+	link_dlg(dlg, 0);
 
 	dlg->lifetime = get_dlg_timeout(req);
 	s.s   = _dlg_ctx.to_route_name;
@@ -846,20 +830,22 @@ int dlg_new_dialog(struct sip_msg *req, struct cell *t, const int run_initial_cb
 		goto error;
 	}
 
-	/* reference it once for current_dialog_pointer */
-    ref_dlg(dlg, 1);
+	/* new dlg - reference it once more for current dialog iuid shortcut */
+    dlg_ref(dlg, 1);
 
     if_update_stat( dlg_enable_stats, processed_dlgs, 1);
 
 finish:
+    _dlg_ctx.iuid.h_entry = dlg->h_entry;
+    _dlg_ctx.iuid.h_id = dlg->h_id;
     set_current_dialog(req, dlg);
-    _dlg_ctx.dlg = dlg;
+	dlg_release(dlg);
 
 	return 0;
 
 error:
 	if (!spiral_detected)
-		unref_dlg(dlg,1);               // undo ref regarding linking
+		dlg_unref(dlg, 1);               // undo ref regarding linking
 	return -1;
 }
 
@@ -875,33 +861,25 @@ error:
 int dlg_set_tm_callbacks(tm_cell_t *t, sip_msg_t *req, dlg_cell_t *dlg,
 		int smode)
 {
+	dlg_iuid_t *iuid;
+	if(t==NULL)
+		return -1;
+
 	if(smode==0) {
+		iuid = dlg_get_iuid_shm_clone(dlg);
+		if(iuid==NULL) 
+		{
+			LM_ERR("failed to create dialog unique id clone\n");
+			goto error;
+		}
 		if ( d_tmb.register_tmcb( req, t,
 				TMCB_RESPONSE_READY|TMCB_RESPONSE_FWDED,
-				dlg_onreply, (void*)dlg, unref_new_dialog)<0 ) {
+				dlg_onreply, (void*)iuid, dlg_iuid_sfree)<0 ) {
 			LM_ERR("failed to register TMCB\n");
 			goto error;
 		}
-		// increase reference counter because of registered callback
-		ref_dlg(dlg, 1);
 	}
 
-	if (t) {
-		// transaction exists ==> keep ref counter large enough to
-		// avoid premature cleanup and ensure proper dialog referencing
-	    if (store_dlg_in_tm( req, t, dlg) < 0) {
-			LM_ERR("failed to store dialog in transaction\n");
-			goto error;
-		}
-	} else {
-		// no transaction exists ==> postpone work until we see the
-		// request being forwarded statefully
-        if ( d_tmb.register_tmcb( req, NULL, TMCB_REQUEST_FWDED,
-                store_dlg_in_tm_cb, (void*)dlg, NULL)<0 ) {
-            LM_ERR("failed to register callback for storing dialog in transaction\n");
-			goto error;
-        }
-	}
 	dlg->dflags |= DLG_FLAG_TM;
 
 	return 0;
@@ -976,16 +954,44 @@ static inline int update_cseqs(struct dlg_cell *dlg, struct sip_msg *req,
  */
 static void unref_dlg_from_cb(struct cell* t, int type, struct tmcb_params *param)
 {
-	struct dlg_cell *dlg = (struct dlg_cell *)(*param->param);
+	dlg_cell_t *dlg = NULL;
+	dlg_iuid_t *iuid = NULL;
 
-	if (!dlg)
+	iuid = (dlg_iuid_t*)(*param->param);
+	if (iuid==NULL)
 		return;
 
-	/* destroy dialog */
-	unreference_dialog(dlg);
+	dlg = dlg_get_by_iuid(iuid);
+	if(dlg==NULL)
+		return;
+	/* unref by 2: 1 set when adding in tm cb, 1 sent by dlg_get_by_iuid() */
+	dlg_unref(dlg, 2);
 }
 
 
+dlg_cell_t *dlg_get_msg_dialog(sip_msg_t *msg)
+{
+	dlg_cell_t *dlg = NULL;
+	str callid;
+    str ftag;
+    str ttag;
+
+	/* Retrieve the current dialog */
+	dlg = dlg_get_ctx_dialog();
+	if(dlg!=NULL)
+		return dlg;
+	
+	if (pre_match_parse(msg, &callid, &ftag, &ttag, 0)<0)
+		return NULL;
+	dlg = get_dlg(&callid, &ftag, &ttag, NULL);
+	if (dlg==NULL){
+		LM_DBG("dlg with callid '%.*s' not found\n",
+				msg->callid->body.len, msg->callid->body.s);
+		return NULL;
+	}
+	return dlg;
+}
+
 /*!
  * \brief Function that is registered as RR callback for dialog tracking
  * 
@@ -999,14 +1005,18 @@ static void unref_dlg_from_cb(struct cell* t, int type, struct tmcb_params *para
  */
 void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
 {
-	struct dlg_cell *dlg;
+	dlg_cell_t *dlg;
+	dlg_iuid_t *iuid;
 	str val, callid, ftag, ttag;
 	int h_entry, h_id, new_state, old_state, unref, event, timeout;
 	unsigned int dir;
 	int ret = 0;
 
-	if (current_dlg_pointer!=NULL)
+	dlg = dlg_get_ctx_dialog();
+	if (dlg!=NULL) {
+		dlg_release(dlg);
 		return;
+	}
 
 	/* skip initial requests - they may end up here because of the
 	 * preloaded route */
@@ -1031,7 +1041,7 @@ 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 = dlg_lookup(h_entry, h_id);
 			if (dlg==0) {
 				LM_WARN("unable to find dialog for %.*s "
 					"with route param '%.*s' [%u:%u]\n",
@@ -1043,7 +1053,7 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
 			} else {
 				if (pre_match_parse( req, &callid, &ftag, &ttag, 1)<0) {
 					// lookup_dlg has incremented the ref count by 1
-					unref_dlg(dlg, 1);
+					dlg_release(dlg);
 					return;
 				}
 				if (match_dialog( dlg, &callid, &ftag, &ttag, &dir )==0) {
@@ -1062,7 +1072,7 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
 							dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s,
 							dlg->tag[DLG_CALLEE_LEG].len);
 					// lookup_dlg has incremented the ref count by 1
-					unref_dlg(dlg, 1);
+					dlg_release(dlg);
 
 					// Reset variables in order to do a lookup based on SIP-Elements.
 					dlg = 0;
@@ -1081,7 +1091,7 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
 		/* TODO - try to use the RR dir detection to speed up here the
 		 * search -bogdan */
 		dlg = get_dlg(&callid, &ftag, &ttag, &dir);
-		if (!dlg){
+		if (dlg==0){
 			LM_DBG("Callid '%.*s' not found\n",
 				req->callid->body.len, req->callid->body.s);
 			return;
@@ -1090,12 +1100,8 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
 
     /* set current dialog - re-use ref increment from dlg_get() above */
     set_current_dialog( req, dlg);
-    _dlg_ctx.dlg = dlg;
-
-    if ( d_tmb.register_tmcb( req, NULL, TMCB_REQUEST_FWDED,
-            store_dlg_in_tm_cb, (void*)dlg, NULL)<0 ) {
-        LM_ERR("failed to store dialog in transaction during dialog creation for later reference\n");
-    }
+    _dlg_ctx.iuid.h_entry = dlg->h_entry;
+    _dlg_ctx.iuid.h_id = dlg->h_id;
 
 	/* run state machine */
 	switch ( req->first_line.u.request.method_value ) {
@@ -1118,11 +1124,15 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
 	/* delay deletion of dialog until transaction has died off in order
 	 * to absorb in-air messages */
 	if (new_state==DLG_STATE_DELETED && old_state!=DLG_STATE_DELETED) {
-		if ( d_tmb.register_tmcb(req, NULL, TMCB_DESTROY,
-					unref_dlg_from_cb, (void*)dlg, NULL)<0 ) {
-			LM_ERR("failed to register deletion delay function\n");
-		} else {
-			ref_dlg(dlg, 1);
+		iuid = dlg_get_iuid_shm_clone(dlg);
+		if(iuid!=NULL) {
+			if ( d_tmb.register_tmcb(req, NULL, TMCB_DESTROY,
+					unref_dlg_from_cb, (void*)iuid, dlg_iuid_sfree)<0 ) {
+				LM_ERR("failed to register deletion delay function\n");
+				shm_free(iuid);
+			} else {
+				dlg_ref(dlg, 1);
+			}
 		}
 	}
 
@@ -1147,15 +1157,16 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
 				dlg->tag[DLG_CALLER_LEG].len, dlg->tag[DLG_CALLER_LEG].s,
 				dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s);
 		} else {
+			/* one extra unref due to removal from timer list */
 			unref++;
 		}
 		/* dialog terminated (BYE) */
         dlg_terminated( req, dlg, dir);
 
-		unref_dlg(dlg, unref);
+		dlg_unref(dlg, unref);
 
 		if_update_stat( dlg_enable_stats, active_dlgs, -1);
-		return;
+		goto done;
 	}
 
 	if ( (event==DLG_EVENT_REQ || event==DLG_EVENT_REQACK)
@@ -1189,15 +1200,17 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
 
 			if ( (event!=DLG_EVENT_REQACK) &&
 					(dlg->cbs.types)&DLGCB_RESPONSE_WITHIN ) {
-				/* ref the dialog as registered into the transaction callback.
-				 * unref will be done when the callback will be destroyed */
-				ref_dlg( dlg , 1);
-				/* register callback for the replies of this request */
-				if ( d_tmb.register_tmcb( req, 0, TMCB_RESPONSE_FWDED,
-							(dir==DLG_DIR_UPSTREAM)?dlg_seq_down_onreply:dlg_seq_up_onreply,
-							(void*)dlg, unreference_dialog)<0 ) {
-					LM_ERR("failed to register TMCB (2)\n");
-					unref_dlg( dlg , 1);
+				iuid = dlg_get_iuid_shm_clone(dlg);
+				if(iuid!=NULL)
+				{
+					/* register callback for the replies of this request */
+					if ( d_tmb.register_tmcb( req, 0, TMCB_RESPONSE_FWDED,
+							(dir==DLG_DIR_UPSTREAM)?dlg_seq_down_onreply:
+														dlg_seq_up_onreply,
+							(void*)iuid, dlg_iuid_sfree)<0 ) {
+						LM_ERR("failed to register TMCB (2)\n");
+						shm_free(iuid);
+					}
 				}
 			}
 		}
@@ -1209,6 +1222,8 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
 			update_dialog_dbinfo(dlg);
 	}
 
+done:
+	dlg_release(dlg);
 	return;
 }
 
@@ -1217,15 +1232,15 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
  * \brief Timer function that removes expired dialogs, run timeout route
  * \param tl dialog timer list
  */
-void dlg_ontimeout( struct dlg_tl *tl)
+void dlg_ontimeout(struct dlg_tl *tl)
 {
-	struct dlg_cell *dlg;
+	dlg_cell_t *dlg;
 	int new_state, old_state, unref;
-	struct sip_msg *fmsg;
+	sip_msg_t *fmsg;
 
 	/* get the dialog tl payload */
 	dlg = ((struct dlg_cell*)((char *)(tl) -
-		(unsigned long)(&((struct dlg_cell*)0)->tl)));
+			(unsigned long)(&((struct dlg_cell*)0)->tl)));
 
 	if(dlg->toroute>0 && dlg->toroute<main_rt.entries
 			&& main_rt.rlist[dlg->toroute]!=NULL)
@@ -1233,12 +1248,14 @@ void dlg_ontimeout( struct dlg_tl *tl)
 		fmsg = faked_msg_next();
 		if (exec_pre_script_cb(fmsg, REQUEST_CB_TYPE)>0)
 		{
-			dlg_set_ctx_dialog(dlg);
+			dlg_ref(dlg, 1);
+			dlg_set_ctx_iuid(dlg);
 			LM_DBG("executing route %d on timeout\n", dlg->toroute);
 			set_route_type(REQUEST_ROUTE);
 			run_top_route(main_rt.rlist[dlg->toroute], fmsg, 0);
-			dlg_set_ctx_dialog(0);
+			dlg_reset_ctx_iuid();
 			exec_post_script_cb(fmsg, REQUEST_CB_TYPE);
+			dlg_unref(dlg, 1);
 		}
 	}
 
@@ -1247,7 +1264,7 @@ void dlg_ontimeout( struct dlg_tl *tl)
 				|| dlg->state==DLG_STATE_CONFIRMED))
 	{
 		dlg_bye_all(dlg, NULL);
-		unref_dlg(dlg, 1);
+		dlg_unref(dlg, 1);
 		if_update_stat(dlg_enable_stats, expired_dlgs, 1);
 		return;
 	}
@@ -1263,12 +1280,12 @@ void dlg_ontimeout( struct dlg_tl *tl)
 		/* dialog timeout */
 		run_dlg_callbacks( DLGCB_EXPIRED, dlg, NULL, NULL, DLG_DIR_NONE, 0);
 
-		unref_dlg(dlg, unref+1);
+		dlg_unref(dlg, unref+1);
 
 		if_update_stat( dlg_enable_stats, expired_dlgs, 1);
 		if_update_stat( dlg_enable_stats, active_dlgs, -1);
 	} else {
-		unref_dlg(dlg, 1);
+		dlg_unref(dlg, 1);
 	}
 
 	return;

+ 14 - 9
modules_k/dialog/dlg_handlers.h

@@ -81,8 +81,8 @@ void destroy_dlg_handlers(void);
  * \note for a request: get record route in normal order, for a reply get
  * in reverse order, skipping the ones from the request and the proxies' own
  */
-int populate_leg_info( struct dlg_cell *dlg, struct sip_msg *msg,
-	struct cell* t, unsigned int leg, str *tag);
+int populate_leg_info(dlg_cell_t *dlg, sip_msg_t *msg,
+	tm_cell_t *t, unsigned int leg, str *tag);
 
 
 /*!
@@ -91,7 +91,7 @@ int populate_leg_info( struct dlg_cell *dlg, struct sip_msg *msg,
  * \param type type of the entered callback
  * \param param saved dialog structure in the callback
  */
-void dlg_onreq(struct cell* t, int type, struct tmcb_params *param);
+void dlg_onreq(tm_cell_t *t, int type, struct tmcb_params *param);
 
 
 /*!
@@ -105,14 +105,14 @@ void dlg_onreq(struct cell* t, int type, struct tmcb_params *param);
  * \param route_params record-route parameter
  * \param param unused
  */
-void dlg_onroute(struct sip_msg* req, str *rr_param, void *param);
+void dlg_onroute(sip_msg_t *req, str *rr_param, void *param);
 
 
 /*!
  * \brief Timer function that removes expired dialogs, run timeout route
  * \param tl dialog timer list
  */
-void dlg_ontimeout( struct dlg_tl *tl);
+void dlg_ontimeout(dlg_tl_t *tl);
 
 
 /*!
@@ -129,7 +129,7 @@ void dlg_ontimeout( struct dlg_tl *tl);
  * \param run_initial_cbs if set zero, initial callbacks are not executed
  * \return 0 on success, -1 on failure
  */ 
-int dlg_new_dialog(struct sip_msg *req, struct cell *t, const int run_initial_cbs);
+int dlg_new_dialog(sip_msg_t *req, tm_cell_t *t, const int run_initial_cbs);
 
 
 /*!
@@ -139,7 +139,7 @@ int dlg_new_dialog(struct sip_msg *req, struct cell *t, const int run_initial_cb
  * \param res pseudo-variable result
  * \return 0 on success, -1 on failure
  */
-int pv_get_dlg_lifetime(struct sip_msg *msg, pv_param_t *param,
+int pv_get_dlg_lifetime(sip_msg_t *msg, pv_param_t *param,
 		pv_value_t *res);
 
 
@@ -150,7 +150,7 @@ int pv_get_dlg_lifetime(struct sip_msg *msg, pv_param_t *param,
  * \param res pseudo-variable result
  * \return 0 on success, -1 on failure
  */
-int pv_get_dlg_status(struct sip_msg *msg, pv_param_t *param,
+int pv_get_dlg_status(sip_msg_t *msg, pv_param_t *param,
 		pv_value_t *res);
 
 
@@ -160,6 +160,11 @@ int pv_get_dlg_status(struct sip_msg *msg, pv_param_t *param,
  * \param type unused
  * \param param unused
  */
-void dlg_tmcb_dummy(struct cell* t, int type, struct tmcb_params *param);
+void dlg_tmcb_dummy(tm_cell_t *t, int type, struct tmcb_params *param);
+
+/*!
+ * \brief Get the dialog structure for the SIP message
+ */
+dlg_cell_t *dlg_get_msg_dialog(sip_msg_t *msg);
 
 #endif

+ 45 - 15
modules_k/dialog/dlg_hash.c

@@ -209,9 +209,6 @@ inline void destroy_dlg(struct dlg_cell *dlg)
 	if (dlg_db_mode)
 		remove_dialog_from_db(dlg);
 
-	if(dlg==get_current_dlg_pointer())
-		reset_current_dlg_pointer();
-
 	if (dlg->cbs.first)
 		destroy_dlg_callbacks_list(dlg->cbs.first);
 
@@ -442,10 +439,10 @@ error:
  * \param h_id id of the hash table entry
  * \return dialog structure on success, NULL on failure
  */
-struct dlg_cell* lookup_dlg( unsigned int h_entry, unsigned int h_id)
+dlg_cell_t *dlg_lookup( unsigned int h_entry, unsigned int h_id)
 {
-	struct dlg_cell *dlg;
-	struct dlg_entry *d_entry;
+	dlg_cell_t *dlg;
+	dlg_entry_t *d_entry;
 
 	if (h_entry>=d_table->size)
 		goto not_found;
@@ -470,6 +467,24 @@ not_found:
 }
 
 
+/*!
+ * \brief Search a dialog in the global list by iuid
+ *
+ * Note that the caller is responsible for decrementing (or reusing)
+ * the reference counter by one again if a dialog has been found.
+ * \param diuid internal unique id per dialog
+ * \return dialog structure on success, NULL on failure
+ */
+dlg_cell_t* dlg_get_by_iuid(dlg_iuid_t *diuid)
+{
+	if(diuid==NULL)
+		return NULL;
+	if(diuid->h_id==0)
+		return NULL;
+	/* dlg ref counter is increased by next line */
+	return dlg_lookup(diuid->h_entry, diuid->h_id);
+}
+
 /*!
  * \brief Helper function to get a dialog corresponding to a SIP message
  * \see get_dlg
@@ -552,7 +567,8 @@ void link_dlg(struct dlg_cell *dlg, int n)
 
 	dlg_lock( d_table, d_entry);
 
-	dlg->h_id = d_entry->next_id++;
+	/* keep id 0 for special cases */
+	dlg->h_id = 1 + d_entry->next_id++;
 	if (d_entry->first==0) {
 		d_entry->first = d_entry->last = dlg;
 	} else {
@@ -574,9 +590,9 @@ void link_dlg(struct dlg_cell *dlg, int n)
  * \param dlg dialog
  * \param cnt increment for the reference counter
  */
-void ref_dlg(struct dlg_cell *dlg, unsigned int cnt)
+void dlg_ref(dlg_cell_t *dlg, unsigned int cnt)
 {
-	struct dlg_entry *d_entry;
+	dlg_entry_t *d_entry;
 
 	d_entry = &(d_table->entries[dlg->h_entry]);
 
@@ -592,9 +608,9 @@ void ref_dlg(struct dlg_cell *dlg, unsigned int cnt)
  * \param dlg dialog
  * \param cnt decrement for the reference counter
  */
-void unref_dlg(struct dlg_cell *dlg, unsigned int cnt)
+void dlg_unref(dlg_cell_t *dlg, unsigned int cnt)
 {
-	struct dlg_entry *d_entry;
+	dlg_entry_t *d_entry;
 
 	d_entry = &(d_table->entries[dlg->h_entry]);
 
@@ -605,7 +621,20 @@ void unref_dlg(struct dlg_cell *dlg, unsigned int cnt)
 
 
 /*!
- * Small logging helper functions for next_state_dlg.
+ * \brief Release a dialog from ref counter by 1
+ * \see dlg_unref
+ * \param dlg dialog
+ */
+void dlg_release(dlg_cell_t *dlg)
+{
+	if(dlg==NULL)
+		return;
+	dlg_unref(dlg, 1);
+}
+
+
+/*!
+ * \brief Small logging helper functions for next_state_dlg.
  * \param event logged event
  * \param dlg dialog data
  * \see next_state_dlg
@@ -632,10 +661,10 @@ static inline void log_next_state_dlg(const int event, const struct dlg_cell *dl
  * \param new_state new dialog state
  * \param unref set to 1 when the dialog was deleted, 0 otherwise
  */
-void next_state_dlg(struct dlg_cell *dlg, int event,
+void next_state_dlg(dlg_cell_t *dlg, int event,
 		int *old_state, int *new_state, int *unref)
 {
-	struct dlg_entry *d_entry;
+	dlg_entry_t *d_entry;
 
 	d_entry = &(d_table->entries[dlg->h_entry]);
 
@@ -772,7 +801,8 @@ void next_state_dlg(struct dlg_cell *dlg, int event,
 	dlg_unlock( d_table, d_entry);
 
 	LM_DBG("dialog %p changed from state %d to "
-		"state %d, due event %d\n",dlg,*old_state,*new_state,event);
+		"state %d, due event %d (ref %d)\n", dlg, *old_state, *new_state, event,
+		dlg->ref);
 }
 
 /**

+ 47 - 26
modules_k/dialog/dlg_hash.h

@@ -89,14 +89,20 @@
 #define DLG_DIR_UPSTREAM       2 /*!< dialog has upstream direction */
 
 
+/*! internal unique ide per dialog */
+typedef struct dlg_iuid {
+	unsigned int         h_id;		/*!< id in the hash table entry (seq nr in slot) */
+	unsigned int         h_entry;	/*!< index of hash table entry (the slot number) */
+} dlg_iuid_t;
+
 /*! entries in the dialog list */
 typedef struct dlg_cell
 {
 	volatile int         ref;		/*!< reference counter */
 	struct dlg_cell      *next;		/*!< next entry in the list */
 	struct dlg_cell      *prev;		/*!< previous entry in the list */
-	unsigned int         h_id;		/*!< id of the hash table entry */
-	unsigned int         h_entry;		/*!< number of hash entry */
+	unsigned int         h_id;		/*!< id in the hash table entry (seq nr in slot) */
+	unsigned int         h_entry;	/*!< index of hash table entry (the slot number) */
 	unsigned int         state;		/*!< dialog state */
 	unsigned int         lifetime;		/*!< dialog lifetime */
 	unsigned int         start_ts;		/*!< start time  (absolute UNIX ts)*/
@@ -105,7 +111,7 @@ typedef struct dlg_cell
 	unsigned int         toroute;		/*!< index of route that is executed on timeout */
 	str                  toroute_name;	/*!< name of route that is executed on timeout */
 	unsigned int         from_rr_nb;	/*!< information from record routing */
-	struct dlg_tl        tl;		/*!< dialog timer list */
+	struct dlg_tl        tl;			/*!< dialog timer list */
 	str                  callid;		/*!< callid from SIP message */
 	str                  from_uri;		/*!< from uri from SIP message */
 	str                  to_uri;		/*!< to uri from SIP message */
@@ -122,29 +128,27 @@ typedef struct dlg_cell
 
 
 /*! entries in the main dialog table */
-struct dlg_entry
+typedef struct dlg_entry
 {
 	struct dlg_cell    *first;	/*!< dialog list */
 	struct dlg_cell    *last;	/*!< optimisation, end of the dialog list */
 	unsigned int       next_id;	/*!< next id */
 	unsigned int       lock_idx;	/*!< lock index */
-};
+} dlg_entry_t;
 
 
 /*! main dialog table */
-struct dlg_table
+typedef struct dlg_table
 {
 	unsigned int       size;	/*!< size of the dialog table */
 	struct dlg_entry   *entries;	/*!< dialog hash table */
 	unsigned int       locks_no;	/*!< number of locks */
 	gen_lock_set_t     *locks;	/*!< lock table */
-};
+} dlg_table_t;
 
 
 /*! global dialog table */
-extern struct dlg_table *d_table;
-/*! point to the current dialog */
-extern struct dlg_cell  *current_dlg_pointer;
+extern dlg_table_t *d_table;
 
 
 /*!
@@ -170,7 +174,7 @@ extern struct dlg_cell  *current_dlg_pointer;
  * \param d_entry unlinked entry
  * \param dlg unlinked dialog
  */
-static inline void unlink_unsafe_dlg(struct dlg_entry *d_entry, struct dlg_cell *dlg)
+static inline void unlink_unsafe_dlg(dlg_entry_t *d_entry, dlg_cell_t *dlg)
 {
 	if (dlg->next)
 		dlg->next->prev = dlg->prev;
@@ -191,7 +195,7 @@ static inline void unlink_unsafe_dlg(struct dlg_entry *d_entry, struct dlg_cell
  * \brief Destroy a dialog, run callbacks and free memory
  * \param dlg destroyed dialog
  */
-inline void destroy_dlg(struct dlg_cell *dlg);
+inline void destroy_dlg(dlg_cell_t *dlg);
 
 
 /*!
@@ -217,7 +221,7 @@ void destroy_dlg_table(void);
  * \param req_uri dialog r-uri
  * \return created dialog structure on success, NULL otherwise
  */
-struct dlg_cell* build_new_dlg(str *callid, str *from_uri,
+dlg_cell_t* build_new_dlg(str *callid, str *from_uri,
 		str *to_uri, str *from_tag, str *req_uri);
 
 
@@ -231,7 +235,7 @@ struct dlg_cell* build_new_dlg(str *callid, str *from_uri,
  * \param leg must be either DLG_CALLER_LEG, or DLG_CALLEE_LEG
  * \return 0 on success, -1 on failure
  */
-int dlg_set_leg_info(struct dlg_cell *dlg, str* tag, str *rr, str *contact,
+int dlg_set_leg_info(dlg_cell_t *dlg, str* tag, str *rr, str *contact,
 		str *cseq, unsigned int leg);
 
 
@@ -242,7 +246,7 @@ int dlg_set_leg_info(struct dlg_cell *dlg, str* tag, str *rr, str *contact,
  * \param cseq CSEQ of caller or callee
  * \return 0 on success, -1 on failure
  */
-int dlg_update_cseq(struct dlg_cell *dlg, unsigned int leg, str *cseq);
+int dlg_update_cseq(dlg_cell_t *dlg, unsigned int leg, str *cseq);
 
 /*!
  * \brief Set time-out route
@@ -250,19 +254,29 @@ int dlg_update_cseq(struct dlg_cell *dlg, unsigned int leg, str *cseq);
  * \param route name of route
  * \return 0 on success, -1 on failure
  */
-int dlg_set_toroute(struct dlg_cell *dlg, str *route);
+int dlg_set_toroute(dlg_cell_t *dlg, str *route);
 
 
 /*!
  * \brief Lookup a dialog in the global list
  *
  * Note that the caller is responsible for decrementing (or reusing)
- * the reference counter by one again iff a dialog has been found.
+ * the reference counter by one again if a dialog has been found.
  * \param h_entry number of the hash table entry
  * \param h_id id of the hash table entry
  * \return dialog structure on success, NULL on failure
  */
-struct dlg_cell* lookup_dlg( unsigned int h_entry, unsigned int h_id);
+dlg_cell_t* dlg_lookup(unsigned int h_entry, unsigned int h_id);
+
+/*!
+ * \brief Search and return dialog in the global list by iuid
+ *
+ * Note that the caller is responsible for decrementing (or reusing)
+ * the reference counter by one again if a dialog has been found.
+ * \param diuid internal unique id per dialog
+ * \return dialog structure on success, NULL on failure
+ */
+dlg_cell_t* dlg_get_by_iuid(dlg_iuid_t *diuid);
 
 
 /*!
@@ -281,7 +295,7 @@ struct dlg_cell* lookup_dlg( unsigned int h_entry, unsigned int h_id);
  * \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);
+dlg_cell_t* get_dlg(str *callid, str *ftag, str *ttag, unsigned int *dir);
 
 
 /*!
@@ -289,7 +303,7 @@ struct dlg_cell* get_dlg(str *callid, str *ftag, str *ttag, unsigned int *dir);
  * \param dlg dialog
  * \param n extra increments for the reference counter
  */
-void link_dlg(struct dlg_cell *dlg, int n);
+void link_dlg(dlg_cell_t *dlg, int n);
 
 
 /*!
@@ -298,7 +312,7 @@ void link_dlg(struct dlg_cell *dlg, int n);
  * \param dlg dialog
  * \param cnt decrement for the reference counter
  */
-void unref_dlg(struct dlg_cell *dlg, unsigned int cnt);
+void dlg_unref(dlg_cell_t *dlg, unsigned int cnt);
 
 
 /*!
@@ -307,8 +321,15 @@ void unref_dlg(struct dlg_cell *dlg, unsigned int cnt);
  * \param dlg dialog
  * \param cnt increment for the reference counter
  */
-void ref_dlg(struct dlg_cell *dlg, unsigned int cnt);
+void dlg_ref(dlg_cell_t *dlg, unsigned int cnt);
+
 
+/*!
+ * \brief Release a dialog from ref counter by 1
+ * \see dlg_unref
+ * \param dlg dialog
+ */
+void dlg_release(dlg_cell_t *dlg);
 
 /*!
  * \brief Update a dialog state according a event and the old state
@@ -323,7 +344,7 @@ void ref_dlg(struct dlg_cell *dlg, unsigned int cnt);
  * \param new_state new dialog state
  * \param unref set to 1 when the dialog was deleted, 0 otherwise
  */
-void next_state_dlg(struct dlg_cell *dlg, int event,
+void next_state_dlg(dlg_cell_t *dlg, int event,
 		int *old_state, int *new_state, int *unref);
 
 
@@ -361,7 +382,7 @@ struct mi_root * mi_terminate_dlgs(struct mi_root *cmd_tree, void *param );
  * \param dir direction of the message, if DLG_DIR_NONE it will set
  * \return 1 if dialog structure and message content matches, 0 otherwise
  */
-static inline int match_dialog(struct dlg_cell *dlg, str *callid,
+static inline int match_dialog(dlg_cell_t *dlg, str *callid,
 							   str *ftag, str *ttag, unsigned int *dir) {
 	if (dlg->tag[DLG_CALLEE_LEG].len == 0) {
         // dialog to tag is undetermined ATM.
@@ -451,7 +472,7 @@ static inline int match_dialog(struct dlg_cell *dlg, str *callid,
  * \param ftag SIP message from tag
  * \return 1 if dialog structure matches the SIP dialog, 0 otherwise
  */
-static inline int match_downstream_dialog(struct dlg_cell *dlg, str *callid, str *ftag)
+static inline int match_downstream_dialog(dlg_cell_t *dlg, str *callid, str *ftag)
 {
 	if(dlg==NULL || callid==NULL)
 		return 0;
@@ -477,6 +498,6 @@ static inline int match_downstream_dialog(struct dlg_cell *dlg, str *callid, str
  * \param with_context if 1 then the dialog context will be also printed
  * \return 0 on success, -1 on failure
  */
-int mi_print_dlg(struct mi_node *rpl, struct dlg_cell *dlg, int with_context);
+int mi_print_dlg(struct mi_node *rpl, dlg_cell_t *dlg, int with_context);
 
 #endif

+ 57 - 88
modules_k/dialog/dlg_profile.c

@@ -40,6 +40,7 @@
 #include "../../route.h"
 #include "../../modules/tm/tm_load.h"
 #include "dlg_hash.h"
+#include "dlg_var.h"
 #include "dlg_handlers.h"
 #include "dlg_profile.h"
 
@@ -51,31 +52,20 @@
 extern struct tm_binds d_tmb;
 
 /*! global dialog message id */
-static unsigned int            current_dlg_msg_id = 0 ;
-
-/*! global dialog */
-struct dlg_cell                *current_dlg_pointer = NULL ;
+static unsigned int       current_dlg_msg_id  = 0 ;
+static unsigned int       current_dlg_msg_pid = 0 ;
 
 /*! pending dialog links */
-static struct dlg_profile_link *current_pending_linkers = NULL;
+static dlg_profile_link_t *current_pending_linkers = NULL;
 
 /*! global dialog profile list */
-static struct dlg_profile_table *profiles = NULL;
+static dlg_profile_table_t *profiles = NULL;
 
 
-static struct dlg_profile_table* new_dlg_profile( str *name,
+static dlg_profile_table_t* new_dlg_profile( str *name,
 		unsigned int size, unsigned int has_value);
 
 
-struct dlg_cell *get_current_dlg_pointer(void)
-{
-	return current_dlg_pointer;
-}
-
-void reset_current_dlg_pointer(void)
-{
-	current_dlg_pointer = NULL;
-}
 
 /*!
  * \brief Add profile definitions to the global list
@@ -310,15 +300,18 @@ void destroy_linkers(struct dlg_profile_link *linker)
  */
 int profile_cleanup( struct sip_msg *msg, unsigned int flags, void *param )
 {
+	dlg_cell_t *dlg;
+
 	current_dlg_msg_id = 0;
-	if (current_dlg_pointer) {
-		if(current_dlg_pointer->dflags & DLG_FLAG_TM) {
-			unref_dlg( current_dlg_pointer, 1);
+	current_dlg_msg_pid = 0;
+	dlg = dlg_get_ctx_dialog();
+	if (dlg!=NULL) {
+		if(dlg->dflags & DLG_FLAG_TM) {
+			dlg_unref(dlg, 1);
 		} else {
 			/* dialog didn't make it to tm */
-			unref_dlg( current_dlg_pointer, 2);
+			dlg_unref(dlg, 2);
 		}
-		current_dlg_pointer = NULL;
 	}
 	if (current_pending_linkers) {
 		destroy_linkers(current_pending_linkers);
@@ -331,47 +324,6 @@ int profile_cleanup( struct sip_msg *msg, unsigned int flags, void *param )
 
 
 
-struct dlg_cell* get_dialog_from_tm(struct cell *t)
-{
-    if (t==NULL || t==T_UNDEFINED)
-        return NULL;
-
-    struct tm_callback* x = (struct tm_callback*)(t->tmcb_hl.first);
-
-    while(x){
-        membar_depends();
-        if (x->types==TMCB_MAX && x->callback==dlg_tmcb_dummy){
-            return (struct dlg_cell*)(x->param);
-        }
-        x=x->next;
-    }
-
-    return NULL;
-}
-
-/*!
- * \brief Get the current dialog for a message, if exists
- * \param msg SIP message
- * \return NULL if called in REQUEST_ROUTE, pointer to dialog ctx otherwise
- */ 
-struct dlg_cell *get_current_dialog(struct sip_msg *msg)
-{
-	if (is_route_type(REQUEST_ROUTE|BRANCH_ROUTE)) {
-		/* use the per-process static holder */
-		if (msg->id==current_dlg_msg_id)
-			return current_dlg_pointer;
-		current_dlg_pointer = NULL;
-		current_dlg_msg_id = msg->id;
-		destroy_linkers(current_pending_linkers);
-		current_pending_linkers = NULL;
-		return NULL;
-	} else {
-		/* use current transaction to get dialog */
-	    return get_dialog_from_tm(d_tmb.t_gett());
-	}
-}
-
-
 /*!
  * \brief Calculate the hash profile from a dialog
  * \see core_hash
@@ -380,8 +332,8 @@ struct dlg_cell *get_current_dialog(struct sip_msg *msg)
  * \param profile dialog profile table (for hash size)
  * \return value hash if the value has a value, hash over dialog otherwise
  */
-inline static unsigned int calc_hash_profile(str *value, struct dlg_cell *dlg,
-		struct dlg_profile_table *profile)
+inline static unsigned int calc_hash_profile(str *value, dlg_cell_t *dlg,
+		dlg_profile_table_t *profile)
 {
 	if (profile->has_value) {
 		/* do hash over the value */
@@ -446,17 +398,18 @@ static void link_dlg_profile(struct dlg_profile_link *linker, struct dlg_cell *d
  * \param msg SIP message
  * \param dlg dialog cell
  */
-void set_current_dialog(struct sip_msg *msg, struct dlg_cell *dlg)
+void set_current_dialog(sip_msg_t *msg, dlg_cell_t *dlg)
 {
 	struct dlg_profile_link *linker;
 	struct dlg_profile_link *tlinker;
 
 	/* if linkers are not from current request, just discard them */
-	if (msg->id!=current_dlg_msg_id) {
+	if (msg->id!=current_dlg_msg_id || msg->pid!=current_dlg_msg_pid) {
 		current_dlg_msg_id = msg->id;
+		current_dlg_msg_pid = msg->pid;
 		destroy_linkers(current_pending_linkers);
 	} else {
-		/* add the linker, one be one, to the dialog */
+		/* add the linker, one by one, to the dialog */
 		linker = current_pending_linkers;
 		while (linker) {
 			tlinker = linker;
@@ -467,10 +420,6 @@ void set_current_dialog(struct sip_msg *msg, struct dlg_cell *dlg)
 		}
 	}
 	current_pending_linkers = NULL;
-	current_dlg_pointer = dlg;
-
-	/* do not increase reference counter here, let caller handle it
-	 * (yes, this is somewhat ugly) */
 }
 
 
@@ -483,11 +432,11 @@ void set_current_dialog(struct sip_msg *msg, struct dlg_cell *dlg)
  */
 int set_dlg_profile(struct sip_msg *msg, str *value, struct dlg_profile_table *profile)
 {
-	struct dlg_cell *dlg;
-	struct dlg_profile_link *linker;
+	dlg_cell_t *dlg = NULL;
+	dlg_profile_link_t *linker;
 
 	/* get current dialog */
-	dlg = get_current_dialog(msg);
+	dlg = dlg_get_msg_dialog(msg);
 
 	if (dlg==NULL && !is_route_type(REQUEST_ROUTE)) {
 		LM_CRIT("BUG - dialog not found in a non REQUEST route (%d)\n",
@@ -500,7 +449,7 @@ int set_dlg_profile(struct sip_msg *msg, str *value, struct dlg_profile_table *p
 		sizeof(struct dlg_profile_link) + (profile->has_value?value->len:0) );
 	if (linker==NULL) {
 		LM_ERR("no more shm memory\n");
-		return -1;
+		goto error;
 	}
 	memset(linker, 0, sizeof(struct dlg_profile_link));
 
@@ -523,7 +472,11 @@ int set_dlg_profile(struct sip_msg *msg, str *value, struct dlg_profile_table *p
 		current_pending_linkers = linker;
 	}
 
+	dlg_release(dlg);
 	return 0;
+error:
+	dlg_release(dlg);
+	return -1;
 }
 
 
@@ -534,19 +487,24 @@ int set_dlg_profile(struct sip_msg *msg, str *value, struct dlg_profile_table *p
  * \param profile dialog profile table
  * \return 1 on success, -1 on failure
  */
-int unset_dlg_profile(struct sip_msg *msg, str *value,
-		struct dlg_profile_table *profile)
+int unset_dlg_profile(sip_msg_t *msg, str *value,
+		dlg_profile_table_t *profile)
 {
-	struct dlg_cell *dlg;
-	struct dlg_profile_link *linker;
-	struct dlg_profile_link *linker_prev;
-	struct dlg_entry *d_entry;
+	dlg_cell_t *dlg;
+	dlg_profile_link_t *linker;
+	dlg_profile_link_t *linker_prev;
+	dlg_entry_t *d_entry;
+
+	if (is_route_type(REQUEST_ROUTE)) {
+		LM_ERR("dialog delete profile cannot be used in request route\n");
+		return -1;
+	}
 
 	/* get current dialog */
-	dlg = get_current_dialog(msg);
+	dlg = dlg_get_msg_dialog(msg);
 
-	if (dlg==NULL || is_route_type(REQUEST_ROUTE)) {
-		LM_CRIT("BUG - dialog NULL or del_profile used in request route\n");
+	if (dlg==NULL) {
+		LM_WARN("dialog is NULL for delete profile\n");
 		return -1;
 	}
 
@@ -569,6 +527,7 @@ int unset_dlg_profile(struct sip_msg *msg, str *value,
 		}
 	}
 	dlg_unlock( d_table, d_entry);
+	dlg_release(dlg);
 	return -1;
 
 found:
@@ -583,6 +542,7 @@ found:
 	dlg_unlock( d_table, d_entry);
 	/* remove linker from profile table and free it */
 	destroy_linkers(linker);
+	dlg_release(dlg);
 	return 1;
 }
 
@@ -602,7 +562,7 @@ int is_dlg_in_profile(struct sip_msg *msg, struct dlg_profile_table *profile,
 	struct dlg_entry *d_entry;
 
 	/* get current dialog */
-	dlg = get_current_dialog(msg);
+	dlg = dlg_get_msg_dialog(msg);
 
 	if (dlg==NULL)
 		return -1;
@@ -614,11 +574,11 @@ int is_dlg_in_profile(struct sip_msg *msg, struct dlg_profile_table *profile,
 		if (linker->profile==profile) {
 			if (profile->has_value==0) {
 				dlg_unlock( d_table, d_entry);
-				return 1;
+				goto done;
 			} else if (value && value->len==linker->hash_linker.value.len &&
 			memcmp(value->s,linker->hash_linker.value.s,value->len)==0){
 				dlg_unlock( d_table, d_entry);
-				return 1;
+				goto done;
 			}
 			/* allow further search - maybe the dialog is inserted twice in
 			 * the same profile, but with different values -bogdan
@@ -626,6 +586,9 @@ int is_dlg_in_profile(struct sip_msg *msg, struct dlg_profile_table *profile,
 		}
 	}
 	dlg_unlock( d_table, d_entry);
+
+done:
+	dlg_release(dlg);
 	return -1;
 }
 
@@ -676,9 +639,15 @@ unsigned int get_profile_size(struct dlg_profile_table *profile, str *value)
  * Determine if message is in a dialog currently being tracked
  */
 int	is_known_dlg(struct sip_msg *msg) {
-	if(get_current_dialog(msg) == NULL)
+	dlg_cell_t *dlg;
+
+	dlg = dlg_get_msg_dialog(msg);
+	
+	if(dlg == NULL)
 		return -1;
 
+	dlg_release(dlg);
+
 	return 1;
 }
 

+ 18 - 26
modules_k/dialog/dlg_profile.h

@@ -44,49 +44,41 @@
 
 
 /*! dialog profile hash list */
-struct dlg_profile_hash {
+typedef struct dlg_profile_hash {
 	str value; /*!< hash value */
 	struct dlg_cell *dlg; /*!< dialog cell */
 	struct dlg_profile_hash *next;
 	struct dlg_profile_hash *prev;
 	unsigned int hash; /*!< position in the hash table */
-};
+} dlg_profile_hash_t;
 
 
 /*! list with links to dialog profiles */
-struct dlg_profile_link {
+typedef struct dlg_profile_link {
 	struct dlg_profile_hash hash_linker;
 	struct dlg_profile_link  *next;
 	struct dlg_profile_table *profile;
-};
+} dlg_profile_link_t;
 
 
 /*! dialog profile entry */
-struct dlg_profile_entry {
+typedef struct dlg_profile_entry {
 	struct dlg_profile_hash *first;
 	unsigned int content; /*!< content of the entry */
-};
+} dlg_profile_entry_t;
 
 
 /*! dialog profile table */
-struct dlg_profile_table {
+typedef struct dlg_profile_table {
 	str name; /*!< name of the dialog profile */
 	unsigned int size; /*!< size of the dialog profile */
 	unsigned int has_value; /*!< 0 for profiles without value, otherwise it has a value */
 	gen_lock_t lock; /*! lock for concurrent access */
 	struct dlg_profile_entry *entries;
 	struct dlg_profile_table *next;
-};
+} dlg_profile_table_t;
 
 
-struct dlg_cell *get_current_dlg_pointer(void);
-
-void reset_current_dlg_pointer(void);
-
-struct dlg_cell* get_dialog_from_tm(struct cell *t);
-
-struct dlg_cell *get_current_dialog(struct sip_msg *msg);
-
 /*!
  * \brief Add profile definitions to the global list
  * \see new_dlg_profile
@@ -119,14 +111,14 @@ struct dlg_profile_table* search_dlg_profile(str *name);
  * \param param unused
  * \return 1
  */
-int profile_cleanup( struct sip_msg *msg, unsigned int flags, void *param );
+int profile_cleanup(sip_msg_t *msg, unsigned int flags, void *param );
 
 
 /*!
  * \brief Destroy dialog linkers
  * \param linker dialog linker
  */ 
-void destroy_linkers(struct dlg_profile_link *linker);
+void destroy_linkers(dlg_profile_link_t *linker);
 
 
 /*!
@@ -134,7 +126,7 @@ void destroy_linkers(struct dlg_profile_link *linker);
  * \param msg SIP message
  * \param dlg dialog cell
  */
-void set_current_dialog(struct sip_msg *msg, struct dlg_cell *dlg);
+void set_current_dialog(sip_msg_t *msg, struct dlg_cell *dlg);
 
 
 /*!
@@ -144,8 +136,8 @@ void set_current_dialog(struct sip_msg *msg, struct dlg_cell *dlg);
  * \param profile dialog profile table
  * \return 0 on success, -1 on failure
  */
-int set_dlg_profile(struct sip_msg *msg, str *value,
-		struct dlg_profile_table *profile);
+int set_dlg_profile(sip_msg_t *msg, str *value,
+		dlg_profile_table_t *profile);
 
 
 /*!
@@ -155,8 +147,8 @@ int set_dlg_profile(struct sip_msg *msg, str *value,
  * \param profile dialog profile table
  * \return 1 on success, -1 on failure
  */
-int unset_dlg_profile(struct sip_msg *msg, str *value,
-		struct dlg_profile_table *profile);
+int unset_dlg_profile(sip_msg_t *msg, str *value,
+		dlg_profile_table_t *profile);
 
 
 /*!
@@ -166,7 +158,7 @@ int unset_dlg_profile(struct sip_msg *msg, str *value,
  * \param value value
  * \return 1 on success, -1 on failure
  */
-int is_dlg_in_profile(struct sip_msg *msg, struct dlg_profile_table *profile,
+int is_dlg_in_profile(sip_msg_t *msg, dlg_profile_table_t *profile,
 		str *value);
 
 
@@ -176,7 +168,7 @@ int is_dlg_in_profile(struct sip_msg *msg, struct dlg_profile_table *profile,
  * \param value value
  * \return the profile size
  */
-unsigned int get_profile_size(struct dlg_profile_table *profile, str *value);
+unsigned int get_profile_size(dlg_profile_table_t *profile, str *value);
 
 
 /*!
@@ -199,6 +191,6 @@ struct mi_root * mi_profile_list(struct mi_root *cmd_tree, void *param );
 /*!
  * \brief return true if the messages belongs to a tracked dialog
  */
-int is_known_dlg(struct sip_msg *msg);
+int is_known_dlg(sip_msg_t *msg);
 
 #endif

+ 6 - 6
modules_k/dialog/dlg_req_within.c

@@ -179,7 +179,7 @@ void bye_reply_cb(struct cell* t, int type, struct tmcb_params* ps){
 
 		LM_DBG("first final reply\n");
 		/* derefering the dialog */
-		unref_dlg(dlg, unref+1);
+		dlg_unref(dlg, unref+1);
 
 		if_update_stat( dlg_enable_stats, active_dlgs, -1);
 	}
@@ -191,7 +191,7 @@ void bye_reply_cb(struct cell* t, int type, struct tmcb_params* ps){
 		if (dlg_db_mode)
 			remove_dialog_from_db(dlg);
 		/* force delete from mem */
-		unref_dlg(dlg, 1);
+		dlg_unref(dlg, 1);
 	}
 
 }
@@ -256,7 +256,7 @@ static inline int send_bye(struct dlg_cell * cell, int dir, str *hdrs)
 
 	LM_DBG("sending BYE to %s\n", (dir==DLG_CALLER_LEG)?"caller":"callee");
 
-	ref_dlg(cell, 1);
+	dlg_ref(cell, 1);
 
 	memset(&uac_r,'\0', sizeof(uac_req_t));
 	set_uac_req(&uac_r, &met, hdrs, NULL, dialog_info, TMCB_LOCAL_COMPLETED,
@@ -274,7 +274,7 @@ static inline int send_bye(struct dlg_cell * cell, int dir, str *hdrs)
 	return 0;
 
 err1:
-	unref_dlg(cell, 1);
+	dlg_unref(cell, 1);
 err:
 	if(dialog_info)
 		free_tm_dlg(dialog_info);
@@ -318,7 +318,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 = dlg_lookup(h_entry, h_id);
 
 	// lookup_dlg has incremented the reference count
 
@@ -333,7 +333,7 @@ struct mi_root * mi_terminate_dlg(struct mi_root *cmd_tree, void *param ){
 			msg_len = MI_OK_LEN;
 		}
 
-		unref_dlg(dlg, 1);
+		dlg_release(dlg);
 
 		return init_mi_tree(status, msg, msg_len);
 	}

+ 4 - 4
modules_k/dialog/dlg_timer.h

@@ -37,20 +37,20 @@
 
 
 /*! dialog timeout list */
-struct dlg_tl
+typedef struct dlg_tl
 {
 	struct dlg_tl     *next;
 	struct dlg_tl     *prev;
 	volatile unsigned int  timeout; /*!< timeout in seconds */
-};
+} dlg_tl_t;
 
 
 /*! dialog timer */
-struct dlg_timer
+typedef struct dlg_timer
 {
 	struct dlg_tl   first; /*!< dialog timeout list */
 	gen_lock_t      *lock; /*!< lock for the list */
-};
+} dlg_timer_t;
 
 
 /*! dialog timer handler */

+ 234 - 104
modules_k/dialog/dlg_var.c

@@ -22,10 +22,12 @@
  */
 		       
 #include "../../route.h"
+#include "../../pvapi.h"
 
 #include "dlg_var.h"
 #include "dlg_hash.h"
 #include "dlg_profile.h"
+#include "dlg_handlers.h"
 #include "dlg_db_handler.h"
 
 dlg_ctx_t _dlg_ctx;
@@ -268,16 +270,18 @@ done:
 
 int pv_get_dlg_variable(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
 {
-	struct dlg_cell *dlg;
+	dlg_cell_t *dlg;
 	str * value;
 
-	if (param==NULL || param->pvn.type!=PV_NAME_INTSTR || param->pvn.u.isname.type!=AVP_NAME_STR || param->pvn.u.isname.name.s.s==NULL) {
+	if (param==NULL || param->pvn.type!=PV_NAME_INTSTR
+			|| param->pvn.u.isname.type!=AVP_NAME_STR
+			|| param->pvn.u.isname.name.s.s==NULL) {
 		LM_CRIT("BUG - bad parameters\n");
 		return -1;
 	}
 
-	/* Retrieve the current dialog */
-	dlg=get_current_dialog( msg);
+	/* Retrieve the dialog for current message */
+	dlg=dlg_get_msg_dialog( msg);
 
 	if (dlg) {
 		/* Lock the dialog */
@@ -287,12 +291,16 @@ int pv_get_dlg_variable(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
 		get_local_varlist_pointer(msg, 0);
 	}
 
+	/* dcm: todo - the value should be cloned for safe usage */
 	value = get_dlg_variable_unsafe(dlg, &param->pvn.u.isname.name.s);
 
 	print_lists(dlg);
 
 	/* unlock dialog */
-	if (dlg) dlg_unlock(d_table, &(d_table->entries[dlg->h_entry]));
+	if (dlg) {
+		dlg_unlock(d_table, &(d_table->entries[dlg->h_entry]));
+		dlg_release(dlg);
+	}
 
 	if (value)
 		return pv_get_strval(msg, param, res, value);
@@ -303,11 +311,18 @@ int pv_get_dlg_variable(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
 
 int pv_set_dlg_variable(struct sip_msg* msg, pv_param_t *param, int op, pv_value_t *val)
 {
-	struct dlg_cell *dlg;
+	dlg_cell_t *dlg = NULL;
 	int ret = -1;
 
-	/* Retrieve the current dialog */
-	dlg=get_current_dialog( msg);
+	if (param==NULL || param->pvn.type!=PV_NAME_INTSTR
+			|| param->pvn.u.isname.type!=AVP_NAME_STR
+			|| param->pvn.u.isname.name.s.s==NULL ) {
+		LM_CRIT("BUG - bad parameters\n");
+		goto error;
+	}
+
+	/* Retrieve the dialog for current message */
+	dlg=dlg_get_msg_dialog( msg);
 	
 	if (dlg) {
 		/* Lock the dialog */
@@ -317,17 +332,15 @@ int pv_set_dlg_variable(struct sip_msg* msg, pv_param_t *param, int op, pv_value
 		get_local_varlist_pointer(msg, 0);
 	}
 
-	if (param==NULL || param->pvn.type!=PV_NAME_INTSTR || param->pvn.u.isname.type!=AVP_NAME_STR || param->pvn.u.isname.name.s.s==NULL ) {
-		LM_CRIT("BUG - bad parameters\n");
-		return -1;
-	}
-
 	if (val==NULL || val->flags&(PV_VAL_NONE|PV_VAL_NULL|PV_VAL_EMPTY)) {
 		/* if NULL, remove the value */
 		ret = set_dlg_variable_unsafe(dlg, &param->pvn.u.isname.name.s, NULL);
 		if(ret!= 0) {
 			/* unlock dialog */
-			if (dlg) dlg_unlock(d_table, &(d_table->entries[dlg->h_entry]));
+			if (dlg) {
+				dlg_unlock(d_table, &(d_table->entries[dlg->h_entry]));
+				dlg_release(dlg);
+			}
 			return ret;
 		}
 	} else {
@@ -336,14 +349,14 @@ int pv_set_dlg_variable(struct sip_msg* msg, pv_param_t *param, int op, pv_value
 			LM_ERR("non-string values are not supported\n");
 			/* unlock dialog */
 			if (dlg) dlg_unlock(d_table, &(d_table->entries[dlg->h_entry]));
-			return -1;
+			goto error;
 		}
 
 		ret = set_dlg_variable_unsafe(dlg, &param->pvn.u.isname.name.s, &val->rs);
 		if(ret!= 0) {
 			/* unlock dialog */
 			if (dlg) dlg_unlock(d_table, &(d_table->entries[dlg->h_entry]));
-			return -1;
+			goto error;
 		}
 	}
 	/* unlock dialog */
@@ -356,7 +369,11 @@ int pv_set_dlg_variable(struct sip_msg* msg, pv_param_t *param, int op, pv_value
 	}
 	print_lists(dlg);
 
+	dlg_release(dlg);
 	return 0;
+error:
+	dlg_release(dlg);
+	return -1;
 }
 
 int pv_get_dlg_ctx(struct sip_msg *msg,  pv_param_t *param,
@@ -379,7 +396,7 @@ int pv_get_dlg_ctx(struct sip_msg *msg,  pv_param_t *param,
 			return pv_get_uintval(msg, param, res,
 					(unsigned int)_dlg_ctx.to_route);
 		case 5:
-			_dlg_ctx.set = (_dlg_ctx.dlg==NULL)?0:1;
+			_dlg_ctx.set = (_dlg_ctx.iuid.h_id==0)?0:1;
 			return pv_get_uintval(msg, param, res,
 					(unsigned int)_dlg_ctx.set);
 		case 6:
@@ -495,117 +512,223 @@ error:
 int pv_get_dlg(struct sip_msg *msg, pv_param_t *param,
 		pv_value_t *res)
 {
+	dlg_cell_t *dlg = NULL;
+	int res_type = 0;
+	str sv = { 0 };
+	unsigned int ui = 0;
+
 	if(param==NULL)
 		return -1;
-	if(_dlg_ctx.dlg == NULL)
+
+	/* Retrieve the dialog for current message */
+	dlg=dlg_get_msg_dialog( msg);
+	if(dlg == NULL)
 		return pv_get_null(msg, param, res);
+
 	switch(param->pvn.u.isname.name.n)
 	{
 		case 1:
-			return pv_get_uintval(msg, param, res,
-					(unsigned int)_dlg_ctx.dlg->h_id);
+			res_type = 1;
+			ui = (unsigned int)dlg->h_id;
+			break;
 		case 2:
-			return pv_get_uintval(msg, param, res,
-					(unsigned int)_dlg_ctx.dlg->state);
+			res_type = 1;
+			ui = (unsigned int)dlg->state;
+			break;
 		case 3:
-			if(_dlg_ctx.dlg->route_set[DLG_CALLEE_LEG].s==NULL
-					|| _dlg_ctx.dlg->route_set[DLG_CALLEE_LEG].len<=0)
-				return pv_get_null(msg, param, res);
-			return pv_get_strval(msg, param, res,
-					&_dlg_ctx.dlg->route_set[DLG_CALLEE_LEG]);
+			if(dlg->route_set[DLG_CALLEE_LEG].s==NULL
+					|| dlg->route_set[DLG_CALLEE_LEG].len<=0)
+				goto done;
+			sv.s = pv_get_buffer();
+			sv.len = dlg->route_set[DLG_CALLEE_LEG].len;
+			if(pv_get_buffer_size()<sv.len)
+				goto done;
+			res_type = 2;
+			strncpy(sv.s, dlg->route_set[DLG_CALLEE_LEG].s, sv.len);
+			sv.s[sv.len] = '\0';
+			break;
 		case 4:
-			return pv_get_uintval(msg, param, res,
-					(unsigned int)_dlg_ctx.dlg->dflags);
+			res_type = 1;
+			ui = (unsigned int)dlg->dflags;
+			break;
 		case 5:
-			return pv_get_uintval(msg, param, res,
-					(unsigned int)_dlg_ctx.dlg->sflags);
+			res_type = 1;
+			ui = (unsigned int)dlg->sflags;
+			break;
 		case 6:
-			if(_dlg_ctx.dlg->callid.s==NULL
-					|| _dlg_ctx.dlg->callid.len<=0)
-				return pv_get_null(msg, param, res);
-			return pv_get_strval(msg, param, res,
-					&_dlg_ctx.dlg->callid);
+			if(dlg->callid.s==NULL
+					|| dlg->callid.len<=0)
+				goto done;
+			sv.s = pv_get_buffer();
+			sv.len = dlg->callid.len;
+			if(pv_get_buffer_size()<sv.len)
+				goto done;
+			res_type = 2;
+			strncpy(sv.s, dlg->callid.s, sv.len);
+			sv.s[sv.len] = '\0';
+			break;
 		case 7:
-			if(_dlg_ctx.dlg->to_uri.s==NULL
-					|| _dlg_ctx.dlg->to_uri.len<=0)
-				return pv_get_null(msg, param, res);
-			return pv_get_strval(msg, param, res,
-					&_dlg_ctx.dlg->to_uri);
+			if(dlg->to_uri.s==NULL
+					|| dlg->to_uri.len<=0)
+				goto done;
+			sv.s = pv_get_buffer();
+			sv.len = dlg->to_uri.len;
+			if(pv_get_buffer_size()<sv.len)
+				goto done;
+			res_type = 2;
+			strncpy(sv.s, dlg->to_uri.s, sv.len);
+			sv.s[sv.len] = '\0';
+			break;
 		case 8:
-			if(_dlg_ctx.dlg->tag[DLG_CALLEE_LEG].s==NULL
-					|| _dlg_ctx.dlg->tag[DLG_CALLEE_LEG].len<=0)
-				return pv_get_null(msg, param, res);
-			return pv_get_strval(msg, param, res,
-					&_dlg_ctx.dlg->tag[DLG_CALLEE_LEG]);
+			if(dlg->tag[DLG_CALLEE_LEG].s==NULL
+					|| dlg->tag[DLG_CALLEE_LEG].len<=0)
+				goto done;
+			sv.s = pv_get_buffer();
+			sv.len = dlg->tag[DLG_CALLEE_LEG].len;
+			if(pv_get_buffer_size()<sv.len)
+				goto done;
+			res_type = 2;
+			strncpy(sv.s, dlg->tag[DLG_CALLEE_LEG].s, sv.len);
+			sv.s[sv.len] = '\0';
+			break;
 		case 9:
-			return pv_get_uintval(msg, param, res,
-					(unsigned int)_dlg_ctx.dlg->toroute);
+			res_type = 1;
+			ui = (unsigned int)dlg->toroute;
+			break;
 		case 10:
-			if(_dlg_ctx.dlg->cseq[DLG_CALLEE_LEG].s==NULL
-					|| _dlg_ctx.dlg->cseq[DLG_CALLEE_LEG].len<=0)
-				return pv_get_null(msg, param, res);
-			return pv_get_strval(msg, param, res,
-					&_dlg_ctx.dlg->cseq[DLG_CALLEE_LEG]);
+			if(dlg->cseq[DLG_CALLEE_LEG].s==NULL
+					|| dlg->cseq[DLG_CALLEE_LEG].len<=0)
+				goto done;
+			sv.s = pv_get_buffer();
+			sv.len = dlg->cseq[DLG_CALLEE_LEG].len;
+			if(pv_get_buffer_size()<sv.len)
+				goto done;
+			res_type = 2;
+			strncpy(sv.s, dlg->cseq[DLG_CALLEE_LEG].s, sv.len);
+			sv.s[sv.len] = '\0';
+			break;
 		case 11:
-			if(_dlg_ctx.dlg->route_set[DLG_CALLER_LEG].s==NULL
-					|| _dlg_ctx.dlg->route_set[DLG_CALLER_LEG].len<=0)
-				return pv_get_null(msg, param, res);
-			return pv_get_strval(msg, param, res,
-					&_dlg_ctx.dlg->route_set[DLG_CALLER_LEG]);
+			if(dlg->route_set[DLG_CALLER_LEG].s==NULL
+					|| dlg->route_set[DLG_CALLER_LEG].len<=0)
+				goto done;
+			sv.s = pv_get_buffer();
+			sv.len = dlg->route_set[DLG_CALLER_LEG].len;
+			if(pv_get_buffer_size()<sv.len)
+				goto done;
+			res_type = 2;
+			strncpy(sv.s, dlg->route_set[DLG_CALLER_LEG].s, sv.len);
+			sv.s[sv.len] = '\0';
+			break;
 		case 12:
-			if(_dlg_ctx.dlg->from_uri.s==NULL
-					|| _dlg_ctx.dlg->from_uri.len<=0)
-				return pv_get_null(msg, param, res);
-			return pv_get_strval(msg, param, res,
-					&_dlg_ctx.dlg->from_uri);
+			if(dlg->from_uri.s==NULL
+					|| dlg->from_uri.len<=0)
+				goto done;
+			sv.s = pv_get_buffer();
+			sv.len = dlg->from_uri.len;
+			if(pv_get_buffer_size()<sv.len)
+				goto done;
+			res_type = 2;
+			strncpy(sv.s, dlg->from_uri.s, sv.len);
+			sv.s[sv.len] = '\0';
+			break;
 		case 13:
-			if(_dlg_ctx.dlg->tag[DLG_CALLER_LEG].s==NULL
-					|| _dlg_ctx.dlg->tag[DLG_CALLER_LEG].len<=0)
-				return pv_get_null(msg, param, res);
-			return pv_get_strval(msg, param, res,
-					&_dlg_ctx.dlg->tag[DLG_CALLER_LEG]);
+			if(dlg->tag[DLG_CALLER_LEG].s==NULL
+					|| dlg->tag[DLG_CALLER_LEG].len<=0)
+				goto done;
+			sv.s = pv_get_buffer();
+			sv.len = dlg->tag[DLG_CALLER_LEG].len;
+			if(pv_get_buffer_size()<sv.len)
+				goto done;
+			res_type = 2;
+			strncpy(sv.s, dlg->tag[DLG_CALLER_LEG].s, sv.len);
+			sv.s[sv.len] = '\0';
+			break;
 		case 14:
-			return pv_get_uintval(msg, param, res,
-					(unsigned int)_dlg_ctx.dlg->lifetime);
+			res_type = 1;
+			ui = (unsigned int)dlg->lifetime;
+			break;
 		case 15:
-			return pv_get_uintval(msg, param, res,
-					(unsigned int)_dlg_ctx.dlg->start_ts);
+			res_type = 1;
+			ui = (unsigned int)dlg->start_ts;
+			break;
 		case 16:
-			if(_dlg_ctx.dlg->cseq[DLG_CALLER_LEG].s==NULL
-					|| _dlg_ctx.dlg->cseq[DLG_CALLER_LEG].len<=0)
-				return pv_get_null(msg, param, res);
-			return pv_get_strval(msg, param, res,
-					&_dlg_ctx.dlg->cseq[DLG_CALLER_LEG]);
+			if(dlg->cseq[DLG_CALLER_LEG].s==NULL
+					|| dlg->cseq[DLG_CALLER_LEG].len<=0)
+				goto done;
+			sv.s = pv_get_buffer();
+			sv.len = dlg->cseq[DLG_CALLER_LEG].len;
+			if(pv_get_buffer_size()<sv.len)
+				goto done;
+			res_type = 2;
+			strncpy(sv.s, dlg->cseq[DLG_CALLER_LEG].s, sv.len);
+			sv.s[sv.len] = '\0';
+			break;
 		case 17:
-			if(_dlg_ctx.dlg->contact[DLG_CALLEE_LEG].s==NULL
-					|| _dlg_ctx.dlg->contact[DLG_CALLEE_LEG].len<=0)
-				return pv_get_null(msg, param, res);
-			return pv_get_strval(msg, param, res,
-					&_dlg_ctx.dlg->contact[DLG_CALLEE_LEG]);
+			if(dlg->contact[DLG_CALLEE_LEG].s==NULL
+					|| dlg->contact[DLG_CALLEE_LEG].len<=0)
+				goto done;
+			sv.s = pv_get_buffer();
+			sv.len = dlg->contact[DLG_CALLEE_LEG].len;
+			if(pv_get_buffer_size()<sv.len)
+				goto done;
+			res_type = 2;
+			strncpy(sv.s, dlg->contact[DLG_CALLEE_LEG].s, sv.len);
+			sv.s[sv.len] = '\0';
+			break;
 		case 18:
-			if(_dlg_ctx.dlg->bind_addr[DLG_CALLEE_LEG]==NULL)
-				return pv_get_null(msg, param, res);
-			return pv_get_strval(msg, param, res,
-					&_dlg_ctx.dlg->bind_addr[DLG_CALLEE_LEG]->sock_str);
+			if(dlg->bind_addr[DLG_CALLEE_LEG]==NULL)
+				goto done;
+			sv.s = pv_get_buffer();
+			sv.len = dlg->bind_addr[DLG_CALLEE_LEG]->sock_str.len;
+			if(pv_get_buffer_size()<sv.len)
+				goto done;
+			res_type = 2;
+			strncpy(sv.s, dlg->bind_addr[DLG_CALLEE_LEG]->sock_str.s, sv.len);
+			sv.s[sv.len] = '\0';
+			break;
 		case 19:
-			if(_dlg_ctx.dlg->contact[DLG_CALLER_LEG].s==NULL
-					|| _dlg_ctx.dlg->contact[DLG_CALLER_LEG].len<=0)
-				return pv_get_null(msg, param, res);
-			return pv_get_strval(msg, param, res,
-					&_dlg_ctx.dlg->contact[DLG_CALLER_LEG]);
+			if(dlg->contact[DLG_CALLER_LEG].s==NULL
+					|| dlg->contact[DLG_CALLER_LEG].len<=0)
+				goto done;
+			sv.s = pv_get_buffer();
+			sv.len = dlg->contact[DLG_CALLER_LEG].len;
+			if(pv_get_buffer_size()<sv.len)
+				goto done;
+			res_type = 2;
+			strncpy(sv.s, dlg->contact[DLG_CALLER_LEG].s, sv.len);
+			sv.s[sv.len] = '\0';
+			break;
 		case 20:
-			if(_dlg_ctx.dlg->bind_addr[DLG_CALLER_LEG]==NULL)
-				return pv_get_null(msg, param, res);
-			return pv_get_strval(msg, param, res,
-					&_dlg_ctx.dlg->bind_addr[DLG_CALLER_LEG]->sock_str);
+			if(dlg->bind_addr[DLG_CALLER_LEG]==NULL)
+				goto done;
+			sv.s = pv_get_buffer();
+			sv.len = dlg->bind_addr[DLG_CALLER_LEG]->sock_str.len;
+			if(pv_get_buffer_size()<sv.len)
+				goto done;
+			res_type = 2;
+			strncpy(sv.s, dlg->bind_addr[DLG_CALLER_LEG]->sock_str.s, sv.len);
+			sv.s[sv.len] = '\0';
+			break;
 		case 21:
-			return pv_get_uintval(msg, param, res,
-					(unsigned int)_dlg_ctx.dlg->h_entry);
+			res_type = 1;
+			ui = (unsigned int)dlg->h_entry;
+			break;
 		default:
-			return pv_get_uintval(msg, param, res,
-					(unsigned int)_dlg_ctx.dlg->ref);
+			res_type = 1;
+			ui = (unsigned int)dlg->ref;
+	}
+
+done:
+	dlg_release(dlg);
+
+	switch(res_type) {
+		case 1:
+			return pv_get_uintval(msg, param, res, ui);
+		case 2:
+			return pv_get_strval(msg, param, res, &sv);
+		default:
+			return pv_get_null(msg, param, res);
 	}
-	return 0;
 }
 
 int pv_parse_dlg_name(pv_spec_p sp, str *in)
@@ -705,14 +828,21 @@ error:
 	return -1;
 }
 
-void dlg_set_ctx_dialog(struct dlg_cell *dlg)
+void dlg_set_ctx_iuid(dlg_cell_t *dlg)
+{
+	_dlg_ctx.iuid.h_entry = dlg->h_entry;
+	_dlg_ctx.iuid.h_id = dlg->h_id;
+}
+
+void dlg_reset_ctx_iuid(void)
 {
-	_dlg_ctx.dlg = dlg;
+	_dlg_ctx.iuid.h_entry = 0;
+	_dlg_ctx.iuid.h_id = 0;
 }
 
-struct dlg_cell* dlg_get_ctx_dialog(void)
+dlg_cell_t* dlg_get_ctx_dialog(void)
 {
-	return _dlg_ctx.dlg;
+	return dlg_get_by_iuid(&_dlg_ctx.iuid);
 }
 
 dlg_ctx_t* dlg_get_dlg_ctx(void)

+ 18 - 16
modules_k/dialog/dlg_var.h

@@ -36,53 +36,55 @@ typedef struct _dlg_ctx {
 	char to_route_name[DLG_TOROUTE_SIZE];
 	int to_bye;
 	int timeout;
-	struct dlg_cell *dlg;
+	dlg_cell_t *dlg1;
+	dlg_iuid_t iuid;
 	int set;
 	unsigned int dir;
 } dlg_ctx_t;
 
 /* A dialog-variable */
-struct dlg_var {
+typedef struct dlg_var {
 	str key;
 	str value;
 	unsigned int vflags;		/*!< internal variable flags */
 	struct dlg_var *next;
-};
+} dlg_var_t;
 
-str * get_dlg_variable(struct dlg_cell *dlg, str *key);
-int set_dlg_variable(struct dlg_cell *dlg, str *key, str *val);
+str* get_dlg_variable(dlg_cell_t *dlg, str *key);
+int set_dlg_variable(dlg_cell_t *dlg, str *key, str *val);
 
 int pv_parse_dialog_var_name(pv_spec_p sp, str *in);
 
-int pv_get_dlg_variable(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
+int pv_get_dlg_variable(sip_msg_t *msg, pv_param_t *param, pv_value_t *res);
 
-int pv_set_dlg_variable(struct sip_msg* msg, pv_param_t *param, int op, pv_value_t *val);
+int pv_set_dlg_variable(sip_msg_t *msg, pv_param_t *param, int op, pv_value_t *val);
 
 /*! Retrieve the current var-list */
-struct dlg_var * get_local_varlist_pointer(struct sip_msg *msg, int clear_pointer);
+dlg_var_t *get_local_varlist_pointer(sip_msg_t *msg, int clear_pointer);
 
 /* Adds, updates and deletes dialog variables */
-int set_dlg_variable_unsafe(struct dlg_cell *dlg, str *key, str *val);
+int set_dlg_variable_unsafe(dlg_cell_t *dlg, str *key, str *val);
 
 extern dlg_ctx_t _dlg_ctx;
 
-int pv_get_dlg_ctx(struct sip_msg *msg,  pv_param_t *param,
+int pv_get_dlg_ctx(sip_msg_t *msg,  pv_param_t *param,
 		pv_value_t *res);
-int pv_set_dlg_ctx(struct sip_msg* msg, pv_param_t *param,
+int pv_set_dlg_ctx(sip_msg_t *msg, pv_param_t *param,
 		int op, pv_value_t *val);
 int pv_parse_dlg_ctx_name(pv_spec_p sp, str *in);
 
-int pv_get_dlg(struct sip_msg *msg,  pv_param_t *param,
+int pv_get_dlg(sip_msg_t *msg,  pv_param_t *param,
 		pv_value_t *res);
 int pv_parse_dlg_name(pv_spec_p sp, str *in);
 
-int dlg_cfg_cb(struct sip_msg *foo, unsigned int flags, void *bar);
+int dlg_cfg_cb(sip_msg_t *foo, unsigned int flags, void *bar);
 
-void dlg_set_ctx_dialog(struct dlg_cell *dlg);
-struct dlg_cell* dlg_get_ctx_dialog(void);
+void dlg_set_ctx_iuid(dlg_cell_t *dlg);
+void dlg_reset_ctx_iuid(void);
+dlg_cell_t* dlg_get_ctx_dialog(void);
 
 dlg_ctx_t* dlg_get_dlg_ctx(void);
 
-int spiral_detect_reset(struct sip_msg *foo, unsigned int flags, void *bar);
+int spiral_detect_reset(sip_msg_t *foo, unsigned int flags, void *bar);
 
 #endif