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