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