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