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