core: enable RVE fixup support when fixup_free is present
[sip-router] / action.c
1
2 /*
3  * $Id$
4  *
5  * Copyright (C) 2001-2003 FhG Fokus
6  *
7  * This file is part of ser, a free SIP server.
8  *
9  * ser is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version
13  *
14  * For a license to use the ser software under conditions
15  * other than those described here, or to purchase support for this
16  * software, please contact iptel.org by e-mail at the following addresses:
17  *    info@iptel.org
18  *
19  * ser is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27  *
28  * History:
29  * ---------
30  *  2003-02-28  scratchpad compatibility abandoned (jiri)
31  *  2003-01-29  removed scratchpad (jiri)
32  *  2003-03-19  fixed set* len calculation bug & simplified a little the code
33  *              (should be a little faster now) (andrei)
34  *              replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei)
35  *  2003-04-01  Added support for loose routing in forward (janakj)
36  *  2003-04-12  FORCE_RPORT_T added (andrei)
37  *  2003-04-22  strip_tail added (jiri)
38  *  2003-10-02  added SET_ADV_ADDR_T & SET_ADV_PORT_T (andrei)
39  *  2003-10-29  added FORCE_TCP_ALIAS_T (andrei)
40  *  2004-11-30  added FORCE_SEND_SOCKET_T (andrei)
41  *  2005-12-12  return & drop/exit differentiation (andrei)
42  *  2005-12-19  select framework (mma)
43  *  2006-04-12  updated *_send() calls to use a struct dest_info (andrei)
44  *  2006-07-27  dns cache and dns based send address failover support (andrei)
45  *  2006-12-06  on popular request last_retcode set also by module functions
46  *              (andrei)
47  *  2007-06-14  run_actions & do_action need a ctx or handle now, no more
48  *               static vars (andrei)
49  *  2008-11-18  support for variable parameter module functions (andrei)
50  *  2008-12-03  use lvalues/rvalues for assignments (andrei)
51  *  2008-12-17  added UDP_MTU_TRY_PROTO_T (andrei)
52  *  2009-05-04  switched IF_T to rval_expr (andrei)
53  *  2009-09-15  added SET_{FWD,RPL}_NO_CONNECT, SET_{FWD,RPL}_CLOSE (andrei)
54  *  2010-06-01  special hack/support for fparam fixups so that they can handle
55  *               variable RVEs (andrei)
56  */
57
58 /*!
59  * \file
60  * \brief SIP-router core :: 
61  * \ingroup core
62  * Module: \ref core
63  */
64
65
66
67 #include "comp_defs.h"
68
69 #include "action.h"
70 #include "config.h"
71 #include "error.h"
72 #include "dprint.h"
73 #include "proxy.h"
74 #include "forward.h"
75 #include "udp_server.h"
76 #include "route.h"
77 #include "parser/msg_parser.h"
78 #include "parser/parse_uri.h"
79 #include "ut.h"
80 #include "lvalue.h"
81 #include "sr_module.h"
82 #include "select_buf.h"
83 #include "mem/mem.h"
84 #include "globals.h"
85 #include "dset.h"
86 #include "onsend.h"
87 #include "resolve.h"
88 #ifdef USE_TCP
89 #include "tcp_server.h"
90 #endif
91 #ifdef USE_SCTP
92 #include "sctp_server.h"
93 #endif
94 #include "switch.h"
95 #include "events.h"
96
97 #include <sys/types.h>
98 #include <sys/socket.h>
99 #include <netdb.h>
100 #include <stdlib.h>
101 #include <netinet/in.h>
102 #include <arpa/inet.h>
103 #include <string.h>
104
105
106 #ifdef DEBUG_DMALLOC
107 #include <dmalloc.h>
108 #endif
109
110 int _last_returned_code  = 0;
111 struct onsend_info* p_onsend=0; /* onsend route send info */
112
113
114
115 /* handle the exit code of a module function call.
116  * (used internally in do_action())
117  * @param h - script handle (h->last_retcode and h->run_flags will be set).
118  * @param ret - module function (v0 or v2) retcode
119  * Side-effects: sets _last_returned_code
120  */
121 #define MODF_HANDLE_RETCODE(h, ret) \
122         do { \
123                 /* if (unlikely((ret)==0)) (h)->run_flags|=EXIT_R_F; */ \
124                 (h)->run_flags |= EXIT_R_F & (((ret) != 0) -1); \
125                 (h)->last_retcode=(ret); \
126                 _last_returned_code = (h)->last_retcode; \
127         } while(0)
128
129
130
131 /* frees parameters converted using MODF_RVE_PARAM_CONVERT() from dst.
132  * (used internally in do_action())
133  * Assumes src is unchanged.
134  * Side-effects: clobbers i (int).
135  */
136 #define MODF_RVE_PARAM_FREE(cmd, src, dst) \
137                 for (i=0; i < (dst)[1].u.number; i++) { \
138                         if ((src)[i+2].type == RVE_ST && (dst)[i+2].u.data) { \
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); \
146                                 } \
147                                 /* free allocated string */ \
148                                 pkg_free((dst)[i+2].u.data); \
149                                 (dst)[i+2].u.data = 0; \
150                         } \
151                 }
152
153
154 /* fills dst from src, converting RVE_ST params to STRING_ST.
155  * (used internally in do_action())
156  * @param src - source action_u_t array, as in the action structure
157  * @param dst - destination action_u_t array, will be filled from src.
158  * WARNING: dst must be cleaned when done, use MODULE_RVE_PARAM_FREE()
159  * Side-effects: clobbers i (int), s (str), rv (rvalue*), might jump to error.
160  */
161 #define MODF_RVE_PARAM_CONVERT(h, msg, cmd, src, dst) \
162         do { \
163                 (dst)[1]=(src)[1]; \
164                 for (i=0; i < (src)[1].u.number; i++) { \
165                         if ((src)[2+i].type == RVE_ST) { \
166                                 rv=rval_expr_eval((h), (msg), (src)[i+2].u.data); \
167                                 if (unlikely(rv == 0 || \
168                                         rval_get_str((h), (msg), &s, rv, 0) < 0)) { \
169                                         rval_destroy(rv); \
170                                         ERR("failed to convert RVE to string\n"); \
171                                         (dst)[1].u.number = i; \
172                                         MODF_RVE_PARAM_FREE(cmd, src, dst); \
173                                         goto error; \
174                                 } \
175                                 (dst)[i+2].type = STRING_RVE_ST; \
176                                 (dst)[i+2].u.string = s.s; \
177                                 (dst)[i+2].u.str.len = s.len; \
178                                 rval_destroy(rv); \
179                                 if ((cmd)->fixup) {\
180                                         if ((cmd)->free_fixup) {\
181                                                 if (likely( call_fixup((cmd)->fixup, \
182                                                                                 &(dst)[i+2].u.data, i+1) >= 0) ) { \
183                                                         /* success => mark it for calling free fixup */ \
184                                                         if (likely((dst)[i+2].u.data != s.s)) \
185                                                                 (dst)[i+2].type = RVE_FREE_FIXUP_ST; \
186                                                 } else { \
187                                                         /* error calling fixup => mark conv. parameter \
188                                                            and return error */ \
189                                                         (dst)[1].u.number = i; \
190                                                         ERR("runtime fixup failed for %s param %d\n", \
191                                                                         (cmd)->name, i+1); \
192                                                         MODF_RVE_PARAM_FREE(cmd, src, dst); \
193                                                         goto error; \
194                                                 } \
195                                         } else if ((cmd)->fixup_flags & FIXUP_F_FPARAM_RVE) { \
196                                                 if (likely( call_fixup((cmd)->fixup, \
197                                                                                 &(dst)[i+2].u.data, i+1) >= 0)) { \
198                                                         if ((dst)[i+2].u.data != s.s) \
199                                                                 (dst)[i+2].type = FPARAM_DYN_ST; \
200                                                 } else { \
201                                                         /* error calling fixup => mark conv. parameter \
202                                                            and return error */ \
203                                                         (dst)[1].u.number = i; \
204                                                         ERR("runtime fixup failed for %s param %d\n", \
205                                                                         (cmd)->name, i+1); \
206                                                         MODF_RVE_PARAM_FREE(cmd, src, dst); \
207                                                         goto error; \
208                                                 }\
209                                         } \
210                                 } \
211                         } else \
212                                 (dst)[i+2]=(src)[i+2]; \
213                 } \
214         } while(0)
215
216
217
218 /* call a module function with normal STRING_ST params.
219  * (used internally in do_action())
220  * @param f_type - cmd_function type
221  * @param h
222  * @param msg
223  * @param src - source action_u_t array (e.g. action->val)
224  * @param params... - variable list of parameters, passed to the module
225  *               function
226  * Side-effects: sets ret, clobbers i (int), s (str), rv (rvalue*), cmd,
227  *               might jump to error.
228  *
229  */
230 #ifdef __SUNPRO_C
231 #define MODF_CALL(f_type, h, msg, src, ...) \
232         do { \
233                 cmd=(src)[0].u.data; \
234                 ret=((f_type)cmd->function)((msg), __VAR_ARGS__); \
235                 MODF_HANDLE_RETCODE(h, ret); \
236         } while (0)
237 #else  /* ! __SUNPRO_C  (gcc, icc a.s.o) */
238 #define MODF_CALL(f_type, h, msg, src, params...) \
239         do { \
240                 cmd=(src)[0].u.data; \
241                 ret=((f_type)cmd->function)((msg), ## params ); \
242                 MODF_HANDLE_RETCODE(h, ret); \
243         } while (0)
244 #endif /* __SUNPRO_C */
245
246
247
248 /* call a module function with possible RVE params.
249  * (used internally in do_action())
250  * @param f_type - cmd_function type
251  * @param h
252  * @param msg
253  * @param src - source action_u_t array (e.g. action->val)
254  * @param dst - temporary action_u_t array used for conversions. It can be
255  *              used for the function parameters. It's contents it's not
256  *              valid after the call.
257  * @param params... - variable list of parameters, passed to the module
258  *               function
259  * Side-effects: sets ret, clobbers i (int), s (str), rv (rvalue*), f, dst,
260  *               might jump to error.
261  *
262  */
263 #ifdef __SUNPRO_C
264 #define MODF_RVE_CALL(f_type, h, msg, src, dst, ...) \
265         do { \
266                 cmd=(src)[0].u.data; \
267                 MODF_RVE_PARAM_CONVERT(h, msg, cmd, src, dst); \
268                 ret=((f_type)cmd->function)((msg), __VAR_ARGS__); \
269                 MODF_HANDLE_RETCODE(h, ret); \
270                 /* free strings allocated by us or fixups */ \
271                 MODF_RVE_PARAM_FREE(cmd, src, dst); \
272         } while (0)
273 #else  /* ! __SUNPRO_C  (gcc, icc a.s.o) */
274 #define MODF_RVE_CALL(f_type, h, msg, src, dst, params...) \
275         do { \
276                 cmd=(src)[0].u.data; \
277                 MODF_RVE_PARAM_CONVERT(h, msg, cmd, src, dst); \
278                 ret=((f_type)cmd->function)((msg), ## params ); \
279                 MODF_HANDLE_RETCODE(h, ret); \
280                 /* free strings allocated by us or fixups */ \
281                 MODF_RVE_PARAM_FREE(cmd, src, dst); \
282         } while (0)
283 #endif /* __SUNPRO_C */
284
285
286 /* ret= 0! if action -> end of list(e.g DROP),
287       > 0 to continue processing next actions
288    and <0 on error */
289 int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
290 {
291         int ret;
292         int v;
293         struct dest_info dst;
294         char* tmp;
295         char *new_uri, *end, *crt;
296         sr31_cmd_export_t* cmd;
297         int len;
298         int user;
299         struct sip_uri uri, next_hop;
300         struct sip_uri *u;
301         unsigned short port;
302         str* dst_host;
303         int i, flags;
304         struct switch_cond_table* sct;
305         struct switch_jmp_table*  sjt;
306         struct rval_expr* rve;
307         struct match_cond_table* mct;
308         struct rvalue* rv;
309         struct rvalue* rv1;
310         struct rval_cache c1;
311         str s;
312         void *srevp[2];
313         /* temporary storage space for a struct action.val[] working copy
314          (needed to transform RVE intro STRING before calling module
315            functions). [0] is not used (corresp. to the module export pointer),
316            [1] contains the number of params, and [2..] the param values.
317            We need [1], because some fixup function use it
318           (see fixup_get_param_count()).  */
319         static action_u_t mod_f_params[MAX_ACTIONS];
320
321         /* reset the value of error to E_UNSPEC so avoid unknowledgable
322            functions to return with error (status<0) and not setting it
323            leaving there previous error; cache the previous value though
324            for functions which want to process it */
325         prev_ser_error=ser_error;
326         ser_error=E_UNSPEC;
327
328         /* hook for every executed action (in use by cfg debugger) */
329         if(unlikely(sr_event_enabled(SREV_CFG_RUN_ACTION)))
330         {
331                 srevp[0] = (void*)a;
332                 srevp[1] = (void*)msg;
333                 sr_event_exec(SREV_CFG_RUN_ACTION, (void*)srevp);
334         }
335
336         ret=E_BUG;
337         switch ((unsigned char)a->type){
338                 case DROP_T:
339                                 switch(a->val[0].type){
340                                         case NUMBER_ST:
341                                                 ret=(int) a->val[0].u.number;
342                                                 break;
343                                         case RVE_ST:
344                                                 rve=(struct rval_expr*)a->val[0].u.data;
345                                                 rval_expr_eval_int(h, msg, &ret, rve);
346                                                 break;
347                                         case RETCODE_ST:
348                                                 ret=h->last_retcode;
349                                                 break;
350                                         default:
351                                                 BUG("unexpected subtype %d in DROP_T\n",
352                                                                 a->val[0].type);
353                                                 ret=0;
354                                                 goto error;
355                                 }
356                                 h->run_flags|=(unsigned int)a->val[1].u.number;
357                         break;
358                 case FORWARD_T:
359 #ifdef USE_TCP
360                 case FORWARD_TCP_T:
361 #endif
362 #ifdef USE_TLS
363                 case FORWARD_TLS_T:
364 #endif
365 #ifdef USE_SCTP
366                 case FORWARD_SCTP_T:
367 #endif
368                 case FORWARD_UDP_T:
369                         /* init dst */
370                         init_dest_info(&dst);
371                         if (a->type==FORWARD_UDP_T) dst.proto=PROTO_UDP;
372 #ifdef USE_TCP
373                         else if (a->type==FORWARD_TCP_T) dst.proto= PROTO_TCP;
374 #endif
375 #ifdef USE_TLS
376                         else if (a->type==FORWARD_TLS_T) dst.proto= PROTO_TLS;
377 #endif
378 #ifdef USE_SCTP
379                         else if (a->type==FORWARD_SCTP_T) dst.proto=PROTO_SCTP;
380 #endif
381                         else dst.proto=PROTO_NONE;
382                         if (a->val[0].type==URIHOST_ST){
383                                 /*parse uri*/
384
385                                 if (msg->dst_uri.len) {
386                                         ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len,
387                                                                         &next_hop);
388                                         u = &next_hop;
389                                 } else {
390                                         ret = parse_sip_msg_uri(msg);
391                                         u = &msg->parsed_uri;
392                                 }
393
394                                 if (ret<0) {
395                                         LOG(L_ERR, "ERROR: do_action: forward: bad_uri "
396                                                                 " dropping packet\n");
397                                         goto error;
398                                 }
399
400                                 switch (a->val[1].type){
401                                         case URIPORT_ST:
402                                                                         port=u->port_no;
403                                                                         break;
404                                         case NUMBER_ST:
405                                                                         port=a->val[1].u.number;
406                                                                         break;
407                                         default:
408                                                         LOG(L_CRIT, "BUG: do_action bad forward 2nd"
409                                                                                 " param type (%d)\n", a->val[1].type);
410                                                         ret=E_UNSPEC;
411                                                         goto error_fwd_uri;
412                                 }
413                                 if (dst.proto == PROTO_NONE){ /* only if proto not set get it
414                                                                                          from the uri */
415                                         switch(u->proto){
416                                                 case PROTO_NONE:
417                                                         /*dst.proto=PROTO_UDP; */
418                                                         /* no proto, try to get it from the dns */
419                                                         break;
420                                                 case PROTO_UDP:
421 #ifdef USE_TCP
422                                                 case PROTO_TCP:
423 #endif
424 #ifdef USE_TLS
425                                                 case PROTO_TLS:
426 #endif
427 #ifdef USE_SCTP
428                                                 case PROTO_SCTP:
429 #endif
430                                                         dst.proto=u->proto;
431                                                         break;
432                                                 default:
433                                                         LOG(L_ERR,"ERROR: do action: forward: bad uri"
434                                                                         " transport %d\n", u->proto);
435                                                         ret=E_BAD_PROTO;
436                                                         goto error_fwd_uri;
437                                         }
438 #ifdef USE_TLS
439                                         if (u->type==SIPS_URI_T){
440                                                 if (u->proto==PROTO_UDP){
441                                                         LOG(L_ERR, "ERROR: do_action: forward: secure uri"
442                                                                         " incompatible with transport %d\n",
443                                                                         u->proto);
444                                                         ret=E_BAD_PROTO;
445                                                         goto error_fwd_uri;
446                                                 }
447                                                 dst.proto=PROTO_TLS;
448                                         }
449 #endif
450                                 }
451
452 #ifdef HONOR_MADDR
453                                 if (u->maddr_val.s && u->maddr_val.len)
454                                         dst_host=&u->maddr_val;
455                                 else
456 #endif
457                                         dst_host=&u->host;
458 #ifdef USE_COMP
459                                 dst.comp=u->comp;
460 #endif
461                                 ret=forward_request(msg, dst_host, port, &dst);
462                                 if (ret>=0){
463                                         ret=1;
464                                 }
465                         }else if ((a->val[0].type==PROXY_ST) && (a->val[1].type==NUMBER_ST)){
466                                 if (dst.proto==PROTO_NONE)
467                                         dst.proto=msg->rcv.proto;
468                                 proxy2su(&dst.to,  (struct proxy_l*)a->val[0].u.data);
469                                 ret=forward_request(msg, 0, 0, &dst);
470                                 if (ret>=0){
471                                         ret=1;
472                                         proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
473                                 }else if (ser_error!=E_OK){
474                                         proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
475                                 }
476                         }else{
477                                 LOG(L_CRIT, "BUG: do_action: bad forward() types %d, %d\n",
478                                                 a->val[0].type, a->val[1].type);
479                                 ret=E_BUG;
480                                 goto error;
481                         }
482                         break;
483                 case SEND_T:
484                 case SEND_TCP_T:
485                         if ((a->val[0].type!= PROXY_ST)|(a->val[1].type!=NUMBER_ST)){
486                                 LOG(L_CRIT, "BUG: do_action: bad send() types %d, %d\n",
487                                                 a->val[0].type, a->val[1].type);
488                                 ret=E_BUG;
489                                 goto error;
490                         }
491                         /* init dst */
492                         init_dest_info(&dst);
493                         ret=proxy2su(&dst.to,  (struct proxy_l*)a->val[0].u.data);
494                         if (ret==0){
495                                 if (p_onsend){
496                                         tmp=p_onsend->buf;
497                                         len=p_onsend->len;
498                                 }else{
499                                         tmp=msg->buf;
500                                         len=msg->len;
501                                 }
502                                 if (a->type==SEND_T){
503                                         /*udp*/
504                                         dst.proto=PROTO_UDP; /* not really needed for udp_send */
505                                         dst.send_sock=get_send_socket(msg, &dst.to, PROTO_UDP);
506                                         if (dst.send_sock!=0){
507                                                 ret=udp_send(&dst, tmp, len);
508                                         }else{
509                                                 ret=-1;
510                                         }
511                                 }
512 #ifdef USE_TCP
513                                         else{
514                                                 /*tcp*/
515                                                 dst.proto=PROTO_TCP;
516                                                 dst.id=0;
517                                                 ret=tcp_send(&dst, 0, tmp, len);
518                                 }
519 #endif
520                         }else{
521                                 ret=E_BUG;
522                                 goto error;
523                         }
524                         proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
525                         if (ret>=0) ret=1;
526
527                         break;
528                 case LOG_T:
529                         if ((a->val[0].type!=NUMBER_ST)|(a->val[1].type!=STRING_ST)){
530                                 LOG(L_CRIT, "BUG: do_action: bad log() types %d, %d\n",
531                                                 a->val[0].type, a->val[1].type);
532                                 ret=E_BUG;
533                                 goto error;
534                         }
535                         LOG_(DEFAULT_FACILITY, a->val[0].u.number, "<script>: ", "%s", 
536                                  a->val[1].u.string);
537                         ret=1;
538                         break;
539
540                 /* jku -- introduce a new branch */
541                 case APPEND_BRANCH_T:
542                         if (unlikely(a->val[0].type!=STR_ST)) {
543                                 LOG(L_CRIT, "BUG: do_action: bad append_branch_t %d\n",
544                                         a->val[0].type );
545                                 ret=E_BUG;
546                                 goto error;
547                         }
548                         getbflagsval(0, (flag_t*)&flags);
549                         ret=append_branch(msg, &a->val[0].u.str, &msg->dst_uri,
550                                                                 &msg->path_vec, a->val[1].u.number,
551                                                                 (flag_t)flags, msg->force_send_socket);
552                         break;
553
554                 /* jku begin: is_length_greater_than */
555                 case LEN_GT_T:
556                         if (a->val[0].type!=NUMBER_ST) {
557                                 LOG(L_CRIT, "BUG: do_action: bad len_gt type %d\n",
558                                         a->val[0].type );
559                                 ret=E_BUG;
560                                 goto error;
561                         }
562                         /* DBG("XXX: message length %d, max %d\n",
563                                 msg->len, a->val[0].u.number ); */
564                         ret = msg->len >= a->val[0].u.number ? 1 : -1;
565                         break;
566                 /* jku end: is_length_greater_than */
567
568                 /* jku - begin : flag processing */
569
570                 case SETFLAG_T:
571                         if (a->val[0].type!=NUMBER_ST) {
572                                 LOG(L_CRIT, "BUG: do_action: bad setflag() type %d\n",
573                                         a->val[0].type );
574                                 ret=E_BUG;
575                                 goto error;
576                         }
577                         if (!flag_in_range( a->val[0].u.number )) {
578                                 ret=E_CFG;
579                                 goto error;
580                         }
581                         setflag( msg, a->val[0].u.number );
582                         ret=1;
583                         break;
584
585                 case RESETFLAG_T:
586                         if (a->val[0].type!=NUMBER_ST) {
587                                 LOG(L_CRIT, "BUG: do_action: bad resetflag() type %d\n",
588                                         a->val[0].type );
589                                 ret=E_BUG;
590                                 goto error;
591                         }
592                         if (!flag_in_range( a->val[0].u.number )) {
593                                 ret=E_CFG;
594                                 goto error;
595                         }
596                         resetflag( msg, a->val[0].u.number );
597                         ret=1;
598                         break;
599
600                 case ISFLAGSET_T:
601                         if (a->val[0].type!=NUMBER_ST) {
602                                 LOG(L_CRIT, "BUG: do_action: bad isflagset() type %d\n",
603                                         a->val[0].type );
604                                 ret=E_BUG;
605                                 goto error;
606                         }
607                         if (!flag_in_range( a->val[0].u.number )) {
608                                 ret=E_CFG;
609                                 goto error;
610                         }
611                         ret=isflagset( msg, a->val[0].u.number );
612                         break;
613                 /* jku - end : flag processing */
614
615                 case AVPFLAG_OPER_T:  {
616                         struct search_state st;
617                         avp_t* avp;
618                         int flag;
619                         ret = 0;
620                         flag = a->val[1].u.number;
621                         if ((a->val[0].u.attr->type & AVP_INDEX_ALL) == AVP_INDEX_ALL || (a->val[0].u.attr->type & AVP_NAME_RE)!=0) {
622                                 for (avp=search_first_avp(a->val[0].u.attr->type, a->val[0].u.attr->name, NULL, &st); avp; avp = search_next_avp(&st, NULL)) {
623                                         switch (a->val[2].u.number) {   /* oper: 0..reset, 1..set, -1..no change */
624                                                 case 0:
625                                                         avp->flags &= ~(avp_flags_t)a->val[1].u.number;
626                                                         break;
627                                                 case 1:
628                                                         avp->flags |= (avp_flags_t)a->val[1].u.number;
629                                                         break;
630                                                 default:;
631                                         }
632                                         ret = ret || ((avp->flags & (avp_flags_t)a->val[1].u.number) != 0);
633                                 }
634                         }
635                         else {
636                                 avp = search_avp_by_index(a->val[0].u.attr->type, a->val[0].u.attr->name, NULL, a->val[0].u.attr->index);
637                                 if (avp) {
638                                         switch (a->val[2].u.number) {   /* oper: 0..reset, 1..set, -1..no change */
639                                                 case 0:
640                                                         avp->flags &= ~(avp_flags_t)a->val[1].u.number;
641                                                         break;
642                                                 case 1:
643                                                         avp->flags |= (avp_flags_t)a->val[1].u.number;
644                                                         break;
645                                                 default:;
646                                         }
647                                         ret = (avp->flags & (avp_flags_t)a->val[1].u.number) != 0;
648                                 }
649                         }
650                         if (ret==0)
651                                 ret = -1;
652                         break;
653                 }
654                 case ERROR_T:
655                         if ((a->val[0].type!=STRING_ST)|(a->val[1].type!=STRING_ST)){
656                                 LOG(L_CRIT, "BUG: do_action: bad error() types %d, %d\n",
657                                                 a->val[0].type, a->val[1].type);
658                                 ret=E_BUG;
659                                 goto error;
660                         }
661                         LOG(L_NOTICE, "WARNING: do_action: error(\"%s\", \"%s\") "
662                                         "not implemented yet\n", a->val[0].u.string, a->val[1].u.string);
663                         ret=1;
664                         break;
665                 case ROUTE_T:
666                         if (a->val[0].type!=NUMBER_ST){
667                                 LOG(L_CRIT, "BUG: do_action: bad route() type %d\n",
668                                                 a->val[0].type);
669                                 ret=E_BUG;
670                                 goto error;
671                         }
672                         if ((a->val[0].u.number>=main_rt.idx)||(a->val[0].u.number<0)){
673                                 LOG(L_ERR, "ERROR: invalid routing table number in"
674                                                         "route(%lu)\n", a->val[0].u.number);
675                                 ret=E_CFG;
676                                 goto error;
677                         }
678                         /*ret=((ret=run_actions(rlist[a->val[0].u.number], msg))<0)?ret:1;*/
679                         ret=run_actions(h, main_rt.rlist[a->val[0].u.number], msg);
680                         h->last_retcode=ret;
681                         _last_returned_code = h->last_retcode;
682                         h->run_flags&=~(RETURN_R_F|BREAK_R_F); /* absorb return & break */
683                         break;
684                 case EXEC_T:
685                         if (a->val[0].type!=STRING_ST){
686                                 LOG(L_CRIT, "BUG: do_action: bad exec() type %d\n",
687                                                 a->val[0].type);
688                                 ret=E_BUG;
689                                 goto error;
690                         }
691                         LOG(L_NOTICE, "WARNING: exec(\"%s\") not fully implemented,"
692                                                 " using dumb version...\n", a->val[0].u.string);
693                         ret=system(a->val[0].u.string);
694                         if (ret!=0){
695                                 LOG(L_NOTICE, "WARNING: exec() returned %d\n", ret);
696                         }
697                         ret=1;
698                         break;
699                 case REVERT_URI_T:
700                         if (msg->new_uri.s) {
701                                 pkg_free(msg->new_uri.s);
702                                 msg->new_uri.len=0;
703                                 msg->new_uri.s=0;
704                                 msg->parsed_uri_ok=0; /* invalidate current parsed uri*/
705                         };
706                         ret=1;
707                         break;
708                 case SET_HOST_T:
709                 case SET_HOSTPORT_T:
710                 case SET_HOSTPORTTRANS_T:
711                 case SET_HOSTALL_T:
712                 case SET_USER_T:
713                 case SET_USERPASS_T:
714                 case SET_PORT_T:
715                 case SET_URI_T:
716                 case PREFIX_T:
717                 case STRIP_T:
718                 case STRIP_TAIL_T:
719                 case SET_USERPHONE_T:
720                                 user=0;
721                                 if (a->type==STRIP_T || a->type==STRIP_TAIL_T) {
722                                         if (a->val[0].type!=NUMBER_ST) {
723                                                 LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
724                                                         a->val[0].type);
725                                                 ret=E_BUG;
726                                                 goto error;
727                                         }
728                                 } else if (a->type!=SET_USERPHONE_T) {
729                                         if (a->val[0].type!=STRING_ST) {
730                                                 LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
731                                                         a->val[0].type);
732                                                 ret=E_BUG;
733                                                 goto error;
734                                         }
735                                 }
736                                 if (a->type==SET_URI_T){
737                                         if (msg->new_uri.s) {
738                                                         pkg_free(msg->new_uri.s);
739                                                         msg->new_uri.len=0;
740                                         }
741                                         msg->parsed_uri_ok=0;
742                                         len=strlen(a->val[0].u.string);
743                                         msg->new_uri.s=pkg_malloc(len+1);
744                                         if (msg->new_uri.s==0){
745                                                 LOG(L_ERR, "ERROR: do_action: memory allocation"
746                                                                 " failure\n");
747                                                 ret=E_OUT_OF_MEM;
748                                                 goto error;
749                                         }
750                                         memcpy(msg->new_uri.s, a->val[0].u.string, len);
751                                         msg->new_uri.s[len]=0;
752                                         msg->new_uri.len=len;
753
754                                         ret=1;
755                                         break;
756                                 }
757                                 if (msg->parsed_uri_ok==0) {
758                                         if (msg->new_uri.s) {
759                                                 tmp=msg->new_uri.s;
760                                                 len=msg->new_uri.len;
761                                         }else{
762                                                 tmp=msg->first_line.u.request.uri.s;
763                                                 len=msg->first_line.u.request.uri.len;
764                                         }
765                                         if (parse_uri(tmp, len, &uri)<0){
766                                                 LOG(L_ERR, "ERROR: do_action: bad uri <%s>, dropping"
767                                                                         " packet\n", tmp);
768                                                 ret=E_UNSPEC;
769                                                 goto error;
770                                         }
771                                 } else {
772                                         uri=msg->parsed_uri;
773                                 }
774
775                                 /* skip SET_USERPHONE_T action if the URI is already
776                                  * a tel: or tels: URI, or contains the user=phone param */
777                                 if ((a->type==SET_USERPHONE_T) 
778                                         && ((uri.type==TEL_URI_T) || (uri.type==TELS_URI_T)
779                                                 || ((uri.user_param_val.len==5) && (memcmp(uri.user_param_val.s, "phone", 5)==0)))
780                                 ) {
781                                         ret=1;
782                                         break;
783                                 }
784                                 /* SET_PORT_T does not work with tel: URIs */
785                                 if ((a->type==SET_PORT_T)
786                                         && ((uri.type==TEL_URI_T) || (uri.type==TELS_URI_T))
787                                         && ((uri.flags & URI_SIP_USER_PHONE)==0)
788                                 ) {
789                                         LOG(L_ERR, "ERROR: do_action: port number of a tel: URI cannot be set\n");
790                                         ret=E_UNSPEC;
791                                         goto error;
792                                 }
793
794                                 new_uri=pkg_malloc(MAX_URI_SIZE);
795                                 if (new_uri==0){
796                                         LOG(L_ERR, "ERROR: do_action: memory allocation "
797                                                                 " failure\n");
798                                         ret=E_OUT_OF_MEM;
799                                         goto error;
800                                 }
801                                 end=new_uri+MAX_URI_SIZE;
802                                 crt=new_uri;
803                                 /* begin copying */
804                                 /* Preserve the URI scheme unless the host part needs
805                                  * to be rewritten, and the shceme is tel: or tels: */
806                                 switch (uri.type) {
807                                 case SIP_URI_T:
808                                         len=s_sip.len;
809                                         tmp=s_sip.s;
810                                         break;
811
812                                 case SIPS_URI_T:
813                                         len=s_sips.len;
814                                         tmp=s_sips.s;
815                                         break;
816
817                                 case TEL_URI_T:
818                                         if ((uri.flags & URI_SIP_USER_PHONE)
819                                                 || (a->type==SET_HOST_T)
820                                                 || (a->type==SET_HOSTPORT_T)
821                                                 || (a->type==SET_HOSTPORTTRANS_T)
822                                         ) {
823                                                 len=s_sip.len;
824                                                 tmp=s_sip.s;
825                                                 break;
826                                         }
827                                         len=s_tel.len;
828                                         tmp=s_tel.s;
829                                         break;
830
831                                 case TELS_URI_T:
832                                         if ((uri.flags & URI_SIP_USER_PHONE)
833                                                 || (a->type==SET_HOST_T)
834                                                 || (a->type==SET_HOSTPORT_T)
835                                                 || (a->type==SET_HOSTPORTTRANS_T)
836                                         ) {
837                                                 len=s_sips.len;
838                                                 tmp=s_sips.s;
839                                                 break;
840                                         }
841                                         len=s_tels.len;
842                                         tmp=s_tels.s;
843                                         break;
844
845                                 default:
846                                         LOG(L_ERR, "ERROR: Unsupported URI scheme (%d), "
847                                                 "reverted to sip:\n",
848                                                 uri.type);
849                                         len=s_sip.len;
850                                         tmp=s_sip.s;
851                                 }
852                                 if(crt+len+1 /* colon */ >end) goto error_uri;
853                                 memcpy(crt,tmp,len);crt+=len;
854                                 *crt=':'; crt++;
855
856                                 /* user */
857
858                                 /* prefix (-jiri) */
859                                 if (a->type==PREFIX_T) {
860                                         tmp=a->val[0].u.string;
861                                         len=strlen(tmp); if(crt+len>end) goto error_uri;
862                                         memcpy(crt,tmp,len);crt+=len;
863                                         /* whatever we had before, with prefix we have username
864                                            now */
865                                         user=1;
866                                 }
867
868                                 if ((a->type==SET_USER_T)||(a->type==SET_USERPASS_T)) {
869                                         tmp=a->val[0].u.string;
870                                         len=strlen(tmp);
871                                 } else if (a->type==STRIP_T) {
872                                         if (a->val[0].u.number>uri.user.len) {
873                                                 LOG(L_WARN, "Error: too long strip asked; "
874                                                                         " deleting username: %lu of <%.*s>\n",
875                                                                         a->val[0].u.number, uri.user.len, uri.user.s );
876                                                 len=0;
877                                         } else if (a->val[0].u.number==uri.user.len) {
878                                                 len=0;
879                                         } else {
880                                                 tmp=uri.user.s + a->val[0].u.number;
881                                                 len=uri.user.len - a->val[0].u.number;
882                                         }
883                                 } else if (a->type==STRIP_TAIL_T) {
884                                         if (a->val[0].u.number>uri.user.len) {
885                                                 LOG(L_WARN, "WARNING: too long strip_tail asked; "
886                                                                         " deleting username: %lu of <%.*s>\n",
887                                                                         a->val[0].u.number, uri.user.len, uri.user.s );
888                                                 len=0;
889                                         } else if (a->val[0].u.number==uri.user.len) {
890                                                 len=0;
891                                         } else {
892                                                 tmp=uri.user.s;
893                                                 len=uri.user.len - a->val[0].u.number;
894                                         }
895                                 } else {
896                                         tmp=uri.user.s;
897                                         len=uri.user.len;
898                                 }
899
900                                 if (len){
901                                         if(crt+len>end) goto error_uri;
902                                         memcpy(crt,tmp,len);crt+=len;
903                                         user=1; /* we have an user field so mark it */
904                                 }
905
906                                 if (a->type==SET_USERPASS_T) tmp=0;
907                                 else tmp=uri.passwd.s;
908                                 /* passwd */
909                                 if (tmp){
910                                         len=uri.passwd.len; if(crt+len+1>end) goto error_uri;
911                                         *crt=':'; crt++;
912                                         memcpy(crt,tmp,len);crt+=len;
913                                 }
914                                 /* tel: URI parameters */
915                                 if ((uri.type==TEL_URI_T)
916                                         || (uri.type==TELS_URI_T)
917                                 ) {
918                                         tmp=uri.params.s;
919                                         if (tmp){
920                                                 len=uri.params.len; if(crt+len+1>end) goto error_uri;
921                                                 *crt=';'; crt++;
922                                                 memcpy(crt,tmp,len);crt+=len;
923                                         }
924                                 }
925                                 /* host */
926                                 if ((a->type==SET_HOST_T)
927                                                 || (a->type==SET_HOSTPORT_T)
928                                                 || (a->type==SET_HOSTALL_T)
929                                                 || (a->type==SET_HOSTPORTTRANS_T)
930                                 ) {
931                                         tmp=a->val[0].u.string;
932                                         if (tmp) len = strlen(tmp);
933                                         else len=0;
934                                 } else if ((uri.type==SIP_URI_T)
935                                         || (uri.type==SIPS_URI_T)
936                                         || (uri.flags & URI_SIP_USER_PHONE)
937                                 ) {
938                                         tmp=uri.host.s;
939                                         len=uri.host.len;
940                                 } else {
941                                         tmp=0;
942                                 }
943                                 if (tmp){
944                                         if (user) { /* add @ */
945                                                 if(crt+1>end) goto error_uri;
946                                                 *crt='@'; crt++;
947                                         }
948                                         if(crt+len>end) goto error_uri;
949                                         memcpy(crt,tmp,len);crt+=len;
950                                 }
951                                 if(a->type==SET_HOSTALL_T)
952                                         goto done_seturi;
953                                 /* port */
954                                 if ((a->type==SET_HOSTPORT_T)
955                                                 || (a->type==SET_HOSTPORTTRANS_T))
956                                         tmp=0;
957                                 else if (a->type==SET_PORT_T) {
958                                         tmp=a->val[0].u.string;
959                                         if (tmp) len = strlen(tmp);
960                                         else len = 0;
961                                 } else {
962                                         tmp=uri.port.s;
963                                         len = uri.port.len;
964                                 }
965                                 if (tmp){
966                                         if(crt+len+1>end) goto error_uri;
967                                         *crt=':'; crt++;
968                                         memcpy(crt,tmp,len);crt+=len;
969                                 }
970                                 /* params */
971                                 if ((a->type==SET_HOSTPORTTRANS_T)
972                                         && uri.sip_params.s
973                                         && uri.transport.s
974                                 ) {
975                                         /* bypass the transport parameter */
976                                         if (uri.sip_params.s < uri.transport.s) {
977                                                 /* there are parameters before transport */
978                                                 len = uri.transport.s - uri.sip_params.s - 1;
979                                                         /* ignore the ';' at the end */
980                                                 if (crt+len+1>end) goto error_uri;
981                                                 *crt=';'; crt++;
982                                                 memcpy(crt,uri.sip_params.s,len);crt+=len;
983                                         }
984                                         len = (uri.sip_params.s + uri.sip_params.len) -
985                                                 (uri.transport.s + uri.transport.len);
986                                         if (len > 0) {
987                                                 /* there are parameters after transport */
988                                                 if (crt+len>end) goto error_uri;
989                                                 tmp = uri.transport.s + uri.transport.len;
990                                                 memcpy(crt,tmp,len);crt+=len;
991                                         }
992                                 } else {
993                                         tmp=uri.sip_params.s;
994                                         if (tmp){
995                                                 len=uri.sip_params.len; if(crt+len+1>end) goto error_uri;
996                                                 *crt=';'; crt++;
997                                                 memcpy(crt,tmp,len);crt+=len;
998                                         }
999                                 }
1000                                 /* Add the user=phone param if a tel: or tels:
1001                                  * URI was converted to sip: or sips:.
1002                                  * (host part of a tel/tels URI was set.)
1003                                  * Or in case of sip: URI and SET_USERPHONE_T action */
1004                                 if (((((uri.type==TEL_URI_T) || (uri.type==TELS_URI_T))
1005                                         && ((uri.flags & URI_SIP_USER_PHONE)==0))
1006                                         && ((a->type==SET_HOST_T)
1007                                                 || (a->type==SET_HOSTPORT_T)
1008                                                 || (a->type==SET_HOSTPORTTRANS_T)))
1009                                         || (a->type==SET_USERPHONE_T)
1010                                 ) {
1011                                         tmp=";user=phone";
1012                                         len=strlen(tmp);
1013                                         if(crt+len>end) goto error_uri;
1014                                         memcpy(crt,tmp,len);crt+=len;
1015                                 }
1016                                 /* headers */
1017                                 tmp=uri.headers.s;
1018                                 if (tmp){
1019                                         len=uri.headers.len; if(crt+len+1>end) goto error_uri;
1020                                         *crt='?'; crt++;
1021                                         memcpy(crt,tmp,len);crt+=len;
1022                                 }
1023         done_seturi:
1024                                 *crt=0; /* null terminate the thing */
1025                                 /* copy it to the msg */
1026                                 if (msg->new_uri.s) pkg_free(msg->new_uri.s);
1027                                 msg->new_uri.s=new_uri;
1028                                 msg->new_uri.len=crt-new_uri;
1029                                 msg->parsed_uri_ok=0;
1030                                 ret=1;
1031                                 break;
1032                 case IF_T:
1033                                         rve=(struct rval_expr*)a->val[0].u.data;
1034                                         if (unlikely(rval_expr_eval_int(h, msg, &v, rve) != 0)){
1035                                                 ERR("if expression evaluation failed (%d,%d-%d,%d)\n",
1036                                                                 rve->fpos.s_line, rve->fpos.s_col,
1037                                                                 rve->fpos.e_line, rve->fpos.e_col);
1038                                                 v=0; /* false */
1039                                         }
1040                                         if (unlikely(h->run_flags & EXIT_R_F)){
1041                                                 ret=0;
1042                                                 break;
1043                                         }
1044                                         h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return &
1045                                                                                                                             break in expr*/
1046                                         ret=1;  /*default is continue */
1047                                         if (v>0) {
1048                                                 if ((a->val[1].type==ACTIONS_ST)&&a->val[1].u.data){
1049                                                         ret=run_actions(h,
1050                                                                                 (struct action*)a->val[1].u.data, msg);
1051                                                 }
1052                                         }else if ((a->val[2].type==ACTIONS_ST)&&a->val[2].u.data){
1053                                                         ret=run_actions(h,
1054                                                                                 (struct action*)a->val[2].u.data, msg);
1055                                         }
1056                         break;
1057                 case MODULE0_T:
1058                         MODF_CALL(cmd_function, h, msg, a->val, 0, 0);
1059                         break;
1060                 /* instead of using the parameter number, we use different names
1061                  * for calls to functions with 3, 4, 5, 6 or variable number of
1062                  * parameters due to performance reasons */
1063                 case MODULE1_T:
1064                         MODF_CALL(cmd_function, h, msg, a->val,
1065                                                                                 (char*)a->val[2].u.data,
1066                                                                                 0
1067                                         );
1068                         break;
1069                 case MODULE2_T:
1070                         MODF_CALL(cmd_function, h, msg, a->val,
1071                                                                                 (char*)a->val[2].u.data,
1072                                                                                 (char*)a->val[3].u.data
1073                                         );
1074                         break;
1075                 case MODULE3_T:
1076                         MODF_CALL(cmd_function3, h, msg, a->val,
1077                                                                                 (char*)a->val[2].u.data,
1078                                                                                 (char*)a->val[3].u.data,
1079                                                                                 (char*)a->val[4].u.data
1080                                         );
1081                         break;
1082                 case MODULE4_T:
1083                         MODF_CALL(cmd_function4, h, msg, a->val,
1084                                                                                 (char*)a->val[2].u.data,
1085                                                                                 (char*)a->val[3].u.data,
1086                                                                                 (char*)a->val[4].u.data,
1087                                                                                 (char*)a->val[5].u.data
1088                                         );
1089                         break;
1090                 case MODULE5_T:
1091                         MODF_CALL(cmd_function5, h, msg, a->val,
1092                                                                                 (char*)a->val[2].u.data,
1093                                                                                 (char*)a->val[3].u.data,
1094                                                                                 (char*)a->val[4].u.data,
1095                                                                                 (char*)a->val[5].u.data,
1096                                                                                 (char*)a->val[6].u.data
1097                                         );
1098                         break;
1099                 case MODULE6_T:
1100                         MODF_CALL(cmd_function6, h, msg, a->val,
1101                                                                                 (char*)a->val[2].u.data,
1102                                                                                 (char*)a->val[3].u.data,
1103                                                                                 (char*)a->val[4].u.data,
1104                                                                                 (char*)a->val[5].u.data,
1105                                                                                 (char*)a->val[6].u.data,
1106                                                                                 (char*)a->val[7].u.data
1107                                         );
1108                         break;
1109                 case MODULEX_T:
1110                         MODF_CALL(cmd_function_var, h, msg, a->val,
1111                                                         a->val[1].u.number, &a->val[2]);
1112                         break;
1113                 case MODULE1_RVE_T:
1114                         MODF_RVE_CALL(cmd_function, h, msg, a->val, mod_f_params,
1115                                                                                         (char*)mod_f_params[2].u.data,
1116                                                                                         0
1117                                         );
1118                         break;
1119                 case MODULE2_RVE_T:
1120                         MODF_RVE_CALL(cmd_function, h, msg, a->val, mod_f_params,
1121                                                                                         (char*)mod_f_params[2].u.data,
1122                                                                                         (char*)mod_f_params[3].u.data
1123                                         );
1124                         break;
1125                 case MODULE3_RVE_T:
1126                         MODF_RVE_CALL(cmd_function3, h, msg, a->val, mod_f_params,
1127                                                                                         (char*)mod_f_params[2].u.data,
1128                                                                                         (char*)mod_f_params[3].u.data,
1129                                                                                         (char*)mod_f_params[4].u.data
1130                                         );
1131                         break;
1132                 case MODULE4_RVE_T:
1133                         MODF_RVE_CALL(cmd_function4, h, msg, a->val, mod_f_params,
1134                                                                                         (char*)mod_f_params[2].u.data,
1135                                                                                         (char*)mod_f_params[3].u.data,
1136                                                                                         (char*)mod_f_params[4].u.data,
1137                                                                                         (char*)mod_f_params[5].u.data
1138                                         );
1139                         break;
1140                 case MODULE5_RVE_T:
1141                         MODF_RVE_CALL(cmd_function5, h, msg, a->val, mod_f_params,
1142                                                                                         (char*)mod_f_params[2].u.data,
1143                                                                                         (char*)mod_f_params[3].u.data,
1144                                                                                         (char*)mod_f_params[4].u.data,
1145                                                                                         (char*)mod_f_params[5].u.data,
1146                                                                                         (char*)mod_f_params[6].u.data
1147                                         );
1148                         break;
1149                 case MODULE6_RVE_T:
1150                         MODF_RVE_CALL(cmd_function6, h, msg, a->val, mod_f_params,
1151                                                                                         (char*)mod_f_params[2].u.data,
1152                                                                                         (char*)mod_f_params[3].u.data,
1153                                                                                         (char*)mod_f_params[4].u.data,
1154                                                                                         (char*)mod_f_params[5].u.data,
1155                                                                                         (char*)mod_f_params[6].u.data,
1156                                                                                         (char*)mod_f_params[7].u.data
1157                                         );
1158                         break;
1159                 case MODULEX_RVE_T:
1160                         MODF_RVE_CALL(cmd_function_var, h, msg, a->val, mod_f_params,
1161                                                         a->val[1].u.number, &mod_f_params[2]);
1162                         break;
1163                 case EVAL_T:
1164                         /* only eval the expression to account for possible
1165                            side-effect */
1166                         rval_expr_eval_int(h, msg, &v,
1167                                         (struct rval_expr*)a->val[0].u.data);
1168                         if (h->run_flags & EXIT_R_F){
1169                                 ret=0;
1170                                 break;
1171                         }
1172                         h->run_flags &= ~RETURN_R_F|BREAK_R_F; /* catch return & break in
1173                                                                                                           expr */
1174                         ret=1; /* default is continue */
1175                         break;
1176                 case SWITCH_COND_T:
1177                         sct=(struct switch_cond_table*)a->val[1].u.data;
1178                         if (unlikely( rval_expr_eval_int(h, msg, &v,
1179                                                                         (struct rval_expr*)a->val[0].u.data) <0)){
1180                                 /* handle error in expression => use default */
1181                                 ret=-1;
1182                                 goto sw_cond_def;
1183                         }
1184                         if (h->run_flags & EXIT_R_F){
1185                                 ret=0;
1186                                 break;
1187                         }
1188                         h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return & break
1189                                                                                                             in expr */
1190                         ret=1; /* default is continue */
1191                         for(i=0; i<sct->n; i++)
1192                                 if (sct->cond[i]==v){
1193                                         if (likely(sct->jump[i])){
1194                                                 ret=run_actions(h, sct->jump[i], msg);
1195                                                 h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
1196                                                                                                            returns passthrough */
1197                                         }
1198                                         goto skip;
1199                                 }
1200 sw_cond_def:
1201                         if (sct->def){
1202                                 ret=run_actions(h, sct->def, msg);
1203                                 h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
1204                                                                                            returns passthrough */
1205                         }
1206                         break;
1207                 case SWITCH_JT_T:
1208                         sjt=(struct switch_jmp_table*)a->val[1].u.data;
1209                         if (unlikely( rval_expr_eval_int(h, msg, &v,
1210                                                                         (struct rval_expr*)a->val[0].u.data) <0)){
1211                                 /* handle error in expression => use default */
1212                                 ret=-1;
1213                                 goto sw_jt_def;
1214                         }
1215                         if (h->run_flags & EXIT_R_F){
1216                                 ret=0;
1217                                 break;
1218                         }
1219                         h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return & break
1220                                                                                                             in expr */
1221                         ret=1; /* default is continue */
1222                         if (likely(v >= sjt->first && v <= sjt->last)){
1223                                 if (likely(sjt->tbl[v - sjt->first])){
1224                                         ret=run_actions(h, sjt->tbl[v - sjt->first], msg);
1225                                         h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
1226                                                                                                    returns passthrough */
1227                                 }
1228                                 break; 
1229                         }else{
1230                                 for(i=0; i<sjt->rest.n; i++)
1231                                         if (sjt->rest.cond[i]==v){
1232                                                 if (likely(sjt->rest.jump[i])){
1233                                                         ret=run_actions(h, sjt->rest.jump[i], msg);
1234                                                         h->run_flags &= ~BREAK_R_F; /* catch breaks, but 
1235                                                                                                                    let returns pass */
1236                                                 }
1237                                                 goto skip;
1238                                         }
1239                         }
1240                         /* not found => try default */
1241 sw_jt_def:
1242                         if (sjt->rest.def){
1243                                 ret=run_actions(h, sjt->rest.def, msg);
1244                                 h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
1245                                                                                            returns passthrough */
1246                         }
1247                         break;
1248                 case BLOCK_T:
1249                         if (likely(a->val[0].u.data)){
1250                                 ret=run_actions(h, (struct action*)a->val[0].u.data, msg);
1251                                 h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
1252                                                                                            returns passthrough */
1253                         }
1254                         break;
1255                 case MATCH_COND_T:
1256                         mct=(struct match_cond_table*)a->val[1].u.data;
1257                         rval_cache_init(&c1);
1258                         rv=0;
1259                         rv1=0;
1260                         ret=rval_expr_eval_rvint(h, msg, &rv, &v, 
1261                                                                         (struct rval_expr*)a->val[0].u.data, &c1);
1262                                                                         
1263                         if (unlikely( ret<0)){
1264                                 /* handle error in expression => use default */
1265                                 ret=-1;
1266                                 goto match_cond_def;
1267                         }
1268                         if (h->run_flags & EXIT_R_F){
1269                                 ret=0;
1270                                 break;
1271                         }
1272                         h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return & break
1273                                                                                                             in expr */
1274                         if (likely(rv)){
1275                                 rv1=rval_convert(h, msg, RV_STR, rv, &c1);
1276                                 if (unlikely(rv1==0)){
1277                                         ret=-1;
1278                                         goto match_cond_def;
1279                                 }
1280                                 s=rv1->v.s;
1281                         }else{
1282                                 /* int result in v */
1283                                 rval_cache_clean(&c1);
1284                                 s.s=sint2str(v, &s.len);
1285                         }
1286                         ret=1; /* default is continue */
1287                         for(i=0; i<mct->n; i++)
1288                                 if (( mct->match[i].type==MATCH_STR &&
1289                                                 mct->match[i].l.s.len==s.len &&
1290                                                 memcmp(mct->match[i].l.s.s, s.s, s.len) == 0 ) ||
1291                                          ( mct->match[i].type==MATCH_RE &&
1292                                           regexec(mct->match[i].l.regex, s.s, 0, 0, 0) == 0)
1293                                         ){
1294                                         if (likely(mct->jump[i])){
1295                                                 ret=run_actions(h, mct->jump[i], msg);
1296                                                 h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
1297                                                                                                            returns passthrough */
1298                                         }
1299                                         goto match_cleanup;
1300                                 }
1301 match_cond_def:
1302                         if (mct->def){
1303                                 ret=run_actions(h, mct->def, msg);
1304                                 h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
1305                                                                                            returns passthrough */
1306                         }
1307 match_cleanup:
1308                         if (rv1){
1309                                 rval_destroy(rv1);
1310                                 rval_destroy(rv);
1311                                 rval_cache_clean(&c1);
1312                         }else if (rv){
1313                                 rval_destroy(rv);
1314                                 rval_cache_clean(&c1);
1315                         }
1316                         break;
1317                 case WHILE_T:
1318                         i=0;
1319                         flags=0;
1320                         rve=(struct rval_expr*)a->val[0].u.data;
1321                         ret=1;
1322                         while(!(flags & BREAK_R_F) && 
1323                                         (rval_expr_eval_int(h, msg, &v, rve) == 0) && v){
1324                                 i++;
1325                                 if (unlikely(i > cfg_get(core, core_cfg, max_while_loops))){
1326                                         LOG(L_ERR, "ERROR: runaway while (%d, %d): more then"
1327                                                                 " %d loops\n", 
1328                                                                 rve->fpos.s_line, rve->fpos.s_col,
1329                                                                 cfg_get(core, core_cfg, max_while_loops));
1330                                         ret=-1;
1331                                         goto error;
1332                                 }
1333                                 if (likely(a->val[1].u.data)){
1334                                         ret=run_actions(h, (struct action*)a->val[1].u.data, msg);
1335                                         flags|=h->run_flags;
1336                                         h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
1337                                                                                                    returns passthrough */
1338                                 }
1339                         }
1340                         break;
1341                 case FORCE_RPORT_T:
1342                         msg->msg_flags|=FL_FORCE_RPORT;
1343                         ret=1; /* continue processing */
1344                         break;
1345                 case ADD_LOCAL_RPORT_T:
1346                         msg->msg_flags|=FL_ADD_LOCAL_RPORT;
1347                         ret=1; /* continue processing */
1348                         break;
1349                 case UDP_MTU_TRY_PROTO_T:
1350                         msg->msg_flags|= (unsigned int)a->val[0].u.number & FL_MTU_FB_MASK;
1351                         ret=1; /* continue processing */
1352                         break;
1353                 case SET_ADV_ADDR_T:
1354                         if (a->val[0].type!=STR_ST){
1355                                 LOG(L_CRIT, "BUG: do_action: bad set_advertised_address() "
1356                                                 "type %d\n", a->val[0].type);
1357                                 ret=E_BUG;
1358                                 goto error;
1359                         }
1360                         msg->set_global_address=*((str*)a->val[0].u.data);
1361                         ret=1; /* continue processing */
1362                         break;
1363                 case SET_ADV_PORT_T:
1364                         if (a->val[0].type!=STR_ST){
1365                                 LOG(L_CRIT, "BUG: do_action: bad set_advertised_port() "
1366                                                 "type %d\n", a->val[0].type);
1367                                 ret=E_BUG;
1368                                 goto error;
1369                         }
1370                         msg->set_global_port=*((str*)a->val[0].u.data);
1371                         ret=1; /* continue processing */
1372                         break;
1373 #ifdef USE_TCP
1374                 case FORCE_TCP_ALIAS_T:
1375                         if ( msg->rcv.proto==PROTO_TCP
1376 #ifdef USE_TLS
1377                                         || msg->rcv.proto==PROTO_TLS
1378 #endif
1379                            ){
1380
1381                                 if (a->val[0].type==NOSUBTYPE)  port=msg->via1->port;
1382                                 else if (a->val[0].type==NUMBER_ST) port=(int)a->val[0].u.number;
1383                                 else{
1384                                         LOG(L_CRIT, "BUG: do_action: bad force_tcp_alias"
1385                                                         " port type %d\n", a->val[0].type);
1386                                         ret=E_BUG;
1387                                         goto error;
1388                                 }
1389
1390                                 if (tcpconn_add_alias(msg->rcv.proto_reserved1, port,
1391                                                                         msg->rcv.proto)!=0){
1392                                         LOG(L_ERR, " ERROR: receive_msg: tcp alias failed\n");
1393                                         ret=E_UNSPEC;
1394                                         goto error;
1395                                 }
1396                         }
1397 #endif
1398                         ret=1; /* continue processing */
1399                         break;
1400                 case FORCE_SEND_SOCKET_T:
1401                         if (a->val[0].type!=SOCKETINFO_ST){
1402                                 LOG(L_CRIT, "BUG: do_action: bad force_send_socket argument"
1403                                                 " type: %d\n", a->val[0].type);
1404                                 ret=E_BUG;
1405                                 goto error;
1406                         }
1407                         set_force_socket(msg, (struct socket_info*)a->val[0].u.data);
1408                         ret=1; /* continue processing */
1409                         break;
1410
1411                 case ADD_T:
1412                 case ASSIGN_T:
1413                         v=lval_assign(h, msg, (struct lvalue*)a->val[0].u.data,
1414                                                                   (struct rval_expr*)a->val[1].u.data);
1415                         if (likely(v>=0))
1416                                 ret = 1;
1417                         else if (unlikely (v == EXPR_DROP)) /* hack to quit on DROP*/
1418                                 ret=0;
1419                         else
1420                                 ret=v;
1421                         break;
1422                 case SET_FWD_NO_CONNECT_T:
1423                         msg->fwd_send_flags.f|= SND_F_FORCE_CON_REUSE;
1424                         ret=1; /* continue processing */
1425                         break;
1426                 case SET_RPL_NO_CONNECT_T:
1427                         msg->rpl_send_flags.f|= SND_F_FORCE_CON_REUSE;
1428                         ret=1; /* continue processing */
1429                         break;
1430                 case SET_FWD_CLOSE_T:
1431                         msg->fwd_send_flags.f|= SND_F_CON_CLOSE;
1432                         ret=1; /* continue processing */
1433                         break;
1434                 case SET_RPL_CLOSE_T:
1435                         msg->rpl_send_flags.f|= SND_F_CON_CLOSE;
1436                         ret=1; /* continue processing */
1437                         break;
1438 /*
1439                 default:
1440                         LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
1441 */
1442         }
1443 skip:
1444         return ret;
1445
1446 error_uri:
1447         LOG(L_ERR, "ERROR: do_action: set*: uri too long\n");
1448         if (new_uri) pkg_free(new_uri);
1449         LM_ERR("run action error at: %s:%d\n", (a->cfile)?a->cfile:"", a->cline);
1450         return E_UNSPEC;
1451 error_fwd_uri:
1452         /*free_uri(&uri); -- not needed anymore, using msg->parsed_uri*/
1453 error:
1454         LM_ERR("run action error at: %s:%d\n", (a->cfile)?a->cfile:"", a->cline);
1455         return ret;
1456 }
1457
1458
1459
1460 /* returns: 0, or 1 on success, <0 on error */
1461 /* (0 if drop or break encountered, 1 if not ) */
1462 int run_actions(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
1463 {
1464         struct action* t;
1465         int ret;
1466         struct sr_module *mod;
1467
1468         ret=E_UNSPEC;
1469         h->rec_lev++;
1470         if (h->rec_lev>ROUTE_MAX_REC_LEV){
1471                 LOG(L_ERR, "WARNING: too many recursive routing table lookups (%d)"
1472                                         " giving up!\n", h->rec_lev);
1473                 ret=E_UNSPEC;
1474                 goto error;
1475         }
1476         if (h->rec_lev==1){
1477                 h->run_flags=0;
1478                 h->last_retcode=0;
1479                 _last_returned_code = h->last_retcode;
1480 #ifdef USE_LONGJMP
1481                 if (setjmp(h->jmp_env)){
1482                         h->rec_lev=0;
1483                         ret=h->last_retcode;
1484                         goto end;
1485                 }
1486 #endif
1487         }
1488
1489         if (a==0){
1490                 DBG("DEBUG: run_actions: null action list (rec_level=%d)\n",
1491                                 h->rec_lev);
1492                 ret=1;
1493         }
1494
1495         for (t=a; t!=0; t=t->next){
1496                 ret=do_action(h, t, msg);
1497                 /* break, return or drop/exit stop execution of the current
1498                    block */
1499                 if (h->run_flags & (BREAK_R_F|RETURN_R_F|EXIT_R_F)){
1500                         if (h->run_flags & EXIT_R_F){
1501 #ifdef USE_LONGJMP
1502                                 h->last_retcode=ret;
1503                                 _last_returned_code = h->last_retcode;
1504                                 longjmp(h->jmp_env, ret);
1505 #endif
1506                         }
1507                         break;
1508                 }
1509                 /* ignore error returns */
1510         }
1511
1512         h->rec_lev--;
1513 end:
1514         /* process module onbreak handlers if present */
1515         if (h->rec_lev==0 && ret==0)
1516                 for (mod=modules;mod;mod=mod->next)
1517                         if (mod->exports.onbreak_f) {
1518                                 mod->exports.onbreak_f( msg );
1519                                 DBG("DEBUG: %s onbreak handler called\n", mod->exports.name);
1520                         }
1521         return ret;
1522
1523
1524 error:
1525         h->rec_lev--;
1526         return ret;
1527 }
1528
1529
1530 int run_top_route(struct action* a, sip_msg_t* msg, struct run_act_ctx *c)
1531 {
1532         struct run_act_ctx ctx;
1533         struct run_act_ctx *p;
1534         int ret;
1535         flag_t sfbk;
1536
1537         p = (c)?c:&ctx;
1538         sfbk = getsflags();
1539         setsflagsval(0);
1540         reset_static_buffer();
1541         init_run_actions_ctx(p);
1542         ret = run_actions(p, a, msg);
1543         setsflagsval(sfbk);
1544         return ret;
1545 }