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