Browse code

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);

Andrei Pelinescu-Onciul authored on 05/08/2010 22:22:05
Showing 4 changed files
... ...
@@ -133,14 +133,18 @@ struct onsend_info* p_onsend=0; /* onsend route send info */
133 133
  * Assumes src is unchanged.
134 134
  * Side-effects: clobbers i (int).
135 135
  */
136
-#define MODF_RVE_PARAM_FREE(src, dst) \
136
+#define MODF_RVE_PARAM_FREE(cmd, src, dst) \
137 137
 		for (i=0; i < (dst)[1].u.number; i++) { \
138 138
 			if ((src)[i+2].type == RVE_ST && (dst)[i+2].u.data) { \
139
-				if ((dst)[i+2].type == FPARAM_DYN_ST) {\
140
-					/* frees also orig. dst.u.data */ \
141
-					fparam_free_contents((dst)[i+2].u.data); \
142
-					/* the fparam struct. (dst.u.data) is freed below */ \
139
+				if ((dst)[i+2].type == RVE_FREE_FIXUP_ST) {\
140
+					/* call free_fixup (which should restore the original
141
+					   string) */ \
142
+					call_fixup((cmd)->free_fixup, &(dst)[i+2].u.data, i+1); \
143
+				} else if ((dst)[i+2].type == FPARAM_DYN_ST) {\
144
+					/* completely frees fparam and restore original string */\
145
+					fparam_free_restore(&(dst)[i+2].u.data); \
143 146
 				} \
147
+				/* free allocated string */ \
144 148
 				pkg_free((dst)[i+2].u.data); \
145 149
 				(dst)[i+2].u.data = 0; \
146 150
 			} \
... ...
@@ -165,18 +169,44 @@ struct onsend_info* p_onsend=0; /* onsend route send info */
165 165
 					rval_destroy(rv); \
166 166
 					ERR("failed to convert RVE to string\n"); \
167 167
 					(dst)[1].u.number = i; \
168
-					MODF_RVE_PARAM_FREE(src, dst); \
168
+					MODF_RVE_PARAM_FREE(cmd, src, dst); \
169 169
 					goto error; \
170 170
 				} \
171 171
 				(dst)[i+2].type = STRING_RVE_ST; \
172 172
 				(dst)[i+2].u.string = s.s; \
173 173
 				(dst)[i+2].u.str.len = s.len; \
174 174
 				rval_destroy(rv); \
175
-				if ((cmd)->fixup && \
176
-						(cmd)->fixup_flags & FIXUP_F_FPARAM_RVE) { \
177
-					call_fixup((cmd)->fixup, &(dst)[i+2].u.data, i+1); \
178
-					if ((dst)[i+2].u.data != s.s) \
179
-						(dst)[i+2].type = FPARAM_DYN_ST; \
175
+				if ((cmd)->fixup) {\
176
+					if ((cmd)->free_fixup) {\
177
+						if (likely( call_fixup((cmd)->fixup, \
178
+										&(dst)[i+2].u.data, i+1) >= 0) ) { \
179
+							/* success => mark it for calling free fixup */ \
180
+							if (likely((dst)[i+2].u.data != s.s)) \
181
+								(dst)[i+2].type = RVE_FREE_FIXUP_ST; \
182
+						} else { \
183
+							/* error calling fixup => mark conv. parameter \
184
+							   and return error */ \
185
+							(dst)[1].u.number = i; \
186
+							ERR("runtime fixup failed for %s param %d\n", \
187
+									(cmd)->name, i+1); \
188
+							MODF_RVE_PARAM_FREE(cmd, src, dst); \
189
+							goto error; \
190
+						} \
191
+					} else if ((cmd)->fixup_flags & FIXUP_F_FPARAM_RVE) { \
192
+						if (likely( call_fixup((cmd)->fixup, \
193
+										&(dst)[i+2].u.data, i+1) >= 0)) { \
194
+							if ((dst)[i+2].u.data != s.s) \
195
+								(dst)[i+2].type = FPARAM_DYN_ST; \
196
+						} else { \
197
+							/* error calling fixup => mark conv. parameter \
198
+							   and return error */ \
199
+							(dst)[1].u.number = i; \
200
+							ERR("runtime fixup failed for %s param %d\n", \
201
+									(cmd)->name, i+1); \
202
+							MODF_RVE_PARAM_FREE(cmd, src, dst); \
203
+							goto error; \
204
+						}\
205
+					} \
180 206
 				} \
181 207
 			} else \
182 208
 				(dst)[i+2]=(src)[i+2]; \
... ...
@@ -238,7 +268,7 @@ struct onsend_info* p_onsend=0; /* onsend route send info */
238 238
 		ret=((f_type)cmd->function)((msg), __VAR_ARGS__); \
239 239
 		MODF_HANDLE_RETCODE(h, ret); \
240 240
 		/* free strings allocated by us or fixups */ \
241
-		MODF_RVE_PARAM_FREE(src, dst); \
241
+		MODF_RVE_PARAM_FREE(cmd, src, dst); \
242 242
 	} while (0)
