瀏覽代碼

modules_k/dialog: Allow configuration of when initial dialog
callbacks are executed (either in-script or post-script).

- Implement functionality.
- Add documentation.

Timo Reimann 14 年之前
父節點
當前提交
48b8190c3f

+ 13 - 1
modules_k/dialog/dialog.c

@@ -104,6 +104,7 @@ static char* profiles_wv_s = NULL;
 static char* profiles_nv_s = NULL;
 str dlg_extra_hdrs = {NULL,0};
 static int db_fetch_rows = 200;
+int initial_cbs_inscript = 1;
 
 str dlg_bridge_controller = {"sip:[email protected]", 27};
 
@@ -241,6 +242,7 @@ static param_export_t mod_params[]={
 	{ "profiles_no_value",     STR_PARAM, &profiles_nv_s            },
 	{ "bridge_controller",     STR_PARAM, &dlg_bridge_controller.s  },
 	{ "ruri_pvar",             STR_PARAM, &ruri_pvar_param.s        },
+	{ "initial_cbs_inscript",  INT_PARAM, &initial_cbs_inscript     },
 	{ 0,0,0 }
 };
 
@@ -503,6 +505,11 @@ static int mod_init(void)
 		return -1;
 	}
 
+	if (initial_cbs_inscript != 0 && initial_cbs_inscript != 1) {
+		LM_ERR("invalid parameter for running initial callbacks in-script (must be either 0 or 1)\n");
+		return -1;
+	}
+
 	/* update the len of the extra headers */
 	if (dlg_extra_hdrs.s)
 		dlg_extra_hdrs.len = strlen(dlg_extra_hdrs.s);
@@ -575,6 +582,11 @@ static int mod_init(void)
 		return -1;
 	}
 
+	if (register_script_cb( spiral_detect_reset, POST_SCRIPT_CB|REQUEST_CB,0)<0) {
+		LM_ERR("cannot register req pre-script spiral detection reset callback\n");
+		return -1;
+	}
+
 	if ( register_timer( dlg_timer_routine, 0, 1)<0 ) {
 		LM_ERR("failed to register timer \n");
 		return -1;
@@ -902,7 +914,7 @@ static int w_dlg_manage(struct sip_msg *msg, char *s1, char *s2)
 		dlg_onroute(msg, NULL, NULL);
 		seq_match_mode = backup_mode;
 	} else {
-		if(dlg_new_dialog(msg, 0)!=0)
+		if(dlg_new_dialog(msg, 0, initial_cbs_inscript)!=0)
 			return -1;
 	}
 	return 1;

+ 18 - 5
modules_k/dialog/dlg_handlers.c

@@ -83,6 +83,8 @@ static int       default_timeout;	/*!< default dialog timeout */
 static int       seq_match_mode;	/*!< dlg_match mode */ 
 static int       shutdown_done = 0;	/*!< 1 when destroy_dlg_handlers was called */
 extern int       detect_spirals;
+extern int       initial_cbs_inscript;
+int              spiral_detected = -1;
 
 extern struct rr_binds d_rrb;		/*!< binding to record-routing module */
 
@@ -609,11 +611,17 @@ void dlg_onreq(struct cell* t, int type, struct tmcb_params *param)
 {
 	struct sip_msg *req = param->req;
 
+	if (!initial_cbs_inscript) {
+		if (spiral_detected == 1)
+			run_dlg_callbacks( DLGCB_SPIRALED, current_dlg_pointer, req, NULL, DLG_DIR_DOWNSTREAM, 0);
+		else if (spiral_detected == 0)
+			run_create_callbacks( current_dlg_pointer, req);
+	}
 	if((req->flags&dlg_flag)!=dlg_flag)
 		return;
 	if (current_dlg_pointer!=NULL)
 		return;
-	dlg_new_dialog(req, t);
+	dlg_new_dialog(req, t, 1);
 }
 
 
