Module: sip-router Branch: andrei/rve_f_params Commit: d002aae942d64ebff7621140f2b148401595978b URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d002aae9...
Author: Andrei Pelinescu-Onciul andrei@iptel.org Committer: Andrei Pelinescu-Onciul andrei@iptel.org Date: Fri Aug 6 00:22:05 2010 +0200
core: enable RVE fixup support when fixup_free is present
RVEs can now be used transparently in all module functions that have registered free_fixup function or that have standard fixup functions with known corresponding free_fixups. This means all the module functions that use ser-like fparam style fixups (sr_module.h) or kamailio style fixups (mod_fix.h).
E.g.: texops(k): $del="From"; remove_hf_re("^"+$del); set_body($body, $content_type);
---
action.c | 56 +++++++++++++++++++++++++++++++++++++++++++------------- cfg.y | 7 ++++--- route.c | 3 ++- route_struct.h | 1 + 4 files changed, 50 insertions(+), 17 deletions(-)
diff --git a/action.c b/action.c index 9c643fb..08bc712 100644 --- a/action.c +++ b/action.c @@ -133,14 +133,18 @@ struct onsend_info* p_onsend=0; /* onsend route send info */ * Assumes src is unchanged. * Side-effects: clobbers i (int). */ -#define MODF_RVE_PARAM_FREE(src, dst) \ +#define MODF_RVE_PARAM_FREE(cmd, src, dst) \ for (i=0; i < (dst)[1].u.number; i++) { \ if ((src)[i+2].type == RVE_ST && (dst)[i+2].u.data) { \ - if ((dst)[i+2].type == FPARAM_DYN_ST) {\ - /* frees also orig. dst.u.data */ \ - fparam_free_contents((dst)[i+2].u.data); \ - /* the fparam struct. (dst.u.data) is freed below */ \ + if ((dst)[i+2].type == RVE_FREE_FIXUP_ST) {\ + /* call free_fixup (which should restore the original + string) */ \ + call_fixup((cmd)->free_fixup, &(dst)[i+2].u.data, i+1); \ + } else if ((dst)[i+2].type == FPARAM_DYN_ST) {\ + /* completely frees fparam and restore original string */\ + fparam_free_restore(&(dst)[i+2].u.data); \ } \ + /* free allocated string */ \ pkg_free((dst)[i+2].u.data); \ (dst)[i+2].u.data = 0; \ } \ @@ -165,18 +169,44 @@ struct onsend_info* p_onsend=0; /* onsend route send info */ rval_destroy(rv); \ ERR("failed to convert RVE to string\n"); \ (dst)[1].u.number = i; \ - MODF_RVE_PARAM_FREE(src, dst); \ + MODF_RVE_PARAM_FREE(cmd, src, dst); \ goto error; \ } \ (dst)[i+2].type = STRING_RVE_ST; \ (dst)[i+2].u.string = s.s; \ (dst)[i+2].u.str.len = s.len; \ rval_destroy(rv); \ - if ((cmd)->fixup && \ - (cmd)->fixup_flags & FIXUP_F_FPARAM_RVE) { \ - call_fixup((cmd)->fixup, &(dst)[i+2].u.data, i+1); \ - if ((dst)[i+2].u.data != s.s) \ - (dst)[i+2].type = FPARAM_DYN_ST; \ + if ((cmd)->fixup) {\ + if ((cmd)->free_fixup) {\ + if (likely( call_fixup((cmd)->fixup, \ + &(dst)[i+2].u.data, i+1) >= 0) ) { \ + /* success => mark it for calling free fixup */ \ + if (likely((dst)[i+2].u.data != s.s)) \ + (dst)[i+2].type = RVE_FREE_FIXUP_ST; \ + } else { \ + /* error calling fixup => mark conv. parameter \ + and return error */ \ + (dst)[1].u.number = i; \ + ERR("runtime fixup failed for %s param %d\n", \ + (cmd)->name, i+1); \ + MODF_RVE_PARAM_FREE(cmd, src, dst); \ + goto error; \ + } \ + } else if ((cmd)->fixup_flags & FIXUP_F_FPARAM_RVE) { \ + if (likely( call_fixup((cmd)->fixup, \ + &(dst)[i+2].u.data, i+1) >= 0)) { \ + if ((dst)[i+2].u.data != s.s) \ + (dst)[i+2].type = FPARAM_DYN_ST; \ + } else { \ + /* error calling fixup => mark conv. parameter \ + and return error */ \ + (dst)[1].u.number = i; \ + ERR("runtime fixup failed for %s param %d\n", \ + (cmd)->name, i+1); \ + MODF_RVE_PARAM_FREE(cmd, src, dst); \ + goto error; \ + }\ + } \ } \ } else \ (dst)[i+2]=(src)[i+2]; \ @@ -238,7 +268,7 @@ struct onsend_info* p_onsend=0; /* onsend route send info */ ret=((f_type)cmd->function)((msg), __VAR_ARGS__); \ MODF_HANDLE_RETCODE(h, ret); \ /* free strings allocated by us or fixups */ \ - MODF_RVE_PARAM_FREE(src, dst); \ + MODF_RVE_PARAM_FREE(cmd, src, dst); \ } while (0) #else /* ! __SUNPRO_C (gcc, icc a.s.o) */ #define MODF_RVE_CALL(f_type, h, msg, src, dst, params...) \ @@ -248,7 +278,7 @@ struct onsend_info* p_onsend=0; /* onsend route send info */ ret=((f_type)cmd->function)((msg), ## params ); \ MODF_HANDLE_RETCODE(h, ret); \ /* free strings allocated by us or fixups */ \ - MODF_RVE_PARAM_FREE(src, dst); \ + MODF_RVE_PARAM_FREE(cmd, src, dst); \ } while (0) #endif /* __SUNPRO_C */
diff --git a/cfg.y b/cfg.y index f97c408..7627619 100644 --- a/cfg.y +++ b/cfg.y @@ -3751,9 +3751,10 @@ static int mod_f_params_pre_fixup(struct action* a) if (is_fparam_rve_fixup(cmd_exp->fixup)) /* mark known fparam rve safe fixups */ cmd_exp->fixup_flags |= FIXUP_F_FPARAM_RVE; - else if (!(cmd_exp->fixup_flags & FIXUP_F_FPARAM_RVE)) { - /* v0 or v1 functions that have fixups need constant, - string params.*/ + else if (!(cmd_exp->fixup_flags & FIXUP_F_FPARAM_RVE) && + cmd_exp->free_fixup == 0) { + /* v0 or v1 functions that have fixups and no coresp. fixup_free + functions, need constant, string params.*/ for (r=0; r < param_no; r++) { rve=params[r].u.data; if (!rve_is_constant(rve)) { diff --git a/route.c b/route.c index e603030..c05a781 100644 --- a/route.c +++ b/route.c @@ -985,7 +985,8 @@ int fix_actions(struct action* a) or RVE_ST (non-ct RVEs) */ if (rve_param_no) { /* we have to fix the type */ if (cmd->fixup && - !(cmd->fixup_flags & FIXUP_F_FPARAM_RVE)) { + !(cmd->fixup_flags & FIXUP_F_FPARAM_RVE) && + cmd->free_fixup == 0) { BUG("non-ct RVEs (%d) in module function call" "that does not support them (%s)\n", rve_param_no, cmd->name); diff --git a/route_struct.h b/route_struct.h index 178ac77..5c1d37f 100644 --- a/route_struct.h +++ b/route_struct.h @@ -128,6 +128,7 @@ enum _operand_subtype{ RETCODE_ST, CASE_ST, BLOCK_ST, JUMPTABLE_ST, CONDTABLE_ST, MATCH_CONDTABLE_ST, STRING_RVE_ST /* RVE converted to a string (fparam hack) */, + RVE_FREE_FIXUP_ST /* (str)RVE fixed up by a reversable fixup */, FPARAM_DYN_ST /* temporary only (fparam hack) */ };