Module: sip-router Branch: master Commit: 48b8190c3fa1e42ed153f92d96e0fb7839712557 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=48b8190c...
Author: Timo Reimann timo.reimann@1und1.de Committer: Timo Reimann timo.reimann@1und1.de Date: Tue Aug 2 20:14:52 2011 +0200
modules_k/dialog: Allow configuration of when initial dialog callbacks are executed (either in-script or post-script).
- Implement functionality. - Add documentation.
---
modules_k/dialog/dialog.c | 14 ++++++++++- modules_k/dialog/dlg_handlers.c | 23 ++++++++++++++---- modules_k/dialog/dlg_handlers.h | 2 +- modules_k/dialog/dlg_var.c | 8 ++++++ modules_k/dialog/dlg_var.h | 2 + modules_k/dialog/doc/dialog_admin.xml | 40 +++++++++++++++++++++++++++++++++ 6 files changed, 82 insertions(+), 7 deletions(-)
diff --git a/modules_k/dialog/dialog.c b/modules_k/dialog/dialog.c index 5e751ac..7f029d8 100644 --- a/modules_k/dialog/dialog.c +++ b/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:controller@kamailio.org", 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; diff --git a/modules_k/dialog/dlg_handlers.c b/modules_k/dialog/dlg_handlers.c index a701fee..450fd09 100644 --- a/modules_k/dialog/dlg_handlers.c +++ b/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 && diff --git a/modules_k/dialog/dlg_handlers.h b/modules_k/dialog/dlg_handlers.h index d56b7fb..eef5a8f 100644 --- a/modules_k/dialog/dlg_handlers.h +++ b/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);
/*! diff --git a/modules_k/dialog/dlg_var.c b/modules_k/dialog/dlg_var.c index 42a7e91..6483233 100644 --- a/modules_k/dialog/dlg_var.c +++ b/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; +} diff --git a/modules_k/dialog/dlg_var.h b/modules_k/dialog/dlg_var.h index 99ab746..cd53807 100644 --- a/modules_k/dialog/dlg_var.h +++ b/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 diff --git a/modules_k/dialog/doc/dialog_admin.xml b/modules_k/dialog/doc/dialog_admin.xml index 34ac2ac..ae6c95d 100644 --- a/modules_k/dialog/doc/dialog_admin.xml +++ b/modules_k/dialog/doc/dialog_admin.xml @@ -1054,6 +1054,46 @@ modparam("dialog", "bridge_controller", "sip:ctd@kamailio.org") </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>