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=d002aae…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)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) */
};