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