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