@@ -754,7 +762,7 @@ static void store_dlg_in_tm_cb (struct cell* t,
  * \param t transaction
  * \return 0 on success, -1 on failure
  */ 
-int dlg_new_dialog(struct sip_msg *req, struct cell *t)
+int dlg_new_dialog(struct sip_msg *req, struct cell *t, const int run_initial_cbs)
 {
 	struct dlg_cell *dlg;
 	str s;
@@ -787,6 +795,9 @@ int dlg_new_dialog(struct sip_msg *req, struct cell *t)
 
     if (detect_spirals)
     {
+        if (spiral_detected == 1)
+            return 0;
+
         dir = DLG_DIR_NONE;
 
         dlg = get_dlg(&callid, &ftag, &ttag, &dir, &del);
@@ -801,14 +812,16 @@ int dlg_new_dialog(struct sip_msg *req, struct cell *t)
         {
             LM_DBG("Callid '%.*s' found, must be a spiraled request\n",
                 callid.len, callid.s);
+            spiral_detected = 1;
 
-            run_dlg_callbacks( DLGCB_SPIRALED, dlg, req, NULL, DLG_DIR_DOWNSTREAM, 0);
-
+            if (run_initial_cbs)
+                run_dlg_callbacks( DLGCB_SPIRALED, dlg, req, NULL, DLG_DIR_DOWNSTREAM, 0);
             // get_dlg with del==0 has incremented the ref count by 1
             unref_dlg(dlg, 1);
             goto finish;
         }
     }
+    spiral_detected = 0;
 
     dlg = build_new_dlg (&callid /*callid*/,
                          &(get_from(req)->uri) /*from uri*/,
@@ -837,7 +850,7 @@ int dlg_new_dialog(struct sip_msg *req, struct cell *t)
 
 	link_dlg(dlg,0);
 
-    run_create_callbacks(dlg, req);
+    if (run_initial_cbs)  run_create_callbacks( dlg, req);
 
 	/* first INVITE seen (dialog created, unconfirmed) */
 	if ( seq_match_mode!=SEQ_MATCH_NO_ID &&

+ 1 - 1
modules_k/dialog/dlg_handlers.h

@@ -128,7 +128,7 @@ void dlg_ontimeout( struct dlg_tl *tl);
  * \param t transaction
  * \return 0 on success, -1 on failure
  */ 
-int dlg_new_dialog(struct sip_msg *msg, struct cell *t);
+int dlg_new_dialog(struct sip_msg *msg, struct cell *t, const int run_initial_cbs);
 
 
 /*!

+ 8 - 0
modules_k/dialog/dlg_var.c

@@ -29,6 +29,7 @@
 #include "dlg_db_handler.h"
 
 dlg_ctx_t _dlg_ctx;
+extern int spiral_detected;
 
 /*! global variable table, in case the dialog does not exist yet */
 struct dlg_var * var_table = 0;
@@ -721,3 +722,10 @@ dlg_ctx_t* dlg_get_dlg_ctx(void)
 {
 	return &_dlg_ctx;
 }
+
+int spiral_detect_reset(struct sip_msg *foo, unsigned int flags, void *bar)
+{
+	spiral_detected = -1;
+
+	return 0;
+}

+ 2 - 0
modules_k/dialog/dlg_var.h

@@ -83,4 +83,6 @@ struct dlg_cell* 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);
+
 #endif

+ 40 - 0
modules_k/dialog/doc/dialog_admin.xml

@@ -1054,6 +1054,46 @@ modparam("dialog", "bridge_controller", "sip:[email protected]")
 		</example>
 	</section>
 
+	<section>
+		<title><varname>initial_cbs_inscript</varname> (string)</title>
+		<para>
+            If the initial dialog callbacks (i.e., DLGCB_CREATED and
+            DLGCB_SPIRALED) should be executed in-script or post-script.
+            If dlg_manage() is not used, the setting of this parameter does
+            not matter; otherwise, initial callbacks will be executed
+            directly after dlg_manage() is called if this parameter is
+            enabled. If it is disabled, initial callback execution will be
+            postponed until configuration script execution completes.
+		</para>
+		<para>
+		The supported values are:
+		</para>
+		<itemizedlist>
+			<listitem><para>
+				<emphasis>0 - POST-SCRIPT</emphasis> - execute initial
+				callbacks after the script completes;
+			</para></listitem>
+			<listitem><para>
+				<emphasis>1 - IN-SCRIPT</emphasis> - execute initial
+                callbacks during script execution, i.e., right after
+                dlg_manage() is called;
+			</para></listitem>
+		</itemizedlist>
+		<para>
+		<emphasis>
+			Default value is <quote>1</quote>.
+		</emphasis>
+		</para>
+		<example>
+		<title>Set <varname>initial_cbs_inscript</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("dialog", "initial_cbs_inscript", "0")
+...
+</programlisting>
+		</example>
+	</section>
+
 	</section>