Skip to content

Commit

Permalink
uac: bug fix for uac module uac_replace* functions, register callback…
Browse files Browse the repository at this point in the history
…s after start

- bug fix for uac module uac_replace* functions, register callbacks after restart
- only applies to the dialog tracking mode of the module
- the uac module was not using the available dialog callbacks for a proxy (re-)start
- because of this the uac module was not able to properly re-write in-dialog messages
  like BYEs after a proxy restart
- As we don't have access to the uac_flag at the dialog on load callback, we just
  install a callback for both from and to rewriting cases. If only one of the
  functions is used in the cfg hen the uac module will obviously not find
  database variables for the other case, and will log an error. This is of
  course also a bit inefficient, but as it only applies to this (re-)start
  case it does not matter.

(cherry picked from commit aa7dee1)
  • Loading branch information
henningw committed Apr 16, 2019
1 parent 26fbc04 commit a829305
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 4 deletions.
75 changes: 74 additions & 1 deletion src/modules/uac/replace.c
Expand Up @@ -55,7 +55,7 @@ extern int_str restore_from_avp_name;
extern unsigned short restore_to_avp_type;
extern int_str restore_to_avp_name;

extern struct dlg_binds dlg_api;
struct dlg_binds dlg_api;
static str from_dlgvar[] = {str_init("_uac_fu"), str_init("_uac_funew"), str_init("_uac_fdp"), str_init("_uac_fdpnew")};
static str to_dlgvar[] = {str_init("_uac_to"), str_init("_uac_tonew"), str_init("_uac_tdp"), str_init("_uac_tdpnew")};

Expand Down Expand Up @@ -1006,3 +1006,76 @@ static void replace_callback(struct dlg_cell *dlg, int type,
free:
pkg_free(p);
}


/* helper function to avoid code duplication */
static inline int uac_load_callback_helper(struct dlg_cell* dialog, unsigned int uac_flag) {

if( dlg_api.register_dlgcb(dialog, DLGCB_REQ_WITHIN,
(void*)(unsigned long)replace_callback, (void*)(unsigned long)uac_flag, 0) != 0) {
LM_ERR("can't register create dialog REQ_WITHIN callback\n");
return -1;
}

if( dlg_api.register_dlgcb(dialog, DLGCB_CONFIRMED,
(void*)(unsigned long)replace_callback, (void*)(unsigned long)uac_flag, 0) != 0) {
LM_ERR("can't register create dialog CONFIRM callback\n");
return -1;
}

if( dlg_api.register_dlgcb(dialog, DLGCB_TERMINATED,
(void*)(unsigned long)replace_callback, (void*)(unsigned long)uac_flag, 0) != 0) {
LM_ERR("can't register create dialog TERMINATED callback\n");
return -1;
}
return 0;
}


/* callback for loading a dialog from database */
static void uac_on_load_callback(struct dlg_cell* dialog, int type, struct dlg_cb_params* params) {

if(!dialog) {
LM_ERR("invalid values\n!");
return;
}

/* Note:
* We don't have a way to access the real uac flags from the uac_replace_*
* method call at this point in time anymore. Therefore we just install a
* callback for both FROM and TO replace cases. This might be a bit
* inefficient in cases where only one of the functions is used. But as
* this applies only e.g. to a proxy restart with runnning dialogs, it
* does not matter. The replace_callback function will just not find a
* an entry in the dialog variables table and log an error.
*/
if(uac_load_callback_helper(dialog, FL_USE_UAC_FROM) != 0) {
LM_ERR("can't register create callbacks for UAC FROM\n");
return;
}
if(uac_load_callback_helper(dialog, FL_USE_UAC_TO) != 0) {
LM_ERR("can't register create callbacks for UAC TO\n");
return;
}

LM_DBG("dialog '%p' loaded and callbacks registered\n", dialog);
}


/* initialization of all necessary callbacks to track a dialog */
int uac_init_dlg(void) {

memset(&dlg_api, 0, sizeof(struct dlg_binds));

if( load_dlg_api(&dlg_api) != 0) {
LM_ERR("can't load dialog API\n");
return -1;
}

if( dlg_api.register_dlgcb( 0, DLGCB_LOADED, uac_on_load_callback, 0, 0) != 0) {
LM_ERR("can't register on load callback\n");
return -1;
}
LM_DBG("loaded dialog API and registered on load callback\n");
return 0;
}
2 changes: 2 additions & 0 deletions src/modules/uac/replace.h
Expand Up @@ -41,5 +41,7 @@ int restore_uri( struct sip_msg *msg, str *rr_param, str* restore_avp, int check
/* RR callback functions */
void rr_checker(struct sip_msg *msg, str *r_param, void *cb_param);

/* init dlg module */
int uac_init_dlg(void);

#endif
4 changes: 1 addition & 3 deletions src/modules/uac/uac.c
Expand Up @@ -90,7 +90,6 @@ struct rr_binds uac_rrb;
pv_spec_t auth_username_spec;
pv_spec_t auth_realm_spec;
pv_spec_t auth_password_spec;
struct dlg_binds dlg_api;

static int w_replace_from(struct sip_msg* msg, char* p1, char* p2);
static int w_restore_from(struct sip_msg* msg, char* p1, char* p2);
Expand Down Expand Up @@ -294,15 +293,14 @@ static int mod_init(void)
if (restore_mode==UAC_AUTO_RESTORE) {
/* we need the append_fromtag on in RR */

memset(&dlg_api, 0, sizeof(struct dlg_binds));
if (uac_restore_dlg==0) {
if (!uac_rrb.append_fromtag) {
LM_ERR("'append_fromtag' RR param is not enabled!"
" - required by AUTO restore mode\n");
goto error;
}
} else {
if (load_dlg_api(&dlg_api)!=0) {
if (uac_init_dlg()!=0) {
LM_ERR("failed to find dialog API - is dialog module loaded?\n");
goto error;
}
Expand Down

0 comments on commit a829305

Please sign in to comment.