243 243
 #else  /* ! __SUNPRO_C  (gcc, icc a.s.o) */
244 244
 #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 */
248 248
 		ret=((f_type)cmd->function)((msg), ## params ); \
249 249
 		MODF_HANDLE_RETCODE(h, ret); \
250 250
 		/* free strings allocated by us or fixups */ \
251
-		MODF_RVE_PARAM_FREE(src, dst); \
251
+		MODF_RVE_PARAM_FREE(cmd, src, dst); \
252 252
 	} while (0)
253 253
 #endif /* __SUNPRO_C */
254 254
 
... ...
@@ -3751,9 +3751,10 @@ static int mod_f_params_pre_fixup(struct action* a)
3751 3751
 		if (is_fparam_rve_fixup(cmd_exp->fixup))
3752 3752
 			/* mark known fparam rve safe fixups */
3753 3753
 			cmd_exp->fixup_flags  |= FIXUP_F_FPARAM_RVE;
3754
-		else if (!(cmd_exp->fixup_flags & FIXUP_F_FPARAM_RVE)) {
3755
-			/* v0 or v1 functions that have fixups need constant,
3756
-			  string params.*/
3754
+		else if (!(cmd_exp->fixup_flags & FIXUP_F_FPARAM_RVE) &&
3755
+				 cmd_exp->free_fixup == 0) {
3756
+			/* v0 or v1 functions that have fixups and no coresp. fixup_free
3757
+			   functions, need constant, string params.*/
3757 3758
 			for (r=0; r < param_no; r++) {
3758 3759
 				rve=params[r].u.data;
3759 3760
 				if (!rve_is_constant(rve)) {
... ...
@@ -985,7 +985,8 @@ int fix_actions(struct action* a)
985 985
 					   or RVE_ST (non-ct RVEs) */
986 986
 					if (rve_param_no) { /* we have to fix the type */
987 987
 						if (cmd->fixup &&
988
-							!(cmd->fixup_flags & FIXUP_F_FPARAM_RVE)) {
988
+							!(cmd->fixup_flags & FIXUP_F_FPARAM_RVE) &&
989
+							cmd->free_fixup == 0) {
989 990
 							BUG("non-ct RVEs (%d) in module function call"
990 991
 									"that does not support them (%s)\n",
991 992
 									rve_param_no, cmd->name);
... ...
@@ -128,6 +128,7 @@ enum _operand_subtype{
128 128
 		RETCODE_ST, CASE_ST,
129 129
 		BLOCK_ST, JUMPTABLE_ST, CONDTABLE_ST, MATCH_CONDTABLE_ST,
130 130
 		STRING_RVE_ST /* RVE converted to a string (fparam hack) */,
131
+		RVE_FREE_FIXUP_ST /* (str)RVE fixed up by a reversable fixup */,
131 132
 		FPARAM_DYN_ST /* temporary only (fparam hack) */
132 133
 };
133 134