a1d0498f15eacef3bfafc35e6309409e4b4772b4
[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  */
44
45
46 #include "comp_defs.h"
47
48 #include "action.h"
49 #include "config.h"
50 #include "error.h"
51 #include "dprint.h"
52 #include "proxy.h"
53 #include "forward.h"
54 #include "udp_server.h"
55 #include "route.h"
56 #include "parser/msg_parser.h"
57 #include "parser/parse_uri.h"
58 #include "ut.h"
59 #include "sr_module.h"
60 #include "mem/mem.h"
61 #include "globals.h"
62 #include "dset.h"
63 #include "onsend.h"
64 #ifdef USE_TCP
65 #include "tcp_server.h"
66 #endif
67
68 #include <sys/types.h>
69 #include <sys/socket.h>
70 #include <netdb.h>
71 #include <stdlib.h>
72 #include <netinet/in.h>
73 #include <arpa/inet.h>
74 #include <string.h>
75
76 #define USE_LONGJMP
77
78 #ifdef USE_LONGJMP
79 #include <setjmp.h>
80 #endif
81
82 #ifdef DEBUG_DMALLOC
83 #include <dmalloc.h>
84 #endif
85
86
87 struct onsend_info* p_onsend=0; /* onsend route send info */
88 static unsigned int run_flags=0;
89 int last_retcode=0; /* last return from a route() */
90
91 /* ret= 0! if action -> end of list(e.g DROP),
92       > 0 to continue processing next actions
93    and <0 on error */
94 int do_action(struct action* a, struct sip_msg* msg)
95 {
96         int ret;
97         int v;
98         union sockaddr_union* to;
99         struct socket_info* send_sock;
100         struct proxy_l* p;
101         char* tmp;
102         char *new_uri, *end, *crt;
103         int len;
104         int user;
105         struct sip_uri uri, next_hop;
106         struct sip_uri *u;
107         unsigned short port;
108         int proto;
109         unsigned short flags;
110         int_str name, value;
111
112         /* reset the value of error to E_UNSPEC so avoid unknowledgable
113            functions to return with error (status<0) and not setting it
114            leaving there previous error; cache the previous value though
115            for functions which want to process it */
116         prev_ser_error=ser_error;
117         ser_error=E_UNSPEC;
118
119         ret=E_BUG;
120         switch ((unsigned char)a->type){
121                 case DROP_T:
122                                 if (a->val[0].type==RETCODE_ST)
123                                         ret=last_retcode;
124                                 else
125                                         ret=(int) a->val[0].u.number;
126                                 run_flags|=(unsigned int)a->val[1].u.number;
127                         break;
128                 case FORWARD_T:
129 #ifdef USE_TCP
130                 case FORWARD_TCP_T:
131 #endif
132 #ifdef USE_TLS
133                 case FORWARD_TLS_T:
134 #endif
135                 case FORWARD_UDP_T:
136
137                         if (a->type==FORWARD_UDP_T) proto=PROTO_UDP;
138 #ifdef USE_TCP
139                         else if (a->type==FORWARD_TCP_T) proto= PROTO_TCP;
140 #endif
141 #ifdef USE_TLS
142                         else if (a->type==FORWARD_TLS_T) proto= PROTO_TLS;
143 #endif
144                         else proto= PROTO_NONE;
145                         if (a->val[0].type==URIHOST_ST){
146                                 /*parse uri*/
147
148                                 if (msg->dst_uri.len) {
149                                         ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len, &next_hop);
150                                         u = &next_hop;
151                                 } else {
152                                         ret = parse_sip_msg_uri(msg);
153                                         u = &msg->parsed_uri;
154                                 }
155
156                                 if (ret<0) {
157                                         LOG(L_ERR, "ERROR: do_action: forward: bad_uri "
158                                                                 " dropping packet\n");
159                                         break;
160                                 }
161
162                                 switch (a->val[1].type){
163                                         case URIPORT_ST:
164                                                                         port=u->port_no;
165                                                                         break;
166                                         case NUMBER_ST:
167                                                                         port=a->val[1].u.number;
168                                                                         break;
169                                         default:
170                                                         LOG(L_CRIT, "BUG: do_action bad forward 2nd"
171                                                                                 " param type (%d)\n", a->val[1].type);
172                                                         ret=E_UNSPEC;
173                                                         goto error_fwd_uri;
174                                 }
175                                 if (proto == PROTO_NONE){ /* only if proto not set get it
176                                                                                          from the uri */
177                                         switch(u->proto){
178                                                 case PROTO_NONE:
179                                                         proto=PROTO_UDP;
180                                                         break;
181                                                 case PROTO_UDP:
182 #ifdef USE_TCP
183                                                 case PROTO_TCP:
184 #endif
185 #ifdef USE_TLS
186                                                 case PROTO_TLS:
187 #endif
188                                                         proto=u->proto;
189                                                         break;
190                                                 default:
191                                                         LOG(L_ERR,"ERROR: do action: forward: bad uri"
192                                                                         " transport %d\n", u->proto);
193                                                         ret=E_BAD_PROTO;
194                                                         goto error_fwd_uri;
195                                         }
196 #ifdef USE_TLS
197                                         if (u->type==SIPS_URI_T){
198                                                 if (u->proto==PROTO_UDP){
199                                                         LOG(L_ERR, "ERROR: do_action: forward: secure uri"
200                                                                         " incompatible with transport %d\n",
201                                                                         u->proto);
202                                                         ret=E_BAD_PROTO;
203                                                         goto error_fwd_uri;
204                                                 }
205                                                 proto=PROTO_TLS;
206                                         }
207 #endif
208                                 }
209                                 /* create a temporary proxy*/
210                                 p=mk_proxy(&u->host, port, proto);
211                                 if (p==0){
212                                         LOG(L_ERR, "ERROR:  bad host name in uri,"
213                                                         " dropping packet\n");
214                                         ret=E_BAD_ADDRESS;
215                                         goto error_fwd_uri;
216                                 }
217                                 ret=forward_request(msg, p, proto);
218                                 /*free_uri(&uri); -- no longer needed, in sip_msg*/
219                                 free_proxy(p); /* frees only p content, not p itself */
220                                 pkg_free(p);
221                                 if (ret>=0) ret=1;
222                         }else if ((a->val[0].type==PROXY_ST) && (a->val[1].type==NUMBER_ST)){
223                                 if (proto==PROTO_NONE)
224                                         proto=msg->rcv.proto;
225                                 ret=forward_request(msg,(struct proxy_l*)a->val[0].u.data, proto);
226                                 if (ret>=0) ret=1;
227                         }else{
228                                 LOG(L_CRIT, "BUG: do_action: bad forward() types %d, %d\n",
229                                                 a->val[0].type, a->val[1].type);
230                                 ret=E_BUG;
231                         }
232                         break;
233                 case SEND_T:
234                 case SEND_TCP_T:
235                         if ((a->val[0].type!= PROXY_ST)|(a->val[1].type!=NUMBER_ST)){
236                                 LOG(L_CRIT, "BUG: do_action: bad send() types %d, %d\n",
237                                                 a->val[0].type, a->val[1].type);
238                                 ret=E_BUG;
239                                 break;
240                         }
241                         to=(union sockaddr_union*)
242                                         pkg_malloc(sizeof(union sockaddr_union));
243                         if (to==0){
244                                 LOG(L_ERR, "ERROR: do_action: "
245                                                         "memory allocation failure\n");
246                                 ret=E_OUT_OF_MEM;
247                                 break;
248                         }
249
250                         p=(struct proxy_l*)a->val[0].u.data;
251
252                         if (p->ok==0){
253                                 if (p->host.h_addr_list[p->addr_idx+1])
254                                         p->addr_idx++;
255                                 else
256                                         p->addr_idx=0;
257                                 p->ok=1;
258                         }
259                         ret=hostent2su( to, &p->host, p->addr_idx,
260                                                 (p->port)?p->port:SIP_PORT );
261                         if (ret==0){
262                                 if (p_onsend){
263                                         tmp=p_onsend->buf;
264                                         len=p_onsend->len;
265                                 }else{
266                                         tmp=msg->buf;
267                                         len=msg->len;
268                                 }
269                                 p->tx++;
270                                 p->tx_bytes+=len;
271                                 if (a->type==SEND_T){
272                                         /*udp*/
273                                         send_sock=get_send_socket(msg, to, PROTO_UDP);
274                                         if (send_sock!=0){
275                                                 ret=udp_send(send_sock, tmp, len, to);
276                                         }else{
277                                                 ret=-1;
278                                         }
279                                 }
280 #ifdef USE_TCP
281                                         else{
282                                         /*tcp*/
283                                         ret=tcp_send(PROTO_TCP, tmp, len, to, 0);
284                                 }
285 #endif
286                         }
287                         pkg_free(to);
288                         if (ret<0){
289                                 p->errors++;
290                                 p->ok=0;
291                         }else ret=1;
292
293                         break;
294                 case LOG_T:
295                         if ((a->val[0].type!=NUMBER_ST)|(a->val[1].type!=STRING_ST)){
296                                 LOG(L_CRIT, "BUG: do_action: bad log() types %d, %d\n",
297                                                 a->val[0].type, a->val[1].type);
298                                 ret=E_BUG;
299                                 break;
300                         }
301                         LOG(a->val[0].u.number, "%s", a->val[1].u.string);
302                         ret=1;
303                         break;
304
305                 /* jku -- introduce a new branch */
306                 case APPEND_BRANCH_T:
307                         if ((a->val[0].type!=STRING_ST)) {
308                                 LOG(L_CRIT, "BUG: do_action: bad append_branch_t %d\n",
309                                         a->val[0].type );
310                                 ret=E_BUG;
311                                 break;
312                         }
313                         ret=append_branch( msg, a->val[0].u.string,
314                                            a->val[0].u.string ? strlen(a->val[0].u.string):0,
315                                            0, 0, a->val[1].u.number, 0);
316                         break;
317
318                 /* jku begin: is_length_greater_than */
319                 case LEN_GT_T:
320                         if (a->val[0].type!=NUMBER_ST) {
321                                 LOG(L_CRIT, "BUG: do_action: bad len_gt type %d\n",
322                                         a->val[0].type );
323                                 ret=E_BUG;
324                                 break;
325                         }
326                         /* DBG("XXX: message length %d, max %d\n",
327                                 msg->len, a->val[0].u.number ); */
328                         ret = msg->len >= a->val[0].u.number ? 1 : -1;
329                         break;
330                 /* jku end: is_length_greater_than */
331
332                 /* jku - begin : flag processing */
333
334                 case SETFLAG_T:
335                         if (a->val[0].type!=NUMBER_ST) {
336                                 LOG(L_CRIT, "BUG: do_action: bad setflag() type %d\n",
337                                         a->val[0].type );
338                                 ret=E_BUG;
339                                 break;
340                         }
341                         if (!flag_in_range( a->val[0].u.number )) {
342                                 ret=E_CFG;
343                                 break;
344                         }
345                         setflag( msg, a->val[0].u.number );
346                         ret=1;
347                         break;
348
349                 case RESETFLAG_T:
350                         if (a->val[0].type!=NUMBER_ST) {
351                                 LOG(L_CRIT, "BUG: do_action: bad resetflag() type %d\n",
352                                         a->val[0].type );
353                                 ret=E_BUG;
354                                 break;
355                         }
356                         if (!flag_in_range( a->val[0].u.number )) {
357                                 ret=E_CFG;
358                                 break;
359                         }
360                         resetflag( msg, a->val[0].u.number );
361                         ret=1;
362                         break;
363
364                 case ISFLAGSET_T:
365                         if (a->val[0].type!=NUMBER_ST) {
366                                 LOG(L_CRIT, "BUG: do_action: bad isflagset() type %d\n",
367                                         a->val[0].type );
368                                 ret=E_BUG;
369                                 break;
370                         }
371                         if (!flag_in_range( a->val[0].u.number )) {
372                                 ret=E_CFG;
373                                 break;
374                         }
375                         ret=isflagset( msg, a->val[0].u.number );
376                         break;
377                 /* jku - end : flag processing */
378
379                 case ERROR_T:
380                         if ((a->val[0].type!=STRING_ST)|(a->val[1].type!=STRING_ST)){
381                                 LOG(L_CRIT, "BUG: do_action: bad error() types %d, %d\n",
382                                                 a->val[0].type, a->val[1].type);
383                                 ret=E_BUG;
384                                 break;
385                         }
386                         LOG(L_NOTICE, "WARNING: do_action: error(\"%s\", \"%s\") "
387                                         "not implemented yet\n", a->val[0].u.string, a->val[1].u.string);
388                         ret=1;
389                         break;
390                 case ROUTE_T:
391                         if (a->val[0].type!=NUMBER_ST){
392                                 LOG(L_CRIT, "BUG: do_action: bad route() type %d\n",
393                                                 a->val[0].type);
394                                 ret=E_BUG;
395                                 break;
396                         }
397                         if ((a->val[0].u.number>=main_rt.idx)||(a->val[0].u.number<0)){
398                                 LOG(L_ERR, "ERROR: invalid routing table number in"
399                                                         "route(%lu)\n", a->val[0].u.number);
400                                 ret=E_CFG;
401                                 break;
402                         }
403                         /*ret=((ret=run_actions(rlist[a->val[0].u.number], msg))<0)?ret:1;*/
404                         ret=run_actions(main_rt.rlist[a->val[0].u.number], msg);
405                         last_retcode=ret;
406                         run_flags&=~RETURN_R_F; /* absorb returns */
407                         break;
408                 case EXEC_T:
409                         if (a->val[0].type!=STRING_ST){
410                                 LOG(L_CRIT, "BUG: do_action: bad exec() type %d\n",
411                                                 a->val[0].type);
412                                 ret=E_BUG;
413                                 break;
414                         }
415                         LOG(L_NOTICE, "WARNING: exec(\"%s\") not fully implemented,"
416                                                 " using dumb version...\n", a->val[0].u.string);
417                         ret=system(a->val[0].u.string);
418                         if (ret!=0){
419                                 LOG(L_NOTICE, "WARNING: exec() returned %d\n", ret);
420                         }
421                         ret=1;
422                         break;
423                 case REVERT_URI_T:
424                         if (msg->new_uri.s) {
425                                 pkg_free(msg->new_uri.s);
426                                 msg->new_uri.len=0;
427                                 msg->new_uri.s=0;
428                                 msg->parsed_uri_ok=0; /* invalidate current parsed uri*/
429                         };
430                         ret=1;
431                         break;
432                 case SET_HOST_T:
433                 case SET_HOSTPORT_T:
434                 case SET_USER_T:
435                 case SET_USERPASS_T:
436                 case SET_PORT_T:
437                 case SET_URI_T:
438                 case PREFIX_T:
439                 case STRIP_T:
440                 case STRIP_TAIL_T:
441                                 user=0;
442                                 if (a->type==STRIP_T || a->type==STRIP_TAIL_T) {
443                                         if (a->val[0].type!=NUMBER_ST) {
444                                                 LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
445                                                         a->val[0].type);
446                                                 break;
447                                         }
448                                 } else if (a->val[0].type!=STRING_ST){
449                                         LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
450                                                         a->val[0].type);
451                                         ret=E_BUG;
452                                         break;
453                                 }
454                                 if (a->type==SET_URI_T){
455                                         if (msg->new_uri.s) {
456                                                         pkg_free(msg->new_uri.s);
457                                                         msg->new_uri.len=0;
458                                         }
459                                         msg->parsed_uri_ok=0;
460                                         len=strlen(a->val[0].u.string);
461                                         msg->new_uri.s=pkg_malloc(len+1);
462                                         if (msg->new_uri.s==0){
463                                                 LOG(L_ERR, "ERROR: do_action: memory allocation"
464                                                                 " failure\n");
465                                                 ret=E_OUT_OF_MEM;
466                                                 break;
467                                         }
468                                         memcpy(msg->new_uri.s, a->val[0].u.string, len);
469                                         msg->new_uri.s[len]=0;
470                                         msg->new_uri.len=len;
471
472                                         ret=1;
473                                         break;
474                                 }
475                                 if (msg->new_uri.s) {
476                                         tmp=msg->new_uri.s;
477                                         len=msg->new_uri.len;
478                                 }else{
479                                         tmp=msg->first_line.u.request.uri.s;
480                                         len=msg->first_line.u.request.uri.len;
481                                 }
482                                 if (parse_uri(tmp, len, &uri)<0){
483                                         LOG(L_ERR, "ERROR: do_action: bad uri <%s>, dropping"
484                                                                 " packet\n", tmp);
485                                         ret=E_UNSPEC;
486                                         break;
487                                 }
488
489                                 new_uri=pkg_malloc(MAX_URI_SIZE);
490                                 if (new_uri==0){
491                                         LOG(L_ERR, "ERROR: do_action: memory allocation "
492                                                                 " failure\n");
493                                         ret=E_OUT_OF_MEM;
494                                         break;
495                                 }
496                                 end=new_uri+MAX_URI_SIZE;
497                                 crt=new_uri;
498                                 /* begin copying */
499                                 len=strlen("sip:"); if(crt+len>end) goto error_uri;
500                                 memcpy(crt,"sip:",len);crt+=len;
501
502                                 /* user */
503
504                                 /* prefix (-jiri) */
505                                 if (a->type==PREFIX_T) {
506                                         tmp=a->val[0].u.string;
507                                         len=strlen(tmp); if(crt+len>end) goto error_uri;
508                                         memcpy(crt,tmp,len);crt+=len;
509                                         /* whatever we had before, with prefix we have username
510                                            now */
511                                         user=1;
512                                 }
513
514                                 if ((a->type==SET_USER_T)||(a->type==SET_USERPASS_T)) {
515                                         tmp=a->val[0].u.string;
516                                         len=strlen(tmp);
517                                 } else if (a->type==STRIP_T) {
518                                         if (a->val[0].u.number>uri.user.len) {
519                                                 LOG(L_WARN, "Error: too long strip asked; "
520                                                                         " deleting username: %lu of <%.*s>\n",
521                                                                         a->val[0].u.number, uri.user.len, uri.user.s );
522                                                 len=0;
523                                         } else if (a->val[0].u.number==uri.user.len) {
524                                                 len=0;
525                                         } else {
526                                                 tmp=uri.user.s + a->val[0].u.number;
527                                                 len=uri.user.len - a->val[0].u.number;
528                                         }
529                                 } else if (a->type==STRIP_TAIL_T) {
530                                         if (a->val[0].u.number>uri.user.len) {
531                                                 LOG(L_WARN, "WARNING: too long strip_tail asked; "
532                                                                         " deleting username: %lu of <%.*s>\n",
533                                                                         a->val[0].u.number, uri.user.len, uri.user.s );
534                                                 len=0;
535                                         } else if (a->val[0].u.number==uri.user.len) {
536                                                 len=0;
537                                         } else {
538                                                 tmp=uri.user.s;
539                                                 len=uri.user.len - a->val[0].u.number;
540                                         }
541                                 } else {
542                                         tmp=uri.user.s;
543                                         len=uri.user.len;
544                                 }
545
546                                 if (len){
547                                         if(crt+len>end) goto error_uri;
548                                         memcpy(crt,tmp,len);crt+=len;
549                                         user=1; /* we have an user field so mark it */
550                                 }
551
552                                 if (a->type==SET_USERPASS_T) tmp=0;
553                                 else tmp=uri.passwd.s;
554                                 /* passwd */
555                                 if (tmp){
556                                         len=uri.passwd.len; if(crt+len+1>end) goto error_uri;
557                                         *crt=':'; crt++;
558                                         memcpy(crt,tmp,len);crt+=len;
559                                 }
560                                 /* host */
561                                 if (user || tmp){ /* add @ */
562                                         if(crt+1>end) goto error_uri;
563                                         *crt='@'; crt++;
564                                 }
565                                 if ((a->type==SET_HOST_T) ||(a->type==SET_HOSTPORT_T)) {
566                                         tmp=a->val[0].u.string;
567                                         if (tmp) len = strlen(tmp);
568                                         else len=0;
569                                 } else {
570                                         tmp=uri.host.s;
571                                         len = uri.host.len;
572                                 }
573                                 if (tmp){
574                                         if(crt+len>end) goto error_uri;
575                                         memcpy(crt,tmp,len);crt+=len;
576                                 }
577                                 /* port */
578                                 if (a->type==SET_HOSTPORT_T) tmp=0;
579                                 else if (a->type==SET_PORT_T) {
580                                         tmp=a->val[0].u.string;
581                                         if (tmp) len = strlen(tmp);
582                                         else len = 0;
583                                 } else {
584                                         tmp=uri.port.s;
585                                         len = uri.port.len;
586                                 }
587                                 if (tmp){
588                                         if(crt+len+1>end) goto error_uri;
589                                         *crt=':'; crt++;
590                                         memcpy(crt,tmp,len);crt+=len;
591                                 }
592                                 /* params */
593                                 tmp=uri.params.s;
594                                 if (tmp){
595                                         len=uri.params.len; if(crt+len+1>end) goto error_uri;
596                                         *crt=';'; crt++;
597                                         memcpy(crt,tmp,len);crt+=len;
598                                 }
599                                 /* headers */
600                                 tmp=uri.headers.s;
601                                 if (tmp){
602                                         len=uri.headers.len; if(crt+len+1>end) goto error_uri;
603                                         *crt='?'; crt++;
604                                         memcpy(crt,tmp,len);crt+=len;
605                                 }
606                                 *crt=0; /* null terminate the thing */
607                                 /* copy it to the msg */
608                                 if (msg->new_uri.s) pkg_free(msg->new_uri.s);
609                                 msg->new_uri.s=new_uri;
610                                 msg->new_uri.len=crt-new_uri;
611                                 msg->parsed_uri_ok=0;
612                                 ret=1;
613                                 break;
614                 case IF_T:
615                                 /* if null expr => ignore if? */
616                                 if ((a->val[0].type==EXPR_ST)&&a->val[0].u.data){
617                                         v=eval_expr((struct expr*)a->val[0].u.data, msg);
618 #if 0
619                                         if (v<0){
620                                                 if (v==EXPR_DROP){ /* hack to quit on DROP*/
621                                                         ret=0;
622                                                         break;
623                                                 }else{
624                                                         LOG(L_WARN,"WARNING: do_action:"
625                                                                                 "error in expression\n");
626                                                 }
627                                         }
628 #endif
629                                         if (run_flags & EXIT_R_F){
630                                                 ret=0;
631                                                 break;
632                                         }
633                                         run_flags &= ~RETURN_R_F; /* catch returns in expr */
634                                         ret=1;  /*default is continue */
635                                         if (v>0) {
636                                                 if ((a->val[1].type==ACTIONS_ST)&&a->val[1].u.data){
637                                                         ret=run_actions((struct action*)a->val[1].u.data, msg);
638                                                 }
639                                         }else if ((a->val[2].type==ACTIONS_ST)&&a->val[2].u.data){
640                                                         ret=run_actions((struct action*)a->val[2].u.data, msg);
641                                         }
642                                 }
643                         break;
644                 case MODULE_T:
645                         if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && ((cmd_export_t*)a->val[0].u.data)->function ){
646                                 ret=((cmd_export_t*)a->val[0].u.data)->function(msg,
647                                         (char*)a->val[2].u.data,
648                                         (char*)a->val[3].u.data
649                                 );
650                                 if (ret==0) run_flags|=EXIT_R_F;
651                         } else {
652                                 LOG(L_CRIT,"BUG: do_action: bad module call\n");
653                         }
654                         break;
655                 case FORCE_RPORT_T:
656                         msg->msg_flags|=FL_FORCE_RPORT;
657                         ret=1; /* continue processing */
658                         break;
659                 case SET_ADV_ADDR_T:
660                         if (a->val[0].type!=STR_ST){
661                                 LOG(L_CRIT, "BUG: do_action: bad set_advertised_address() "
662                                                 "type %d\n", a->val[0].type);
663                                 ret=E_BUG;
664                                 break;
665                         }
666                         msg->set_global_address=*((str*)a->val[0].u.data);
667                         ret=1; /* continue processing */
668                         break;
669                 case SET_ADV_PORT_T:
670                         if (a->val[0].type!=STR_ST){
671                                 LOG(L_CRIT, "BUG: do_action: bad set_advertised_port() "
672                                                 "type %d\n", a->val[0].type);
673                                 ret=E_BUG;
674                                 break;
675                         }
676                         msg->set_global_port=*((str*)a->val[0].u.data);
677                         ret=1; /* continue processing */
678                         break;
679 #ifdef USE_TCP
680                 case FORCE_TCP_ALIAS_T:
681                         if ( msg->rcv.proto==PROTO_TCP
682 #ifdef USE_TLS
683                                         || msg->rcv.proto==PROTO_TLS
684 #endif
685                            ){
686
687                                 if (a->val[0].type==NOSUBTYPE)  port=msg->via1->port;
688                                 else if (a->val[0].type==NUMBER_ST) port=(int)a->val[0].u.number;
689                                 else{
690                                         LOG(L_CRIT, "BUG: do_action: bad force_tcp_alias"
691                                                         " port type %d\n", a->val[0].type);
692                                         ret=E_BUG;
693                                         break;
694                                 }
695
696                                 if (tcpconn_add_alias(msg->rcv.proto_reserved1, port,
697                                                                         msg->rcv.proto)!=0){
698                                         LOG(L_ERR, " ERROR: receive_msg: tcp alias failed\n");
699                                         ret=E_UNSPEC;
700                                         break;
701                                 }
702                         }
703 #endif
704                         ret=1; /* continue processing */
705                         break;
706                 case FORCE_SEND_SOCKET_T:
707                         if (a->val[0].type!=SOCKETINFO_ST){
708                                 LOG(L_CRIT, "BUG: do_action: bad force_send_socket argument"
709                                                 " type: %d\n", a->val[0].type);
710                                 ret=E_BUG;
711                                 break;
712                         }
713                         msg->force_send_socket=(struct socket_info*)a->val[0].u.data;
714                         ret=1; /* continue processing */
715                         break;
716
717                 case ADD_T:
718                 case ASSIGN_T:
719
720                         /* If the left attr was specified withou indexing brackets delete
721                          * existing AVPs before adding new ones
722                          */
723                         if ((a->val[0].u.attr->type & AVP_INDEX_ALL) != AVP_INDEX_ALL) delete_avp(a->val[0].u.attr->type, a->val[0].u.attr->name);
724
725                         if (a->val[1].type == STRING_ST) {
726                                 value.s = a->val[1].u.str;
727                                 flags = a->val[0].u.attr->type | AVP_VAL_STR;
728                                 name = a->val[0].u.attr->name;
729                                 ret = 1;
730                         } else if (a->val[1].type == NUMBER_ST) {
731                                 value.n = a->val[1].u.number;
732                                 flags = a->val[0].u.attr->type;
733                                 name = a->val[0].u.attr->name;
734                                 ret = 1;
735                         } else if (a->val[1].type == ACTION_ST) {
736                                 flags = a->val[0].u.attr->type;
737                                 name = a->val[0].u.attr->name;
738                                 if (a->val[1].u.data) {
739                                         value.n = run_actions((struct action*)a->val[1].u.data, msg);
740                                 } else {
741                                         value.n = -1;
742                                 }
743                                 ret = value.n;
744                         } else if(a->val[1].type == EXPR_ST && a->val[1].u.data) {
745                                 v = eval_expr((struct expr*)a->val[1].u.data, msg);
746                                 if (v < 0) {
747                                         if (v == EXPR_DROP){ /* hack to quit on DROP*/
748                                                 ret = 0;
749                                                 break;
750                                         } else {
751                                                 LOG(L_WARN,"WARNING: do_action: error in expression\n");
752                                         }
753                                 }
754
755                                 flags = a->val[0].u.attr->type;
756                                 name = a->val[0].u.attr->name;
757                                 value.n = v;
758                         } else if (a->val[1].type == AVP_ST) {
759                                 struct search_state st;
760                                 avp_t* avp;
761                                 avp_t* avp_mark;
762
763                                 avp_mark = NULL;
764                                 if ((a->val[1].u.attr->type & AVP_INDEX_ALL) == AVP_INDEX_ALL) {
765                                         avp = search_first_avp(a->val[1].u.attr->type, a->val[1].u.attr->name, &value, &st);
766                                         while(avp) {
767                                                      /* We take only the type of value and name from the source avp
768                                                       * and reset class and track flags
769                                                       */
770                                                 flags = (a->val[0].u.attr->type & ~AVP_INDEX_ALL) | (avp->flags & ~(AVP_CLASS_ALL|AVP_TRACK_ALL));
771
772                                                 if (add_avp_before(avp_mark, flags, a->val[0].u.attr->name, value) < 0) {
773                                                         LOG(L_CRIT, "ERROR: Failed to assign value to attribute\n");
774                                                         ret=E_UNSPEC;
775                                                         break;
776                                                 }
777
778                                                 /* move the mark, so the next found AVP will come before the one currently added
779                                                  * so they will have the same order as in the source list
780                                                  */
781                                                 if (avp_mark) {
782                                                         avp_mark=avp_mark->next;
783                                                 } else {
784                                                         avp_mark=search_first_avp(flags, a->val[0].u.attr->name, NULL, NULL);
785                                                 }
786
787                                                 avp = search_next_avp(&st, &value);
788                                         }
789                                         ret = 1;
790                                         break;
791                                 } else {
792                                         avp = search_avp_by_index(a->val[1].u.attr->type, a->val[1].u.attr->name, &value, a->val[1].u.attr->index);
793                                         if (avp) {
794                                                 flags = a->val[0].u.attr->type | (avp->flags & ~(AVP_CLASS_ALL|AVP_TRACK_ALL));
795                                                 name = a->val[0].u.attr->name;
796                                                 ret = 1;
797                                         } else {
798                                                 ret = E_UNSPEC;
799                                                 break;
800                                         }
801                                 }
802                         } else if (a->val[1].type == SELECT_ST) {
803                                 int r;
804                                 r = run_select(&value.s, a->val[1].u.select, msg);
805                                 if (r < 0) {
806                                         ret=E_UNSPEC;
807                                         break;
808                                 } else if (r > 0) {
809                                         value.s.s = "";
810                                         value.s.len = 0;
811                                 }
812
813                                 flags = a->val[0].u.attr->type | AVP_VAL_STR;
814                                 name = a->val[0].u.attr->name;
815                                 ret = 1;
816                         } else {
817                                 LOG(L_CRIT, "BUG: do_action: Bad right side of avp assignment\n");
818                                 ret=E_BUG;
819                                 break;
820                         }
821
822                         /* If the action is assign then remove the old avp value
823                          * before adding new ones */
824 //                      if ((unsigned char)a->type == ASSIGN_T) delete_avp(flags, name);
825                         if (add_avp(flags & ~AVP_INDEX_ALL, name, value) < 0) {
826                                 LOG(L_CRIT, "ERROR: Failed to assign value to attribute\n");
827                                 ret=E_UNSPEC;
828                                 break;
829                         }
830                         break;
831
832                 default:
833                         LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
834         }
835 /*skip:*/
836         return ret;
837
838 error_uri:
839         LOG(L_ERR, "ERROR: do_action: set*: uri too long\n");
840         if (new_uri) pkg_free(new_uri);
841         return E_UNSPEC;
842 error_fwd_uri:
843         /*free_uri(&uri); -- not needed anymore, using msg->parsed_uri*/
844         return ret;
845 }
846
847
848
849 /* returns: 0, or 1 on success, <0 on error */
850 /* (0 if drop or break encountered, 1 if not ) */
851 int run_actions(struct action* a, struct sip_msg* msg)
852 {
853         struct action* t;
854         int ret=E_UNSPEC;
855         static int rec_lev=0;
856         static jmp_buf jmp_env;
857         struct sr_module *mod;
858
859         rec_lev++;
860         if (rec_lev>ROUTE_MAX_REC_LEV){
861                 LOG(L_ERR, "WARNING: too many recursive routing table lookups (%d)"
862                                         " giving up!\n", rec_lev);
863                 ret=E_UNSPEC;
864                 goto error;
865         }
866         if (rec_lev==1){
867                 run_flags=0;
868                 last_retcode=0;
869                 if (setjmp(jmp_env)){
870                         rec_lev=0;
871                         ret=last_retcode;
872                         goto end;
873                 }
874         }
875
876         if (a==0){
877                 LOG(L_ERR, "WARNING: run_actions: null action list (rec_level=%d)\n",
878                         rec_lev);
879                 ret=0;
880         }
881
882         for (t=a; t!=0; t=t->next){
883                 ret=do_action(t, msg);
884                 if (run_flags & (RETURN_R_F|EXIT_R_F)){
885                         if (run_flags & EXIT_R_F){
886                                 last_retcode=ret;
887                                 longjmp(jmp_env, ret);
888                         }
889                         break;
890                 }
891                 /* ignore error returns */
892         }
893
894         rec_lev--;
895 end:
896         /* process module onbreak handlers if present */
897         if (rec_lev==0 && ret==0)
898                 for (mod=modules;mod;mod=mod->next)
899                         if (mod->exports && mod->exports->onbreak_f) {
900                                 mod->exports->onbreak_f( msg );
901                                 DBG("DEBUG: %s onbreak handler called\n", mod->exports->name);
902                         }
903         return ret;
904
905
906 error:
907         rec_lev--;
908         return ret;
909 }
910
911
912