Support for auto_inv_100_reason tm parameter.
[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  */
53
54
55 #include "comp_defs.h"
56
57 #include "action.h"
58 #include "config.h"
59 #include "error.h"
60 #include "dprint.h"
61 #include "proxy.h"
62 #include "forward.h"
63 #include "udp_server.h"
64 #include "route.h"
65 #include "parser/msg_parser.h"
66 #include "parser/parse_uri.h"
67 #include "ut.h"
68 #include "lvalue.h"
69 #include "sr_module.h"
70 #include "mem/mem.h"
71 #include "globals.h"
72 #include "dset.h"
73 #include "onsend.h"
74 #include "resolve.h"
75 #ifdef USE_TCP
76 #include "tcp_server.h"
77 #endif
78 #ifdef USE_SCTP
79 #include "sctp_server.h"
80 #endif
81 #include "switch.h"
82
83 #include <sys/types.h>
84 #include <sys/socket.h>
85 #include <netdb.h>
86 #include <stdlib.h>
87 #include <netinet/in.h>
88 #include <arpa/inet.h>
89 #include <string.h>
90
91
92 #ifdef DEBUG_DMALLOC
93 #include <dmalloc.h>
94 #endif
95
96
97 struct onsend_info* p_onsend=0; /* onsend route send info */
98
99 /* ret= 0! if action -> end of list(e.g DROP),
100       > 0 to continue processing next actions
101    and <0 on error */
102 int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
103 {
104         int ret;
105         int v;
106         struct dest_info dst;
107         char* tmp;
108         char *new_uri, *end, *crt;
109         void* f;
110         int len;
111         int user;
112         struct sip_uri uri, next_hop;
113         struct sip_uri *u;
114         unsigned short port;
115         str* dst_host;
116         int i, flags;
117         struct switch_cond_table* sct;
118         struct switch_jmp_table*  sjt;
119         struct rval_expr* rve;
120         struct match_cond_table* mct;
121         struct rvalue* rv;
122         struct rvalue* rv1;
123         struct rval_cache c1;
124         str s;
125
126
127         /* reset the value of error to E_UNSPEC so avoid unknowledgable
128            functions to return with error (status<0) and not setting it
129            leaving there previous error; cache the previous value though
130            for functions which want to process it */
131         prev_ser_error=ser_error;
132         ser_error=E_UNSPEC;
133
134         ret=E_BUG;
135         switch ((unsigned char)a->type){
136                 case DROP_T:
137                                 if (a->val[0].type==RETCODE_ST)
138                                         ret=h->last_retcode;
139                                 else
140                                         ret=(int) a->val[0].u.number;
141                                 h->run_flags|=(unsigned int)a->val[1].u.number;
142                         break;
143                 case FORWARD_T:
144 #ifdef USE_TCP
145                 case FORWARD_TCP_T:
146 #endif
147 #ifdef USE_TLS
148                 case FORWARD_TLS_T:
149 #endif
150 #ifdef USE_SCTP
151                 case FORWARD_SCTP_T:
152 #endif
153                 case FORWARD_UDP_T:
154                         /* init dst */
155                         init_dest_info(&dst);
156                         if (a->type==FORWARD_UDP_T) dst.proto=PROTO_UDP;
157 #ifdef USE_TCP
158                         else if (a->type==FORWARD_TCP_T) dst.proto= PROTO_TCP;
159 #endif
160 #ifdef USE_TLS
161                         else if (a->type==FORWARD_TLS_T) dst.proto= PROTO_TLS;
162 #endif
163 #ifdef USE_SCTP
164                         else if (a->type==FORWARD_SCTP_T) dst.proto=PROTO_SCTP;
165 #endif
166                         else dst.proto=PROTO_NONE;
167                         if (a->val[0].type==URIHOST_ST){
168                                 /*parse uri*/
169
170                                 if (msg->dst_uri.len) {
171                                         ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len,
172                                                                         &next_hop);
173                                         u = &next_hop;
174                                 } else {
175                                         ret = parse_sip_msg_uri(msg);
176                                         u = &msg->parsed_uri;
177                                 }
178
179                                 if (ret<0) {
180                                         LOG(L_ERR, "ERROR: do_action: forward: bad_uri "
181                                                                 " dropping packet\n");
182                                         break;
183                                 }
184
185                                 switch (a->val[1].type){
186                                         case URIPORT_ST:
187                                                                         port=u->port_no;
188                                                                         break;
189                                         case NUMBER_ST:
190                                                                         port=a->val[1].u.number;
191                                                                         break;
192                                         default:
193                                                         LOG(L_CRIT, "BUG: do_action bad forward 2nd"
194                                                                                 " param type (%d)\n", a->val[1].type);
195                                                         ret=E_UNSPEC;
196                                                         goto error_fwd_uri;
197                                 }
198                                 if (dst.proto == PROTO_NONE){ /* only if proto not set get it
199                                                                                          from the uri */
200                                         switch(u->proto){
201                                                 case PROTO_NONE:
202                                                         /*dst.proto=PROTO_UDP; */
203                                                         /* no proto, try to get it from the dns */
204                                                         break;
205                                                 case PROTO_UDP:
206 #ifdef USE_TCP
207                                                 case PROTO_TCP:
208 #endif
209 #ifdef USE_TLS
210                                                 case PROTO_TLS:
211 #endif
212 #ifdef USE_SCTP
213                                                 case PROTO_SCTP:
214 #endif
215                                                         dst.proto=u->proto;
216                                                         break;
217                                                 default:
218                                                         LOG(L_ERR,"ERROR: do action: forward: bad uri"
219                                                                         " transport %d\n", u->proto);
220                                                         ret=E_BAD_PROTO;
221                                                         goto error_fwd_uri;
222                                         }
223 #ifdef USE_TLS
224                                         if (u->type==SIPS_URI_T){
225                                                 if (u->proto==PROTO_UDP){
226                                                         LOG(L_ERR, "ERROR: do_action: forward: secure uri"
227                                                                         " incompatible with transport %d\n",
228                                                                         u->proto);
229                                                         ret=E_BAD_PROTO;
230                                                         goto error_fwd_uri;
231                                                 }
232                                                 dst.proto=PROTO_TLS;
233                                         }
234 #endif
235                                 }
236
237 #ifdef HONOR_MADDR
238                                 if (u->maddr_val.s && u->maddr_val.len)
239                                         dst_host=&u->maddr_val;
240                                 else
241 #endif
242                                         dst_host=&u->host;
243 #ifdef USE_COMP
244                                 dst.comp=u->comp;
245 #endif
246                                 ret=forward_request(msg, dst_host, port, &dst);
247                                 if (ret>=0){
248                                         ret=1;
249                                 }
250                         }else if ((a->val[0].type==PROXY_ST) && (a->val[1].type==NUMBER_ST)){
251                                 if (dst.proto==PROTO_NONE)
252                                         dst.proto=msg->rcv.proto;
253                                 proxy2su(&dst.to,  (struct proxy_l*)a->val[0].u.data);
254                                 ret=forward_request(msg, 0, 0, &dst);
255                                 if (ret>=0){
256                                         ret=1;
257                                         proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
258                                 }else if (ser_error!=E_OK){
259                                         proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
260                                 }
261                         }else{
262                                 LOG(L_CRIT, "BUG: do_action: bad forward() types %d, %d\n",
263                                                 a->val[0].type, a->val[1].type);
264                                 ret=E_BUG;
265                         }
266                         break;
267                 case SEND_T:
268                 case SEND_TCP_T:
269                         if ((a->val[0].type!= PROXY_ST)|(a->val[1].type!=NUMBER_ST)){
270                                 LOG(L_CRIT, "BUG: do_action: bad send() types %d, %d\n",
271                                                 a->val[0].type, a->val[1].type);
272                                 ret=E_BUG;
273                                 break;
274                         }
275                         /* init dst */
276                         init_dest_info(&dst);
277                         ret=proxy2su(&dst.to,  (struct proxy_l*)a->val[0].u.data);
278                         if (ret==0){
279                                 if (p_onsend){
280                                         tmp=p_onsend->buf;
281                                         len=p_onsend->len;
282                                 }else{
283                                         tmp=msg->buf;
284                                         len=msg->len;
285                                 }
286                                 if (a->type==SEND_T){
287                                         /*udp*/
288                                         dst.proto=PROTO_UDP; /* not really needed for udp_send */
289                                         dst.send_sock=get_send_socket(msg, &dst.to, PROTO_UDP);
290                                         if (dst.send_sock!=0){
291                                                 ret=udp_send(&dst, tmp, len);
292                                         }else{
293                                                 ret=-1;
294                                         }
295                                 }
296 #ifdef USE_TCP
297                                         else{
298                                                 /*tcp*/
299                                                 dst.proto=PROTO_TCP;
300                                                 dst.id=0;
301                                                 ret=tcp_send(&dst, 0, tmp, len);
302                                 }
303 #endif
304                         }else{
305                                 ret=E_BUG;
306                                 break;
307                         }
308                         proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
309                         if (ret>=0) ret=1;
310
311                         break;
312                 case LOG_T:
313                         if ((a->val[0].type!=NUMBER_ST)|(a->val[1].type!=STRING_ST)){
314                                 LOG(L_CRIT, "BUG: do_action: bad log() types %d, %d\n",
315                                                 a->val[0].type, a->val[1].type);
316                                 ret=E_BUG;
317                                 break;
318                         }
319                         LOG_(DEFAULT_FACILITY, a->val[0].u.number, "<script>: ", "%s", 
320                                  a->val[1].u.string);
321                         ret=1;
322                         break;
323
324                 /* jku -- introduce a new branch */
325                 case APPEND_BRANCH_T:
326                         if ((a->val[0].type!=STRING_ST)) {
327                                 LOG(L_CRIT, "BUG: do_action: bad append_branch_t %d\n",
328                                         a->val[0].type );
329                                 ret=E_BUG;
330                                 break;
331                         }
332                         ret=append_branch( msg, a->val[0].u.string,
333                                            a->val[0].u.string ? strlen(a->val[0].u.string):0,
334                                            0, 0, a->val[1].u.number, 0);
335                         break;
336
337                 /* jku begin: is_length_greater_than */
338                 case LEN_GT_T:
339                         if (a->val[0].type!=NUMBER_ST) {
340                                 LOG(L_CRIT, "BUG: do_action: bad len_gt type %d\n",
341                                         a->val[0].type );
342                                 ret=E_BUG;
343                                 break;
344                         }
345                         /* DBG("XXX: message length %d, max %d\n",
346                                 msg->len, a->val[0].u.number ); */
347                         ret = msg->len >= a->val[0].u.number ? 1 : -1;
348                         break;
349                 /* jku end: is_length_greater_than */
350
351                 /* jku - begin : flag processing */
352
353                 case SETFLAG_T:
354                         if (a->val[0].type!=NUMBER_ST) {
355                                 LOG(L_CRIT, "BUG: do_action: bad setflag() type %d\n",
356                                         a->val[0].type );
357                                 ret=E_BUG;
358                                 break;
359                         }
360                         if (!flag_in_range( a->val[0].u.number )) {
361                                 ret=E_CFG;
362                                 break;
363                         }
364                         setflag( msg, a->val[0].u.number );
365                         ret=1;
366                         break;
367
368                 case RESETFLAG_T:
369                         if (a->val[0].type!=NUMBER_ST) {
370                                 LOG(L_CRIT, "BUG: do_action: bad resetflag() type %d\n",
371                                         a->val[0].type );
372                                 ret=E_BUG;
373                                 break;
374                         }
375                         if (!flag_in_range( a->val[0].u.number )) {
376                                 ret=E_CFG;
377                                 break;
378                         }
379                         resetflag( msg, a->val[0].u.number );
380                         ret=1;
381                         break;
382
383                 case ISFLAGSET_T:
384                         if (a->val[0].type!=NUMBER_ST) {
385                                 LOG(L_CRIT, "BUG: do_action: bad isflagset() type %d\n",
386                                         a->val[0].type );
387                                 ret=E_BUG;
388                                 break;
389                         }
390                         if (!flag_in_range( a->val[0].u.number )) {
391                                 ret=E_CFG;
392                                 break;
393                         }
394                         ret=isflagset( msg, a->val[0].u.number );
395                         break;
396                 /* jku - end : flag processing */
397
398                 case AVPFLAG_OPER_T:  {
399                         struct search_state st;
400                         avp_t* avp;
401                         int flag;
402                         ret = 0;
403                         flag = a->val[1].u.number;
404                         if ((a->val[0].u.attr->type & AVP_INDEX_ALL) == AVP_INDEX_ALL || (a->val[0].u.attr->type & AVP_NAME_RE)!=0) {
405                                 for (avp=search_first_avp(a->val[0].u.attr->type, a->val[0].u.attr->name, NULL, &st); avp; avp = search_next_avp(&st, NULL)) {
406                                         switch (a->val[2].u.number) {   /* oper: 0..reset, 1..set, -1..no change */
407                                                 case 0:
408                                                         avp->flags &= ~(avp_flags_t)a->val[1].u.number;
409                                                         break;
410                                                 case 1:
411                                                         avp->flags |= (avp_flags_t)a->val[1].u.number;
412                                                         break;
413                                                 default:;
414                                         }
415                                         ret = ret || ((avp->flags & (avp_flags_t)a->val[1].u.number) != 0);
416                                 }
417                         }
418                         else {
419                                 avp = search_avp_by_index(a->val[0].u.attr->type, a->val[0].u.attr->name, NULL, a->val[0].u.attr->index);
420                                 if (avp) {
421                                         switch (a->val[2].u.number) {   /* oper: 0..reset, 1..set, -1..no change */
422                                                 case 0:
423                                                         avp->flags &= ~(avp_flags_t)a->val[1].u.number;
424                                                         break;
425                                                 case 1:
426                                                         avp->flags |= (avp_flags_t)a->val[1].u.number;
427                                                         break;
428                                                 default:;
429                                         }
430                                         ret = (avp->flags & (avp_flags_t)a->val[1].u.number) != 0;
431                                 }
432                         }
433                         if (ret==0)
434                                 ret = -1;
435                         break;
436                 }
437                 case ERROR_T:
438                         if ((a->val[0].type!=STRING_ST)|(a->val[1].type!=STRING_ST)){
439                                 LOG(L_CRIT, "BUG: do_action: bad error() types %d, %d\n",
440                                                 a->val[0].type, a->val[1].type);
441                                 ret=E_BUG;
442                                 break;
443                         }
444                         LOG(L_NOTICE, "WARNING: do_action: error(\"%s\", \"%s\") "
445                                         "not implemented yet\n", a->val[0].u.string, a->val[1].u.string);
446                         ret=1;
447                         break;
448                 case ROUTE_T:
449                         if (a->val[0].type!=NUMBER_ST){
450                                 LOG(L_CRIT, "BUG: do_action: bad route() type %d\n",
451                                                 a->val[0].type);
452                                 ret=E_BUG;
453                                 break;
454                         }
455                         if ((a->val[0].u.number>=main_rt.idx)||(a->val[0].u.number<0)){
456                                 LOG(L_ERR, "ERROR: invalid routing table number in"
457                                                         "route(%lu)\n", a->val[0].u.number);
458                                 ret=E_CFG;
459                                 break;
460                         }
461                         /*ret=((ret=run_actions(rlist[a->val[0].u.number], msg))<0)?ret:1;*/
462                         ret=run_actions(h, main_rt.rlist[a->val[0].u.number], msg);
463                         h->last_retcode=ret;
464                         h->run_flags&=~(RETURN_R_F|BREAK_R_F); /* absorb return & break */
465                         break;
466                 case EXEC_T:
467                         if (a->val[0].type!=STRING_ST){
468                                 LOG(L_CRIT, "BUG: do_action: bad exec() type %d\n",
469                                                 a->val[0].type);
470                                 ret=E_BUG;
471                                 break;
472                         }
473                         LOG(L_NOTICE, "WARNING: exec(\"%s\") not fully implemented,"
474                                                 " using dumb version...\n", a->val[0].u.string);
475                         ret=system(a->val[0].u.string);
476                         if (ret!=0){
477                                 LOG(L_NOTICE, "WARNING: exec() returned %d\n", ret);
478                         }
479                         ret=1;
480                         break;
481                 case REVERT_URI_T:
482                         if (msg->new_uri.s) {
483                                 pkg_free(msg->new_uri.s);
484                                 msg->new_uri.len=0;
485                                 msg->new_uri.s=0;
486                                 msg->parsed_uri_ok=0; /* invalidate current parsed uri*/
487                         };
488                         ret=1;
489                         break;
490                 case SET_HOST_T:
491                 case SET_HOSTPORT_T:
492                 case SET_HOSTPORTTRANS_T:
493                 case SET_HOSTALL_T:
494                 case SET_USER_T:
495                 case SET_USERPASS_T:
496                 case SET_PORT_T:
497                 case SET_URI_T:
498                 case PREFIX_T:
499                 case STRIP_T:
500                 case STRIP_TAIL_T:
501                                 user=0;
502                                 if (a->type==STRIP_T || a->type==STRIP_TAIL_T) {
503                                         if (a->val[0].type!=NUMBER_ST) {
504                                                 LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
505                                                         a->val[0].type);
506                                                 break;
507                                         }
508                                 } else if (a->val[0].type!=STRING_ST){
509                                         LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
510                                                         a->val[0].type);
511                                         ret=E_BUG;
512                                         break;
513                                 }
514                                 if (a->type==SET_URI_T){
515                                         if (msg->new_uri.s) {
516                                                         pkg_free(msg->new_uri.s);
517                                                         msg->new_uri.len=0;
518                                         }
519                                         msg->parsed_uri_ok=0;
520                                         len=strlen(a->val[0].u.string);
521                                         msg->new_uri.s=pkg_malloc(len+1);
522                                         if (msg->new_uri.s==0){
523                                                 LOG(L_ERR, "ERROR: do_action: memory allocation"
524                                                                 " failure\n");
525                                                 ret=E_OUT_OF_MEM;
526                                                 break;
527                                         }
528                                         memcpy(msg->new_uri.s, a->val[0].u.string, len);
529                                         msg->new_uri.s[len]=0;
530                                         msg->new_uri.len=len;
531
532                                         ret=1;
533                                         break;
534                                 }
535                                 if (msg->parsed_uri_ok==0) {
536                                         if (msg->new_uri.s) {
537                                                 tmp=msg->new_uri.s;
538                                                 len=msg->new_uri.len;
539                                         }else{
540                                                 tmp=msg->first_line.u.request.uri.s;
541                                                 len=msg->first_line.u.request.uri.len;
542                                         }
543                                         if (parse_uri(tmp, len, &uri)<0){
544                                                 LOG(L_ERR, "ERROR: do_action: bad uri <%s>, dropping"
545                                                                         " packet\n", tmp);
546                                                 ret=E_UNSPEC;
547                                                 break;
548                                         }
549                                 } else {
550                                         uri=msg->parsed_uri;
551                                 }
552
553                                 new_uri=pkg_malloc(MAX_URI_SIZE);
554                                 if (new_uri==0){
555                                         LOG(L_ERR, "ERROR: do_action: memory allocation "
556                                                                 " failure\n");
557                                         ret=E_OUT_OF_MEM;
558                                         break;
559                                 }
560                                 end=new_uri+MAX_URI_SIZE;
561                                 crt=new_uri;
562                                 /* begin copying */
563                                 len=strlen("sip:"); if(crt+len>end) goto error_uri;
564                                 memcpy(crt,"sip:",len);crt+=len;
565
566                                 /* user */
567
568                                 /* prefix (-jiri) */
569                                 if (a->type==PREFIX_T) {
570                                         tmp=a->val[0].u.string;
571                                         len=strlen(tmp); if(crt+len>end) goto error_uri;
572                                         memcpy(crt,tmp,len);crt+=len;
573                                         /* whatever we had before, with prefix we have username
574                                            now */
575                                         user=1;
576                                 }
577
578                                 if ((a->type==SET_USER_T)||(a->type==SET_USERPASS_T)) {
579                                         tmp=a->val[0].u.string;
580                                         len=strlen(tmp);
581                                 } else if (a->type==STRIP_T) {
582                                         if (a->val[0].u.number>uri.user.len) {
583                                                 LOG(L_WARN, "Error: too long strip asked; "
584                                                                         " deleting username: %lu of <%.*s>\n",
585                                                                         a->val[0].u.number, uri.user.len, uri.user.s );
586                                                 len=0;
587                                         } else if (a->val[0].u.number==uri.user.len) {
588                                                 len=0;
589                                         } else {
590                                                 tmp=uri.user.s + a->val[0].u.number;
591                                                 len=uri.user.len - a->val[0].u.number;
592                                         }
593                                 } else if (a->type==STRIP_TAIL_T) {
594                                         if (a->val[0].u.number>uri.user.len) {
595                                                 LOG(L_WARN, "WARNING: too long strip_tail asked; "
596                                                                         " deleting username: %lu of <%.*s>\n",
597                                                                         a->val[0].u.number, uri.user.len, uri.user.s );
598                                                 len=0;
599                                         } else if (a->val[0].u.number==uri.user.len) {
600                                                 len=0;
601                                         } else {
602                                                 tmp=uri.user.s;
603                                                 len=uri.user.len - a->val[0].u.number;
604                                         }
605                                 } else {
606                                         tmp=uri.user.s;
607                                         len=uri.user.len;
608                                 }
609
610                                 if (len){
611                                         if(crt+len>end) goto error_uri;
612                                         memcpy(crt,tmp,len);crt+=len;
613                                         user=1; /* we have an user field so mark it */
614                                 }
615
616                                 if (a->type==SET_USERPASS_T) tmp=0;
617                                 else tmp=uri.passwd.s;
618                                 /* passwd */
619                                 if (tmp){
620                                         len=uri.passwd.len; if(crt+len+1>end) goto error_uri;
621                                         *crt=':'; crt++;
622                                         memcpy(crt,tmp,len);crt+=len;
623                                 }
624                                 /* host */
625                                 if (user || tmp){ /* add @ */
626                                         if(crt+1>end) goto error_uri;
627                                         *crt='@'; crt++;
628                                 }
629                                 if ((a->type==SET_HOST_T)
630                                                 || (a->type==SET_HOSTPORT_T)
631                                                 || (a->type==SET_HOSTALL_T)
632                                                 || (a->type==SET_HOSTPORTTRANS_T)) {
633                                         tmp=a->val[0].u.string;
634                                         if (tmp) len = strlen(tmp);
635                                         else len=0;
636                                 } else {
637                                         tmp=uri.host.s;
638                                         len = uri.host.len;
639                                 }
640                                 if (tmp){
641                                         if(crt+len>end) goto error_uri;
642                                         memcpy(crt,tmp,len);crt+=len;
643                                 }
644                                 if(a->type==SET_HOSTALL_T)
645                                         goto done_seturi;
646                                 /* port */
647                                 if ((a->type==SET_HOSTPORT_T)
648                                                 || (a->type==SET_HOSTPORTTRANS_T))
649                                         tmp=0;
650                                 else if (a->type==SET_PORT_T) {
651                                         tmp=a->val[0].u.string;
652                                         if (tmp) len = strlen(tmp);
653                                         else len = 0;
654                                 } else {
655                                         tmp=uri.port.s;
656                                         len = uri.port.len;
657                                 }
658                                 if (tmp){
659                                         if(crt+len+1>end) goto error_uri;
660                                         *crt=':'; crt++;
661                                         memcpy(crt,tmp,len);crt+=len;
662                                 }
663                                 /* params */
664                                 if ((a->type==SET_HOSTPORTTRANS_T) && uri.transport.s) {
665                                         /* bypass the transport parameter */
666                                         if (uri.params.s < uri.transport.s) {
667                                                 /* there are parameters before transport */
668                                                 len = uri.transport.s - uri.params.s - 1;
669                                                         /* ignore the ';' at the end */
670                                                 if (crt+len+1>end) goto error_uri;
671                                                 *crt=';'; crt++;
672                                                 memcpy(crt,uri.params.s,len);crt+=len;
673                                         }
674                                         len = (uri.params.s + uri.params.len) -
675                                                 (uri.transport.s + uri.transport.len);
676                                         if (len > 0) {
677                                                 /* there are parameters after transport */
678                                                 if (crt+len>end) goto error_uri;
679                                                 tmp = uri.transport.s + uri.transport.len;
680                                                 memcpy(crt,tmp,len);crt+=len;
681                                         }
682                                 } else {
683                                         tmp=uri.params.s;
684                                         if (tmp){
685                                                 len=uri.params.len; if(crt+len+1>end) goto error_uri;
686                                                 *crt=';'; crt++;
687                                                 memcpy(crt,tmp,len);crt+=len;
688                                         }
689                                 }
690                                 /* headers */
691                                 tmp=uri.headers.s;
692                                 if (tmp){
693                                         len=uri.headers.len; if(crt+len+1>end) goto error_uri;
694                                         *crt='?'; crt++;
695                                         memcpy(crt,tmp,len);crt+=len;
696                                 }
697         done_seturi:
698                                 *crt=0; /* null terminate the thing */
699                                 /* copy it to the msg */
700                                 if (msg->new_uri.s) pkg_free(msg->new_uri.s);
701                                 msg->new_uri.s=new_uri;
702                                 msg->new_uri.len=crt-new_uri;
703                                 msg->parsed_uri_ok=0;
704                                 ret=1;
705                                 break;
706                 case IF_T:
707                                 /* if null expr => ignore if? */
708                                 if ((a->val[0].type==EXPR_ST)&&a->val[0].u.data){
709                                         v=eval_expr(h, (struct expr*)a->val[0].u.data, msg);
710 #if 0
711                                         if (v<0){
712                                                 if (v==EXPR_DROP){ /* hack to quit on DROP*/
713                                                         ret=0;
714                                                         break;
715                                                 }else{
716                                                         LOG(L_WARN,"WARNING: do_action:"
717                                                                                 "error in expression\n");
718                                                 }
719                                         }
720 #endif
721                                         if (h->run_flags & EXIT_R_F){
722                                                 ret=0;
723                                                 break;
724                                         }
725                                         h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return &
726                                                                                                                             break in expr*/
727                                         ret=1;  /*default is continue */
728                                         if (v>0) {
729                                                 if ((a->val[1].type==ACTIONS_ST)&&a->val[1].u.data){
730                                                         ret=run_actions(h,
731                                                                                 (struct action*)a->val[1].u.data, msg);
732                                                 }
733                                         }else if ((a->val[2].type==ACTIONS_ST)&&a->val[2].u.data){
734                                                         ret=run_actions(h,
735                                                                                 (struct action*)a->val[2].u.data, msg);
736                                         }
737                                 }
738                         break;
739                 case MODULE_T:
740                         if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
741                                         (f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
742                                 ret=((cmd_function)f)(msg,
743                                                                                 (char*)a->val[2].u.data,
744                                                                                 (char*)a->val[3].u.data
745                                                                         );
746                                 if (ret==0) h->run_flags|=EXIT_R_F;
747                                 h->last_retcode=ret;
748                         } else {
749                                 LOG(L_CRIT,"BUG: do_action: bad module call\n");
750                         }
751                         break;
752                 /* instead of using the parameter number, we use different names
753                  * for calls to functions with 3, 4, 5, 6 or variable number of
754                  * parameters due to performance reasons */
755                 case MODULE3_T:
756                         if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
757                                         (f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
758                                 ret=((cmd_function3)f)(msg,
759                                                                                 (char*)a->val[2].u.data,
760                                                                                 (char*)a->val[3].u.data,
761                                                                                 (char*)a->val[4].u.data
762                                                                         );
763                                 if (ret==0) h->run_flags|=EXIT_R_F;
764                                 h->last_retcode=ret;
765                         } else {
766                                 LOG(L_CRIT,"BUG: do_action: bad module call\n");
767                         }
768                         break;
769                 case MODULE4_T:
770                         if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
771                                         (f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
772                                 ret=((cmd_function4)f)(msg,
773                                                                                 (char*)a->val[2].u.data,
774                                                                                 (char*)a->val[3].u.data,
775                                                                                 (char*)a->val[4].u.data,
776                                                                                 (char*)a->val[5].u.data
777                                                                         );
778                                 if (ret==0) h->run_flags|=EXIT_R_F;
779                                 h->last_retcode=ret;
780                         } else {
781                                 LOG(L_CRIT,"BUG: do_action: bad module call\n");
782                         }
783                         break;
784                 case MODULE5_T:
785                         if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
786                                         (f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
787                                 ret=((cmd_function5)f)(msg,
788                                                                                 (char*)a->val[2].u.data,
789                                                                                 (char*)a->val[3].u.data,
790                                                                                 (char*)a->val[4].u.data,
791                                                                                 (char*)a->val[5].u.data,
792                                                                                 (char*)a->val[6].u.data
793                                                                         );
794                                 if (ret==0) h->run_flags|=EXIT_R_F;
795                                 h->last_retcode=ret;
796                         } else {
797                                 LOG(L_CRIT,"BUG: do_action: bad module call\n");
798                         }
799                         break;
800                 case MODULE6_T:
801                         if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
802                                         (f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
803                                 ret=((cmd_function6)f)(msg,
804                                                                                 (char*)a->val[2].u.data,
805                                                                                 (char*)a->val[3].u.data,
806                                                                                 (char*)a->val[4].u.data,
807                                                                                 (char*)a->val[5].u.data,
808                                                                                 (char*)a->val[6].u.data,
809                                                                                 (char*)a->val[7].u.data
810                                                                         );
811                                 if (ret==0) h->run_flags|=EXIT_R_F;
812                                 h->last_retcode=ret;
813                         } else {
814                                 LOG(L_CRIT,"BUG: do_action: bad module call\n");
815                         }
816                         break;
817                 case MODULEX_T:
818                         if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
819                                         (f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
820                                 ret=((cmd_function_var)f)(msg,
821                                                                                         a->val[1].u.number,
822                                                                                         &a->val[2]
823                                                                                 );
824                                 if (ret==0) h->run_flags|=EXIT_R_F;
825                                 h->last_retcode=ret;
826                         } else {
827                                 LOG(L_CRIT,"BUG: do_action: bad module call\n");
828                         }
829                         break;
830                 case EVAL_T:
831                         /* only eval the expression to account for possible
832                            side-effect */
833                         rval_expr_eval_int(h, msg, &v,
834                                         (struct rval_expr*)a->val[0].u.data);
835                         if (h->run_flags & EXIT_R_F){
836                                 ret=0;
837                                 break;
838                         }
839                         h->run_flags &= ~RETURN_R_F|BREAK_R_F; /* catch return & break in
840                                                                                                           expr */
841                         ret=1; /* default is continue */
842                         break;
843                 case SWITCH_COND_T:
844                         sct=(struct switch_cond_table*)a->val[1].u.data;
845                         if (unlikely( rval_expr_eval_int(h, msg, &v,
846                                                                         (struct rval_expr*)a->val[0].u.data) <0)){
847                                 /* handle error in expression => use default */
848                                 ret=-1;
849                                 goto sw_cond_def;
850                         }
851                         if (h->run_flags & EXIT_R_F){
852                                 ret=0;
853                                 break;
854                         }
855                         h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return & break
856                                                                                                             in expr */
857                         ret=1; /* default is continue */
858                         for(i=0; i<sct->n; i++)
859                                 if (sct->cond[i]==v){
860                                         if (likely(sct->jump[i])){
861                                                 ret=run_actions(h, sct->jump[i], msg);
862                                                 h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
863                                                                                                            returns passthrough */
864                                         }
865                                         goto skip;
866                                 }
867 sw_cond_def:
868                         if (sct->def){
869                                 ret=run_actions(h, sct->def, msg);
870                                 h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
871                                                                                            returns passthrough */
872                         }
873                         break;
874                 case SWITCH_JT_T:
875                         sjt=(struct switch_jmp_table*)a->val[1].u.data;
876                         if (unlikely( rval_expr_eval_int(h, msg, &v,
877                                                                         (struct rval_expr*)a->val[0].u.data) <0)){
878                                 /* handle error in expression => use default */
879                                 ret=-1;
880                                 goto sw_jt_def;
881                         }
882                         if (h->run_flags & EXIT_R_F){
883                                 ret=0;
884                                 break;
885                         }
886                         h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return & break
887                                                                                                             in expr */
888                         ret=1; /* default is continue */
889                         if (likely(v >= sjt->first && v <= sjt->last)){
890                                 if (likely(sjt->tbl[v - sjt->first])){
891                                         ret=run_actions(h, sjt->tbl[v - sjt->first], msg);
892                                         h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
893                                                                                                    returns passthrough */
894                                 }
895                                 break; 
896                         }else{
897                                 for(i=0; i<sjt->rest.n; i++)
898                                         if (sjt->rest.cond[i]==v){
899                                                 if (likely(sjt->rest.jump[i])){
900                                                         ret=run_actions(h, sjt->rest.jump[i], msg);
901                                                         h->run_flags &= ~BREAK_R_F; /* catch breaks, but 
902                                                                                                                    let returns pass */
903                                                 }
904                                                 goto skip;
905                                         }
906                         }
907                         /* not found => try default */
908 sw_jt_def:
909                         if (sjt->rest.def){
910                                 ret=run_actions(h, sjt->rest.def, msg);
911                                 h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
912                                                                                            returns passthrough */
913                         }
914                         break;
915                 case BLOCK_T:
916                         if (likely(a->val[0].u.data)){
917                                 ret=run_actions(h, (struct action*)a->val[0].u.data, msg);
918                                 h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
919                                                                                            returns passthrough */
920                         }
921                         break;
922                 case MATCH_COND_T:
923                         mct=(struct match_cond_table*)a->val[1].u.data;
924                         rval_cache_init(&c1);
925                         rv=0;
926                         rv1=0;
927                         ret=rval_expr_eval_rvint(h, msg, &rv, &v, 
928                                                                         (struct rval_expr*)a->val[0].u.data, &c1);
929                                                                         
930                         if (unlikely( ret<0)){
931                                 /* handle error in expression => use default */
932                                 ret=-1;
933                                 goto match_cond_def;
934                         }
935                         if (h->run_flags & EXIT_R_F){
936                                 ret=0;
937                                 break;
938                         }
939                         h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return & break
940                                                                                                             in expr */
941                         if (likely(rv)){
942                                 rv1=rval_convert(h, msg, RV_STR, rv, &c1);
943                                 if (unlikely(rv1==0)){
944                                         ret=-1;
945                                         goto match_cond_def;
946                                 }
947                                 s=rv1->v.s;
948                         }else{
949                                 /* int result in v */
950                                 rval_cache_clean(&c1);
951                                 s.s=sint2str(v, &s.len);
952                         }
953                         ret=1; /* default is continue */
954                         for(i=0; i<mct->n; i++)
955                                 if (( mct->match[i].type==MATCH_STR &&
956                                                 mct->match[i].l.s.len==s.len &&
957                                                 memcmp(mct->match[i].l.s.s, s.s, s.len) == 0 ) ||
958                                          ( mct->match[i].type==MATCH_RE &&
959                                           regexec(mct->match[i].l.regex, s.s, 0, 0, 0) == 0)
960                                         ){
961                                         if (likely(mct->jump[i])){
962                                                 ret=run_actions(h, mct->jump[i], msg);
963                                                 h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
964                                                                                                            returns passthrough */
965                                         }
966                                         goto match_cleanup;
967                                 }
968 match_cond_def:
969                         if (mct->def){
970                                 ret=run_actions(h, mct->def, msg);
971                                 h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
972                                                                                            returns passthrough */
973                         }
974 match_cleanup:
975                         if (rv1){
976                                 rval_destroy(rv1);
977                                 rval_destroy(rv);
978                                 rval_cache_clean(&c1);
979                         }else if (rv){
980                                 rval_destroy(rv);
981                                 rval_cache_clean(&c1);
982                         }
983                         break;
984                 case WHILE_T:
985                         i=0;
986                         flags=0;
987                         rve=(struct rval_expr*)a->val[0].u.data;
988                         ret=1;
989                         while(!(flags & BREAK_R_F) && 
990                                         (rval_expr_eval_int(h, msg, &v, rve) == 0) && v){
991                                 i++;
992                                 if (unlikely(i > cfg_get(core, core_cfg, max_while_loops))){
993                                         LOG(L_ERR, "ERROR: runaway while (%d, %d): more then"
994                                                                 " %d loops\n", 
995                                                                 rve->fpos.s_line, rve->fpos.s_col,
996                                                                 cfg_get(core, core_cfg, max_while_loops));
997                                         ret=-1;
998                                         break;
999                                 }
1000                                 if (likely(a->val[1].u.data)){
1001                                         ret=run_actions(h, (struct action*)a->val[1].u.data, msg);
1002                                         flags|=h->run_flags;
1003                                         h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
1004                                                                                                    returns passthrough */
1005                                 }
1006                         }
1007                         break;
1008                 case FORCE_RPORT_T:
1009                         msg->msg_flags|=FL_FORCE_RPORT;
1010                         ret=1; /* continue processing */
1011                         break;
1012                 case UDP_MTU_TRY_PROTO_T:
1013                         msg->msg_flags|= (unsigned int)a->val[0].u.number & FL_MTU_FB_MASK;
1014                         ret=1; /* continue processing */
1015                         break;
1016                 case SET_ADV_ADDR_T:
1017                         if (a->val[0].type!=STR_ST){
1018                                 LOG(L_CRIT, "BUG: do_action: bad set_advertised_address() "
1019                                                 "type %d\n", a->val[0].type);
1020                                 ret=E_BUG;
1021                                 break;
1022                         }
1023                         msg->set_global_address=*((str*)a->val[0].u.data);
1024                         ret=1; /* continue processing */
1025                         break;
1026                 case SET_ADV_PORT_T:
1027                         if (a->val[0].type!=STR_ST){
1028                                 LOG(L_CRIT, "BUG: do_action: bad set_advertised_port() "
1029                                                 "type %d\n", a->val[0].type);
1030                                 ret=E_BUG;
1031                                 break;
1032                         }
1033                         msg->set_global_port=*((str*)a->val[0].u.data);
1034                         ret=1; /* continue processing */
1035                         break;
1036 #ifdef USE_TCP
1037                 case FORCE_TCP_ALIAS_T:
1038                         if ( msg->rcv.proto==PROTO_TCP
1039 #ifdef USE_TLS
1040                                         || msg->rcv.proto==PROTO_TLS
1041 #endif
1042                            ){
1043
1044                                 if (a->val[0].type==NOSUBTYPE)  port=msg->via1->port;
1045                                 else if (a->val[0].type==NUMBER_ST) port=(int)a->val[0].u.number;
1046                                 else{
1047                                         LOG(L_CRIT, "BUG: do_action: bad force_tcp_alias"
1048                                                         " port type %d\n", a->val[0].type);
1049                                         ret=E_BUG;
1050                                         break;
1051                                 }
1052
1053                                 if (tcpconn_add_alias(msg->rcv.proto_reserved1, port,
1054                                                                         msg->rcv.proto)!=0){
1055                                         LOG(L_ERR, " ERROR: receive_msg: tcp alias failed\n");
1056                                         ret=E_UNSPEC;
1057                                         break;
1058                                 }
1059                         }
1060 #endif
1061                         ret=1; /* continue processing */
1062                         break;
1063                 case FORCE_SEND_SOCKET_T:
1064                         if (a->val[0].type!=SOCKETINFO_ST){
1065                                 LOG(L_CRIT, "BUG: do_action: bad force_send_socket argument"
1066                                                 " type: %d\n", a->val[0].type);
1067                                 ret=E_BUG;
1068                                 break;
1069                         }
1070                         msg->force_send_socket=(struct socket_info*)a->val[0].u.data;
1071                         ret=1; /* continue processing */
1072                         break;
1073
1074                 case ADD_T:
1075                 case ASSIGN_T:
1076                         v=lval_assign(h, msg, (struct lvalue*)a->val[0].u.data,
1077                                                                   (struct rval_expr*)a->val[1].u.data);
1078                         if (likely(v>=0))
1079                                 ret = 1;
1080                         else if (unlikely (v == EXPR_DROP)) /* hack to quit on DROP*/
1081                                 ret=0;
1082                         else
1083                                 ret=v;
1084                         break;
1085
1086                 default:
1087                         LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
1088         }
1089 skip:
1090         return ret;
1091
1092 error_uri:
1093         LOG(L_ERR, "ERROR: do_action: set*: uri too long\n");
1094         if (new_uri) pkg_free(new_uri);
1095         return E_UNSPEC;
1096 error_fwd_uri:
1097         /*free_uri(&uri); -- not needed anymore, using msg->parsed_uri*/
1098         return ret;
1099 }
1100
1101
1102
1103 /* returns: 0, or 1 on success, <0 on error */
1104 /* (0 if drop or break encountered, 1 if not ) */
1105 int run_actions(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
1106 {
1107         struct action* t;
1108         int ret;
1109         struct sr_module *mod;
1110
1111         ret=E_UNSPEC;
1112         h->rec_lev++;
1113         if (h->rec_lev>ROUTE_MAX_REC_LEV){
1114                 LOG(L_ERR, "WARNING: too many recursive routing table lookups (%d)"
1115                                         " giving up!\n", h->rec_lev);
1116                 ret=E_UNSPEC;
1117                 goto error;
1118         }
1119         if (h->rec_lev==1){
1120                 h->run_flags=0;
1121                 h->last_retcode=0;
1122 #ifdef USE_LONGJMP
1123                 if (setjmp(h->jmp_env)){
1124                         h->rec_lev=0;
1125                         ret=h->last_retcode;
1126                         goto end;
1127                 }
1128 #endif
1129         }
1130
1131         if (a==0){
1132                 DBG("DEBUG: run_actions: null action list (rec_level=%d)\n",
1133                                 h->rec_lev);
1134                 ret=1;
1135         }
1136
1137         for (t=a; t!=0; t=t->next){
1138                 ret=do_action(h, t, msg);
1139                 /* break, return or drop/exit stop execution of the current
1140                    block */
1141                 if (h->run_flags & (BREAK_R_F|RETURN_R_F|EXIT_R_F)){
1142                         if (h->run_flags & EXIT_R_F){
1143 #ifdef USE_LONGJMP
1144                                 h->last_retcode=ret;
1145                                 longjmp(h->jmp_env, ret);
1146 #endif
1147                         }
1148                         break;
1149                 }
1150                 /* ignore error returns */
1151         }
1152
1153         h->rec_lev--;
1154 end:
1155         /* process module onbreak handlers if present */
1156         if (h->rec_lev==0 && ret==0)
1157                 for (mod=modules;mod;mod=mod->next)
1158                         if ((mod->mod_interface_ver==0) && mod->exports && 
1159                                         mod->exports->v0.onbreak_f) {
1160                                 mod->exports->v0.onbreak_f( msg );
1161                                 DBG("DEBUG: %s onbreak handler called\n",
1162                                                 mod->exports->c.name);
1163                         }
1164         return ret;
1165
1166
1167 error:
1168         h->rec_lev--;
1169         return ret;
1170 }