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