e39b53917e4dd8450b5ff67d1e890a97fef1e4ed
[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-11-18  support for variable parameter module functions (andrei)
50  *  2008-12-03  use lvalues/rvalues for assignments (andrei)
51  *  2008-12-17  added UDP_MTU_TRY_PROTO_T (andrei)
52  *  2009-05-04  switched IF_T to rval_expr (andrei)
53  *  2009-09-15  added SET_{FWD,RPL}_NO_CONNECT, SET_{FWD,RPL}_CLOSE (andrei)
54  */
55
56 /*!
57  * \file
58  * \brief SIP-router core :: 
59  * \ingroup core
60  * Module: \ref core
61  */
62
63
64
65 #include "comp_defs.h"
66
67 #include "action.h"
68 #include "config.h"
69 #include "error.h"
70 #include "dprint.h"
71 #include "proxy.h"
72 #include "forward.h"
73 #include "udp_server.h"
74 #include "route.h"
75 #include "parser/msg_parser.h"
76 #include "parser/parse_uri.h"
77 #include "ut.h"
78 #include "lvalue.h"
79 #include "sr_module.h"
80 #include "select_buf.h"
81 #include "mem/mem.h"
82 #include "globals.h"
83 #include "dset.h"
84 #include "onsend.h"
85 #include "resolve.h"
86 #ifdef USE_TCP
87 #include "tcp_server.h"
88 #endif
89 #ifdef USE_SCTP
90 #include "sctp_server.h"
91 #endif
92 #include "switch.h"
93 #include "events.h"
94
95 #include <sys/types.h>
96 #include <sys/socket.h>
97 #include <netdb.h>
98 #include <stdlib.h>
99 #include <netinet/in.h>
100 #include <arpa/inet.h>
101 #include <string.h>
102
103
104 #ifdef DEBUG_DMALLOC
105 #include <dmalloc.h>
106 #endif
107
108 int _last_returned_code  = 0;
109 struct onsend_info* p_onsend=0; /* onsend route send info */
110
111 /* ret= 0! if action -> end of list(e.g DROP),
112       > 0 to continue processing next actions
113    and <0 on error */
114 int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
115 {
116         int ret;
117         int v;
118         struct dest_info dst;
119         char* tmp;
120         char *new_uri, *end, *crt;
121         void* f;
122         int len;
123         int user;
124         struct sip_uri uri, next_hop;
125         struct sip_uri *u;
126         unsigned short port;
127         str* dst_host;
128         int i, flags;
129         struct switch_cond_table* sct;
130         struct switch_jmp_table*  sjt;
131         struct rval_expr* rve;
132         struct match_cond_table* mct;
133         struct rvalue* rv;
134         struct rvalue* rv1;
135         struct rval_cache c1;
136         str s;
137         void *srevp[2];
138
139         /* reset the value of error to E_UNSPEC so avoid unknowledgable
140            functions to return with error (status<0) and not setting it
141            leaving there previous error; cache the previous value though
142            for functions which want to process it */
143         prev_ser_error=ser_error;
144         ser_error=E_UNSPEC;
145
146         /* hook for every executed action (in use by cfg debugger) */
147         if(unlikely(sr_event_enabled(SREV_CFG_RUN_ACTION)))
148         {
149                 srevp[0] = (void*)a;
150                 srevp[1] = (void*)msg;
151                 sr_event_exec(SREV_CFG_RUN_ACTION, (void*)srevp);
152         }
153
154         ret=E_BUG;
155         switch ((unsigned char)a->type){
156                 case DROP_T:
157                                 switch(a->val[0].type){
158                                         case NUMBER_ST:
159                                                 ret=(int) a->val[0].u.number;
160                                                 break;
161                                         case RVE_ST:
162                                                 rve=(struct rval_expr*)a->val[0].u.data;
163                                                 rval_expr_eval_int(h, msg, &ret, rve);
164                                                 break;
165                                         case RETCODE_ST:
166                                                 ret=h->last_retcode;
167                                                 break;
168                                         default:
169                                                 BUG("unexpected subtype %d in DROP_T\n",
170                                                                 a->val[0].type);
171                                                 ret=0;
172                                                 goto error;
173                                 }
174                                 h->run_flags|=(unsigned int)a->val[1].u.number;
175                         break;
176                 case FORWARD_T:
177 #ifdef USE_TCP
178                 case FORWARD_TCP_T:
179 #endif
180 #ifdef USE_TLS
181                 case FORWARD_TLS_T:
182 #endif
183 #ifdef USE_SCTP
184                 case FORWARD_SCTP_T:
185 #endif
186                 case FORWARD_UDP_T:
187                         /* init dst */
188                         init_dest_info(&dst);
189                         if (a->type==FORWARD_UDP_T) dst.proto=PROTO_UDP;
190 #ifdef USE_TCP
191                         else if (a->type==FORWARD_TCP_T) dst.proto= PROTO_TCP;
192 #endif
193 #ifdef USE_TLS
194                         else if (a->type==FORWARD_TLS_T) dst.proto= PROTO_TLS;
195 #endif
196 #ifdef USE_SCTP
197                         else if (a->type==FORWARD_SCTP_T) dst.proto=PROTO_SCTP;
198 #endif
199                         else dst.proto=PROTO_NONE;
200                         if (a->val[0].type==URIHOST_ST){
201                                 /*parse uri*/
202
203                                 if (msg->dst_uri.len) {
204                                         ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len,
205                                                                         &next_hop);
206                                         u = &next_hop;
207                                 } else {
208                                         ret = parse_sip_msg_uri(msg);
209                                         u = &msg->parsed_uri;
210                                 }
211
212                                 if (ret<0) {
213                                         LOG(L_ERR, "ERROR: do_action: forward: bad_uri "
214                                                                 " dropping packet\n");
215                                         goto error;
216                                 }
217
218                                 switch (a->val[1].type){
219                                         case URIPORT_ST:
220                                                                         port=u->port_no;
221                                                                         break;
222                                         case NUMBER_ST:
223                                                                         port=a->val[1].u.number;
224                                                                         break;
225                                         default:
226                                                         LOG(L_CRIT, "BUG: do_action bad forward 2nd"
227                                                                                 " param type (%d)\n", a->val[1].type);
228                                                         ret=E_UNSPEC;
229                                                         goto error_fwd_uri;
230                                 }
231                                 if (dst.proto == PROTO_NONE){ /* only if proto not set get it
232                                                                                          from the uri */
233                                         switch(u->proto){
234                                                 case PROTO_NONE:
235                                                         /*dst.proto=PROTO_UDP; */
236                                                         /* no proto, try to get it from the dns */
237                                                         break;
238                                                 case PROTO_UDP:
239 #ifdef USE_TCP
240                                                 case PROTO_TCP:
241 #endif
242 #ifdef USE_TLS
243                                                 case PROTO_TLS:
244 #endif
245 #ifdef USE_SCTP
246                                                 case PROTO_SCTP:
247 #endif
248                                                         dst.proto=u->proto;
249                                                         break;
250                                                 default:
251                                                         LOG(L_ERR,"ERROR: do action: forward: bad uri"
252                                                                         " transport %d\n", u->proto);
253                                                         ret=E_BAD_PROTO;
254                                                         goto error_fwd_uri;
255                                         }
256 #ifdef USE_TLS
257                                         if (u->type==SIPS_URI_T){
258                                                 if (u->proto==PROTO_UDP){
259                                                         LOG(L_ERR, "ERROR: do_action: forward: secure uri"
260                                                                         " incompatible with transport %d\n",
261                                                                         u->proto);
262                                                         ret=E_BAD_PROTO;
263                                                         goto error_fwd_uri;
264                                                 }
265                                                 dst.proto=PROTO_TLS;
266                                         }
267 #endif
268                                 }
269
270 #ifdef HONOR_MADDR
271                                 if (u->maddr_val.s && u->maddr_val.len)
272                                         dst_host=&u->maddr_val;
273                                 else
274 #endif
275                                         dst_host=&u->host;
276 #ifdef USE_COMP
277                                 dst.comp=u->comp;
278 #endif
279                                 ret=forward_request(msg, dst_host, port, &dst);
280                                 if (ret>=0){
281                                         ret=1;
282                                 }
283                         }else if ((a->val[0].type==PROXY_ST) && (a->val[1].type==NUMBER_ST)){
284                                 if (dst.proto==PROTO_NONE)
285                                         dst.proto=msg->rcv.proto;
286                                 proxy2su(&dst.to,  (struct proxy_l*)a->val[0].u.data);
287                                 ret=forward_request(msg, 0, 0, &dst);
288                                 if (ret>=0){
289                                         ret=1;
290                                         proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
291                                 }else if (ser_error!=E_OK){
292                                         proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
293                                 }
294                         }else{
295                                 LOG(L_CRIT, "BUG: do_action: bad forward() types %d, %d\n",
296                                                 a->val[0].type, a->val[1].type);
297                                 ret=E_BUG;
298                                 goto error;
299                         }
300                         break;
301                 case SEND_T:
302                 case SEND_TCP_T:
303                         if ((a->val[0].type!= PROXY_ST)|(a->val[1].type!=NUMBER_ST)){
304                                 LOG(L_CRIT, "BUG: do_action: bad send() types %d, %d\n",
305                                                 a->val[0].type, a->val[1].type);
306                                 ret=E_BUG;
307                                 goto error;
308                         }
309                         /* init dst */
310                         init_dest_info(&dst);
311                         ret=proxy2su(&dst.to,  (struct proxy_l*)a->val[0].u.data);
312                         if (ret==0){
313                                 if (p_onsend){
314                                         tmp=p_onsend->buf;
315                                         len=p_onsend->len;
316                                 }else{
317                                         tmp=msg->buf;
318                                         len=msg->len;
319                                 }
320                                 if (a->type==SEND_T){
321                                         /*udp*/
322                                         dst.proto=PROTO_UDP; /* not really needed for udp_send */
323                                         dst.send_sock=get_send_socket(msg, &dst.to, PROTO_UDP);
324                                         if (dst.send_sock!=0){
325                                                 ret=udp_send(&dst, tmp, len);
326                                         }else{
327                                                 ret=-1;
328                                         }
329                                 }
330 #ifdef USE_TCP
331                                         else{
332                                                 /*tcp*/
333                                                 dst.proto=PROTO_TCP;
334                                                 dst.id=0;
335                                                 ret=tcp_send(&dst, 0, tmp, len);
336                                 }
337 #endif
338                         }else{
339                                 ret=E_BUG;
340                                 goto error;
341                         }
342                         proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
343                         if (ret>=0) ret=1;
344
345                         break;
346                 case LOG_T:
347                         if ((a->val[0].type!=NUMBER_ST)|(a->val[1].type!=STRING_ST)){
348                                 LOG(L_CRIT, "BUG: do_action: bad log() types %d, %d\n",
349                                                 a->val[0].type, a->val[1].type);
350                                 ret=E_BUG;
351                                 goto error;
352                         }
353                         LOG_(DEFAULT_FACILITY, a->val[0].u.number, "<script>: ", "%s", 
354                                  a->val[1].u.string);
355                         ret=1;
356                         break;
357
358                 /* jku -- introduce a new branch */
359                 case APPEND_BRANCH_T:
360                         if (unlikely(a->val[0].type!=STR_ST)) {
361                                 LOG(L_CRIT, "BUG: do_action: bad append_branch_t %d\n",
362                                         a->val[0].type );
363                                 ret=E_BUG;
364                                 goto error;
365                         }
366                         getbflagsval(0, (flag_t*)&flags);
367                         ret=append_branch(msg, &a->val[0].u.str, &msg->dst_uri,
368                                                                 &msg->path_vec, a->val[1].u.number,
369                                                                 (flag_t)flags, msg->force_send_socket);
370                         break;
371
372                 /* jku begin: is_length_greater_than */
373                 case LEN_GT_T:
374                         if (a->val[0].type!=NUMBER_ST) {
375                                 LOG(L_CRIT, "BUG: do_action: bad len_gt type %d\n",
376                                         a->val[0].type );
377                                 ret=E_BUG;
378                                 goto error;
379                         }
380                         /* DBG("XXX: message length %d, max %d\n",
381                                 msg->len, a->val[0].u.number ); */
382                         ret = msg->len >= a->val[0].u.number ? 1 : -1;
383                         break;
384                 /* jku end: is_length_greater_than */
385
386                 /* jku - begin : flag processing */
387
388                 case SETFLAG_T:
389                         if (a->val[0].type!=NUMBER_ST) {
390                                 LOG(L_CRIT, "BUG: do_action: bad setflag() type %d\n",
391                                         a->val[0].type );
392                                 ret=E_BUG;
393                                 goto error;
394                         }
395                         if (!flag_in_range( a->val[0].u.number )) {
396                                 ret=E_CFG;
397                                 goto error;
398                         }
399                         setflag( msg, a->val[0].u.number );
400                         ret=1;
401                         break;
402
403                 case RESETFLAG_T:
404                         if (a->val[0].type!=NUMBER_ST) {
405                                 LOG(L_CRIT, "BUG: do_action: bad resetflag() type %d\n",
406                                         a->val[0].type );
407                                 ret=E_BUG;
408                                 goto error;
409                         }
410                         if (!flag_in_range( a->val[0].u.number )) {
411                                 ret=E_CFG;
412                                 goto error;
413                         }
414                         resetflag( msg, a->val[0].u.number );
415                         ret=1;
416                         break;
417
418                 case ISFLAGSET_T:
419                         if (a->val[0].type!=NUMBER_ST) {
420                                 LOG(L_CRIT, "BUG: do_action: bad isflagset() type %d\n",
421                                         a->val[0].type );
422                                 ret=E_BUG;
423                                 goto error;
424                         }
425                         if (!flag_in_range( a->val[0].u.number )) {
426                                 ret=E_CFG;
427                                 goto error;
428                         }
429                         ret=isflagset( msg, a->val[0].u.number );
430                         break;
431                 /* jku - end : flag processing */
432
433                 case AVPFLAG_OPER_T:  {
434                         struct search_state st;
435                         avp_t* avp;
436                         int flag;
437                         ret = 0;
438                         flag = a->val[1].u.number;
439                         if ((a->val[0].u.attr->type & AVP_INDEX_ALL) == AVP_INDEX_ALL || (a->val[0].u.attr->type & AVP_NAME_RE)!=0) {
440                                 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)) {
441                                         switch (a->val[2].u.number) {   /* oper: 0..reset, 1..set, -1..no change */
442                                                 case 0:
443                                                         avp->flags &= ~(avp_flags_t)a->val[1].u.number;
444                                                         break;
445                                                 case 1:
446                                                         avp->flags |= (avp_flags_t)a->val[1].u.number;
447                                                         break;
448                                                 default:;
449                                         }
450                                         ret = ret || ((avp->flags & (avp_flags_t)a->val[1].u.number) != 0);
451                                 }
452                         }
453                         else {
454                                 avp = search_avp_by_index(a->val[0].u.attr->type, a->val[0].u.attr->name, NULL, a->val[0].u.attr->index);
455                                 if (avp) {
456                                         switch (a->val[2].u.number) {   /* oper: 0..reset, 1..set, -1..no change */
457                                                 case 0:
458                                                         avp->flags &= ~(avp_flags_t)a->val[1].u.number;
459                                                         break;
460                                                 case 1:
461                                                         avp->flags |= (avp_flags_t)a->val[1].u.number;
462                                                         break;
463                                                 default:;
464                                         }
465                                         ret = (avp->flags & (avp_flags_t)a->val[1].u.number) != 0;
466                                 }
467                         }
468                         if (ret==0)
469                                 ret = -1;
470                         break;
471                 }
472                 case ERROR_T:
473                         if ((a->val[0].type!=STRING_ST)|(a->val[1].type!=STRING_ST)){
474                                 LOG(L_CRIT, "BUG: do_action: bad error() types %d, %d\n",
475                                                 a->val[0].type, a->val[1].type);
476                                 ret=E_BUG;
477                                 goto error;
478                         }
479                         LOG(L_NOTICE, "WARNING: do_action: error(\"%s\", \"%s\") "
480                                         "not implemented yet\n", a->val[0].u.string, a->val[1].u.string);
481                         ret=1;
482                         break;
483                 case ROUTE_T:
484                         if (a->val[0].type!=NUMBER_ST){
485                                 LOG(L_CRIT, "BUG: do_action: bad route() type %d\n",
486                                                 a->val[0].type);
487                                 ret=E_BUG;
488                                 goto error;
489                         }
490                         if ((a->val[0].u.number>=main_rt.idx)||(a->val[0].u.number<0)){
491                                 LOG(L_ERR, "ERROR: invalid routing table number in"
492                                                         "route(%lu)\n", a->val[0].u.number);
493                                 ret=E_CFG;
494                                 goto error;
495                         }
496                         /*ret=((ret=run_actions(rlist[a->val[0].u.number], msg))<0)?ret:1;*/
497                         ret=run_actions(h, main_rt.rlist[a->val[0].u.number], msg);
498                         h->last_retcode=ret;
499                         _last_returned_code = h->last_retcode;
500                         h->run_flags&=~(RETURN_R_F|BREAK_R_F); /* absorb return & break */
501                         break;
502                 case EXEC_T:
503                         if (a->val[0].type!=STRING_ST){
504                                 LOG(L_CRIT, "BUG: do_action: bad exec() type %d\n",
505                                                 a->val[0].type);
506                                 ret=E_BUG;
507                                 goto error;
508                         }
509                         LOG(L_NOTICE, "WARNING: exec(\"%s\") not fully implemented,"
510                                                 " using dumb version...\n", a->val[0].u.string);
511                         ret=system(a->val[0].u.string);
512                         if (ret!=0){
513                                 LOG(L_NOTICE, "WARNING: exec() returned %d\n", ret);
514                         }
515                         ret=1;
516                         break;
517                 case REVERT_URI_T:
518                         if (msg->new_uri.s) {
519                                 pkg_free(msg->new_uri.s);
520                                 msg->new_uri.len=0;
521                                 msg->new_uri.s=0;
522                                 msg->parsed_uri_ok=0; /* invalidate current parsed uri*/
523                         };
524                         ret=1;
525                         break;
526                 case SET_HOST_T:
527                 case SET_HOSTPORT_T:
528                 case SET_HOSTPORTTRANS_T:
529                 case SET_HOSTALL_T:
530                 case SET_USER_T:
531                 case SET_USERPASS_T:
532                 case SET_PORT_T:
533                 case SET_URI_T:
534                 case PREFIX_T:
535                 case STRIP_T:
536                 case STRIP_TAIL_T:
537                 case SET_USERPHONE_T:
538                                 user=0;
539                                 if (a->type==STRIP_T || a->type==STRIP_TAIL_T) {
540                                         if (a->val[0].type!=NUMBER_ST) {
541                                                 LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
542                                                         a->val[0].type);
543                                                 ret=E_BUG;
544                                                 goto error;
545                                         }
546                                 } else if (a->type!=SET_USERPHONE_T) {
547                                         if (a->val[0].type!=STRING_ST) {
548                                                 LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
549                                                         a->val[0].type);
550                                                 ret=E_BUG;
551                                                 goto error;
552                                         }
553                                 }
554                                 if (a->type==SET_URI_T){
555                                         if (msg->new_uri.s) {
556                                                         pkg_free(msg->new_uri.s);
557                                                         msg->new_uri.len=0;
558                                         }
559                                         msg->parsed_uri_ok=0;
560                                         len=strlen(a->val[0].u.string);
561                                         msg->new_uri.s=pkg_malloc(len+1);
562                                         if (msg->new_uri.s==0){
563                                                 LOG(L_ERR, "ERROR: do_action: memory allocation"
564                                                                 " failure\n");
565                                                 ret=E_OUT_OF_MEM;
566                                                 goto error;
567                                         }
568                                         memcpy(msg->new_uri.s, a->val[0].u.string, len);
569                                         msg->new_uri.s[len]=0;
570                                         msg->new_uri.len=len;
571
572                                         ret=1;
573                                         break;
574                                 }
575                                 if (msg->parsed_uri_ok==0) {
576                                         if (msg->new_uri.s) {
577                                                 tmp=msg->new_uri.s;
578                                                 len=msg->new_uri.len;
579                                         }else{
580                                                 tmp=msg->first_line.u.request.uri.s;
581                                                 len=msg->first_line.u.request.uri.len;
582                                         }
583                                         if (parse_uri(tmp, len, &uri)<0){
584                                                 LOG(L_ERR, "ERROR: do_action: bad uri <%s>, dropping"
585                                                                         " packet\n", tmp);
586                                                 ret=E_UNSPEC;
587                                                 goto error;
588                                         }
589                                 } else {
590                                         uri=msg->parsed_uri;
591                                 }
592
593                                 /* skip SET_USERPHONE_T action if the URI is already
594                                  * a tel: or tels: URI, or contains the user=phone param */
595                                 if ((a->type==SET_USERPHONE_T) 
596                                         && ((uri.type==TEL_URI_T) || (uri.type==TELS_URI_T)
597                                                 || ((uri.user_param_val.len==5) && (memcmp(uri.user_param_val.s, "phone", 5)==0)))
598                                 ) {
599                                         ret=1;
600                                         break;
601                                 }
602                                 /* SET_PORT_T does not work with tel: URIs */
603                                 if ((a->type==SET_PORT_T)
604                                         && ((uri.type==TEL_URI_T) || (uri.type==TELS_URI_T))
605                                         && ((uri.flags & URI_SIP_USER_PHONE)==0)
606                                 ) {
607                                         LOG(L_ERR, "ERROR: do_action: port number of a tel: URI cannot be set\n");
608                                         ret=E_UNSPEC;
609                                         goto error;
610                                 }
611
612                                 new_uri=pkg_malloc(MAX_URI_SIZE);
613                                 if (new_uri==0){
614                                         LOG(L_ERR, "ERROR: do_action: memory allocation "
615                                                                 " failure\n");
616                                         ret=E_OUT_OF_MEM;
617                                         goto error;
618                                 }
619                                 end=new_uri+MAX_URI_SIZE;
620                                 crt=new_uri;
621                                 /* begin copying */
622                                 /* Preserve the URI scheme unless the host part needs
623                                  * to be rewritten, and the shceme is tel: or tels: */
624                                 switch (uri.type) {
625                                 case SIP_URI_T:
626                                         len=s_sip.len;
627                                         tmp=s_sip.s;
628                                         break;
629
630                                 case SIPS_URI_T:
631                                         len=s_sips.len;
632                                         tmp=s_sips.s;
633                                         break;
634
635                                 case TEL_URI_T:
636                                         if ((uri.flags & URI_SIP_USER_PHONE)
637                                                 || (a->type==SET_HOST_T)
638                                                 || (a->type==SET_HOSTPORT_T)
639                                                 || (a->type==SET_HOSTPORTTRANS_T)
640                                         ) {
641                                                 len=s_sip.len;
642                                                 tmp=s_sip.s;
643                                                 break;
644                                         }
645                                         len=s_tel.len;
646                                         tmp=s_tel.s;
647                                         break;
648
649                                 case TELS_URI_T:
650                                         if ((uri.flags & URI_SIP_USER_PHONE)
651                                                 || (a->type==SET_HOST_T)
652                                                 || (a->type==SET_HOSTPORT_T)
653                                                 || (a->type==SET_HOSTPORTTRANS_T)
654                                         ) {
655                                                 len=s_sips.len;
656                                                 tmp=s_sips.s;
657                                                 break;
658                                         }
659                                         len=s_tels.len;
660                                         tmp=s_tels.s;
661                                         break;
662
663                                 default:
664                                         LOG(L_ERR, "ERROR: Unsupported URI scheme (%d), "
665                                                 "reverted to sip:\n",
666                                                 uri.type);
667                                         len=s_sip.len;
668                                         tmp=s_sip.s;
669                                 }
670                                 if(crt+len+1 /* colon */ >end) goto error_uri;
671                                 memcpy(crt,tmp,len);crt+=len;
672                                 *crt=':'; crt++;
673
674                                 /* user */
675
676                                 /* prefix (-jiri) */
677                                 if (a->type==PREFIX_T) {
678                                         tmp=a->val[0].u.string;
679                                         len=strlen(tmp); if(crt+len>end) goto error_uri;
680                                         memcpy(crt,tmp,len);crt+=len;
681                                         /* whatever we had before, with prefix we have username
682                                            now */
683                                         user=1;
684                                 }
685
686                                 if ((a->type==SET_USER_T)||(a->type==SET_USERPASS_T)) {
687                                         tmp=a->val[0].u.string;
688                                         len=strlen(tmp);
689                                 } else if (a->type==STRIP_T) {
690                                         if (a->val[0].u.number>uri.user.len) {
691                                                 LOG(L_WARN, "Error: too long strip asked; "
692                                                                         " deleting username: %lu of <%.*s>\n",
693                                                                         a->val[0].u.number, uri.user.len, uri.user.s );
694                                                 len=0;
695                                         } else if (a->val[0].u.number==uri.user.len) {
696                                                 len=0;
697                                         } else {
698                                                 tmp=uri.user.s + a->val[0].u.number;
699                                                 len=uri.user.len - a->val[0].u.number;
700                                         }
701                                 } else if (a->type==STRIP_TAIL_T) {
702                                         if (a->val[0].u.number>uri.user.len) {
703                                                 LOG(L_WARN, "WARNING: too long strip_tail asked; "
704                                                                         " deleting username: %lu of <%.*s>\n",
705                                                                         a->val[0].u.number, uri.user.len, uri.user.s );
706                                                 len=0;
707                                         } else if (a->val[0].u.number==uri.user.len) {
708                                                 len=0;
709                                         } else {
710                                                 tmp=uri.user.s;
711                                                 len=uri.user.len - a->val[0].u.number;
712                                         }
713                                 } else {
714                                         tmp=uri.user.s;
715                                         len=uri.user.len;
716                                 }
717
718                                 if (len){
719                                         if(crt+len>end) goto error_uri;
720                                         memcpy(crt,tmp,len);crt+=len;
721                                         user=1; /* we have an user field so mark it */
722                                 }
723
724                                 if (a->type==SET_USERPASS_T) tmp=0;
725                                 else tmp=uri.passwd.s;
726                                 /* passwd */
727                                 if (tmp){
728                                         len=uri.passwd.len; if(crt+len+1>end) goto error_uri;
729                                         *crt=':'; crt++;
730                                         memcpy(crt,tmp,len);crt+=len;
731                                 }
732                                 /* tel: URI parameters */
733                                 if ((uri.type==TEL_URI_T)
734                                         || (uri.type==TELS_URI_T)
735                                 ) {
736                                         tmp=uri.params.s;
737                                         if (tmp){
738                                                 len=uri.params.len; if(crt+len+1>end) goto error_uri;
739                                                 *crt=';'; crt++;
740                                                 memcpy(crt,tmp,len);crt+=len;
741                                         }
742                                 }
743                                 /* host */
744                                 if ((a->type==SET_HOST_T)
745                                                 || (a->type==SET_HOSTPORT_T)
746                                                 || (a->type==SET_HOSTALL_T)
747                                                 || (a->type==SET_HOSTPORTTRANS_T)
748                                 ) {
749                                         tmp=a->val[0].u.string;
750                                         if (tmp) len = strlen(tmp);
751                                         else len=0;
752                                 } else if ((uri.type==SIP_URI_T)
753                                         || (uri.type==SIPS_URI_T)
754                                         || (uri.flags & URI_SIP_USER_PHONE)
755                                 ) {
756                                         tmp=uri.host.s;
757                                         len=uri.host.len;
758                                 } else {
759                                         tmp=0;
760                                 }
761                                 if (tmp){
762                                         if (user) { /* add @ */
763                                                 if(crt+1>end) goto error_uri;
764                                                 *crt='@'; crt++;
765                                         }
766                                         if(crt+len>end) goto error_uri;
767                                         memcpy(crt,tmp,len);crt+=len;
768                                 }
769                                 if(a->type==SET_HOSTALL_T)
770                                         goto done_seturi;
771                                 /* port */
772                                 if ((a->type==SET_HOSTPORT_T)
773                                                 || (a->type==SET_HOSTPORTTRANS_T))
774                                         tmp=0;
775                                 else if (a->type==SET_PORT_T) {
776                                         tmp=a->val[0].u.string;
777                                         if (tmp) len = strlen(tmp);
778                                         else len = 0;
779                                 } else {
780                                         tmp=uri.port.s;
781                                         len = uri.port.len;
782                                 }
783                                 if (tmp){
784                                         if(crt+len+1>end) goto error_uri;
785                                         *crt=':'; crt++;
786                                         memcpy(crt,tmp,len);crt+=len;
787                                 }
788                                 /* params */
789                                 if ((a->type==SET_HOSTPORTTRANS_T)
790                                         && uri.sip_params.s
791                                         && uri.transport.s
792                                 ) {
793                                         /* bypass the transport parameter */
794                                         if (uri.sip_params.s < uri.transport.s) {
795                                                 /* there are parameters before transport */
796                                                 len = uri.transport.s - uri.sip_params.s - 1;
797                                                         /* ignore the ';' at the end */
798                                                 if (crt+len+1>end) goto error_uri;
799                                                 *crt=';'; crt++;
800                                                 memcpy(crt,uri.sip_params.s,len);crt+=len;
801                                         }
802                                         len = (uri.sip_params.s + uri.sip_params.len) -
803                                                 (uri.transport.s + uri.transport.len);
804                                         if (len > 0) {
805                                                 /* there are parameters after transport */
806                                                 if (crt+len>end) goto error_uri;
807                                                 tmp = uri.transport.s + uri.transport.len;
808                                                 memcpy(crt,tmp,len);crt+=len;
809                                         }
810                                 } else {
811                                         tmp=uri.sip_params.s;
812                                         if (tmp){
813                                                 len=uri.sip_params.len; if(crt+len+1>end) goto error_uri;
814                                                 *crt=';'; crt++;
815                                                 memcpy(crt,tmp,len);crt+=len;
816                                         }
817                                 }
818                                 /* Add the user=phone param if a tel: or tels:
819                                  * URI was converted to sip: or sips:.
820                                  * (host part of a tel/tels URI was set.)
821                                  * Or in case of sip: URI and SET_USERPHONE_T action */
822                                 if (((((uri.type==TEL_URI_T) || (uri.type==TELS_URI_T))
823                                         && ((uri.flags & URI_SIP_USER_PHONE)==0))
824                                         && ((a->type==SET_HOST_T)
825                                                 || (a->type==SET_HOSTPORT_T)
826                                                 || (a->type==SET_HOSTPORTTRANS_T)))
827                                         || (a->type==SET_USERPHONE_T)
828                                 ) {
829                                         tmp=";user=phone";
830                                         len=strlen(tmp);
831                                         if(crt+len>end) goto error_uri;
832                                         memcpy(crt,tmp,len);crt+=len;
833                                 }
834                                 /* headers */
835                                 tmp=uri.headers.s;
836                                 if (tmp){
837                                         len=uri.headers.len; if(crt+len+1>end) goto error_uri;
838                                         *crt='?'; crt++;
839                                         memcpy(crt,tmp,len);crt+=len;
840                                 }
841         done_seturi:
842                                 *crt=0; /* null terminate the thing */
843                                 /* copy it to the msg */
844                                 if (msg->new_uri.s) pkg_free(msg->new_uri.s);
845                                 msg->new_uri.s=new_uri;
846                                 msg->new_uri.len=crt-new_uri;
847                                 msg->parsed_uri_ok=0;
848                                 ret=1;
849                                 break;
850                 case IF_T:
851                                         rve=(struct rval_expr*)a->val[0].u.data;
852                                         if (unlikely(rval_expr_eval_int(h, msg, &v, rve) != 0)){
853                                                 ERR("if expression evaluation failed (%d,%d-%d,%d)\n",
854                                                                 rve->fpos.s_line, rve->fpos.s_col,
855                                                                 rve->fpos.e_line, rve->fpos.e_col);
856                                                 v=0; /* false */
857                                         }
858                                         if (unlikely(h->run_flags & EXIT_R_F)){
859                                                 ret=0;
860                                                 break;
861                                         }
862                                         h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return &
863                                                                                                                             break in expr*/
864                                         ret=1;  /*default is continue */
865                                         if (v>0) {
866                                                 if ((a->val[1].type==ACTIONS_ST)&&a->val[1].u.data){
867                                                         ret=run_actions(h,
868                                                                                 (struct action*)a->val[1].u.data, msg);
869                                                 }
870                                         }else if ((a->val[2].type==ACTIONS_ST)&&a->val[2].u.data){
871                                                         ret=run_actions(h,
872                                                                                 (struct action*)a->val[2].u.data, msg);
873                                         }
874                         break;
875                 case MODULE_T:
876                         if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
877                                         (f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
878                                 ret=((cmd_function)f)(msg,
879                                                                                 (char*)a->val[2].u.data,
880                                                                                 (char*)a->val[3].u.data
881                                                                         );
882                                 if (ret==0) h->run_flags|=EXIT_R_F;
883                                 h->last_retcode=ret;
884                                 _last_returned_code = h->last_retcode;
885                         } else {
886                                 LOG(L_CRIT,"BUG: do_action: bad module call\n");
887                                 goto error;
888                         }
889                         break;
890                 /* instead of using the parameter number, we use different names
891                  * for calls to functions with 3, 4, 5, 6 or variable number of
892                  * parameters due to performance reasons */
893                 case MODULE3_T:
894                         if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
895                                         (f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
896                                 ret=((cmd_function3)f)(msg,
897                                                                                 (char*)a->val[2].u.data,
898                                                                                 (char*)a->val[3].u.data,
899                                                                                 (char*)a->val[4].u.data
900                                                                         );
901                                 if (ret==0) h->run_flags|=EXIT_R_F;
902                                 h->last_retcode=ret;
903                                 _last_returned_code = h->last_retcode;
904                         } else {
905                                 LOG(L_CRIT,"BUG: do_action: bad module call\n");
906                                 goto error;
907                         }
908                         break;
909                 case MODULE4_T:
910                         if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
911                                         (f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
912                                 ret=((cmd_function4)f)(msg,
913                                                                                 (char*)a->val[2].u.data,
914                                                                                 (char*)a->val[3].u.data,
915                                                                                 (char*)a->val[4].u.data,
916                                                                                 (char*)a->val[5].u.data
917                                                                         );
918                                 if (ret==0) h->run_flags|=EXIT_R_F;
919                                 h->last_retcode=ret;
920                                 _last_returned_code = h->last_retcode;
921                         } else {
922                                 LOG(L_CRIT,"BUG: do_action: bad module call\n");
923                                 goto error;
924                         }
925                         break;
926                 case MODULE5_T:
927                         if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
928                                         (f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
929                                 ret=((cmd_function5)f)(msg,
930                                                                                 (char*)a->val[2].u.data,
931                                                                                 (char*)a->val[3].u.data,
932                                                                                 (char*)a->val[4].u.data,
933                                                                                 (char*)a->val[5].u.data,
934                                                                                 (char*)a->val[6].u.data
935                                                                         );
936                                 if (ret==0) h->run_flags|=EXIT_R_F;
937                                 h->last_retcode=ret;
938                                 _last_returned_code = h->last_retcode;
939                         } else {
940                                 LOG(L_CRIT,"BUG: do_action: bad module call\n");
941                                 goto error;
942                         }
943                         break;
944                 case MODULE6_T:
945                         if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
946                                         (f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
947                                 ret=((cmd_function6)f)(msg,
948                                                                                 (char*)a->val[2].u.data,
949                                                                                 (char*)a->val[3].u.data,
950                                                                                 (char*)a->val[4].u.data,
951                                                                                 (char*)a->val[5].u.data,
952                                                                                 (char*)a->val[6].u.data,
953                                                                                 (char*)a->val[7].u.data
954                                                                         );
955                                 if (ret==0) h->run_flags|=EXIT_R_F;
956                                 h->last_retcode=ret;
957                                 _last_returned_code = h->last_retcode;
958                         } else {
959                                 LOG(L_CRIT,"BUG: do_action: bad module call\n");
960                                 goto error;
961                         }
962                         break;
963                 case MODULEX_T:
964                         if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && 
965                                         (f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
966                                 ret=((cmd_function_var)f)(msg,
967                                                                                         a->val[1].u.number,
968                                                                                         &a->val[2]
969                                                                                 );
970                                 if (ret==0) h->run_flags|=EXIT_R_F;
971                                 h->last_retcode=ret;
972                                 _last_returned_code = h->last_retcode;
973                         } else {
974                                 LOG(L_CRIT,"BUG: do_action: bad module call\n");
975                                 goto error;
976                         }
977                         break;
978                 case EVAL_T:
979                         /* only eval the expression to account for possible
980                            side-effect */
981                         rval_expr_eval_int(h, msg, &v,
982                                         (struct rval_expr*)a->val[0].u.data);
983                         if (h->run_flags & EXIT_R_F){
984                                 ret=0;
985                                 break;
986                         }
987                         h->run_flags &= ~RETURN_R_F|BREAK_R_F; /* catch return & break in
988                                                                                                           expr */
989                         ret=1; /* default is continue */
990                         break;
991                 case SWITCH_COND_T:
992                         sct=(struct switch_cond_table*)a->val[1].u.data;
993                         if (unlikely( rval_expr_eval_int(h, msg, &v,
994                                                                         (struct rval_expr*)a->val[0].u.data) <0)){
995                                 /* handle error in expression => use default */
996                                 ret=-1;
997                                 goto sw_cond_def;
998                         }
999                         if (h->run_flags & EXIT_R_F){
1000                                 ret=0;
1001                                 break;
1002                         }
1003                         h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return & break
1004                                                                                                             in expr */
1005                         ret=1; /* default is continue */
1006                         for(i=0; i<sct->n; i++)
1007                                 if (sct->cond[i]==v){
1008                                         if (likely(sct->jump[i])){
1009                                                 ret=run_actions(h, sct->jump[i], msg);
1010                                                 h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
1011                                                                                                            returns passthrough */
1012                                         }
1013                                         goto skip;
1014                                 }
1015 sw_cond_def:
1016                         if (sct->def){
1017                                 ret=run_actions(h, sct->def, msg);
1018                                 h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
1019                                                                                            returns passthrough */
1020                         }
1021                         break;
1022                 case SWITCH_JT_T:
1023                         sjt=(struct switch_jmp_table*)a->val[1].u.data;
1024                         if (unlikely( rval_expr_eval_int(h, msg, &v,
1025                                                                         (struct rval_expr*)a->val[0].u.data) <0)){
1026                                 /* handle error in expression => use default */
1027                                 ret=-1;
1028                                 goto sw_jt_def;
1029                         }
1030                         if (h->run_flags & EXIT_R_F){
1031                                 ret=0;
1032                                 break;
1033                         }
1034                         h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return & break
1035                                                                                                             in expr */
1036                         ret=1; /* default is continue */
1037                         if (likely(v >= sjt->first && v <= sjt->last)){
1038                                 if (likely(sjt->tbl[v - sjt->first])){
1039                                         ret=run_actions(h, sjt->tbl[v - sjt->first], msg);
1040                                         h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
1041                                                                                                    returns passthrough */
1042                                 }
1043                                 break; 
1044                         }else{
1045                                 for(i=0; i<sjt->rest.n; i++)
1046                                         if (sjt->rest.cond[i]==v){
1047                                                 if (likely(sjt->rest.jump[i])){
1048                                                         ret=run_actions(h, sjt->rest.jump[i], msg);
1049                                                         h->run_flags &= ~BREAK_R_F; /* catch breaks, but 
1050                                                                                                                    let returns pass */
1051                                                 }
1052                                                 goto skip;
1053                                         }
1054                         }
1055                         /* not found => try default */
1056 sw_jt_def:
1057                         if (sjt->rest.def){
1058                                 ret=run_actions(h, sjt->rest.def, msg);
1059                                 h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
1060                                                                                            returns passthrough */
1061                         }
1062                         break;
1063                 case BLOCK_T:
1064                         if (likely(a->val[0].u.data)){
1065                                 ret=run_actions(h, (struct action*)a->val[0].u.data, msg);
1066                                 h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
1067                                                                                            returns passthrough */
1068                         }
1069                         break;
1070                 case MATCH_COND_T:
1071                         mct=(struct match_cond_table*)a->val[1].u.data;
1072                         rval_cache_init(&c1);
1073                         rv=0;
1074                         rv1=0;
1075                         ret=rval_expr_eval_rvint(h, msg, &rv, &v, 
1076                                                                         (struct rval_expr*)a->val[0].u.data, &c1);
1077                                                                         
1078                         if (unlikely( ret<0)){
1079                                 /* handle error in expression => use default */
1080                                 ret=-1;
1081                                 goto match_cond_def;
1082                         }
1083                         if (h->run_flags & EXIT_R_F){
1084                                 ret=0;
1085                                 break;
1086                         }
1087                         h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return & break
1088                                                                                                             in expr */
1089                         if (likely(rv)){
1090                                 rv1=rval_convert(h, msg, RV_STR, rv, &c1);
1091                                 if (unlikely(rv1==0)){
1092                                         ret=-1;
1093                                         goto match_cond_def;
1094                                 }
1095                                 s=rv1->v.s;
1096                         }else{
1097                                 /* int result in v */
1098                                 rval_cache_clean(&c1);
1099                                 s.s=sint2str(v, &s.len);
1100                         }
1101                         ret=1; /* default is continue */
1102                         for(i=0; i<mct->n; i++)
1103                                 if (( mct->match[i].type==MATCH_STR &&
1104                                                 mct->match[i].l.s.len==s.len &&
1105                                                 memcmp(mct->match[i].l.s.s, s.s, s.len) == 0 ) ||
1106                                          ( mct->match[i].type==MATCH_RE &&
1107                                           regexec(mct->match[i].l.regex, s.s, 0, 0, 0) == 0)
1108                                         ){
1109                                         if (likely(mct->jump[i])){
1110                                                 ret=run_actions(h, mct->jump[i], msg);
1111                                                 h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
1112                                                                                                            returns passthrough */
1113                                         }
1114                                         goto match_cleanup;
1115                                 }
1116 match_cond_def:
1117                         if (mct->def){
1118                                 ret=run_actions(h, mct->def, msg);
1119                                 h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
1120                                                                                            returns passthrough */
1121                         }
1122 match_cleanup:
1123                         if (rv1){
1124                                 rval_destroy(rv1);
1125                                 rval_destroy(rv);
1126                                 rval_cache_clean(&c1);
1127                         }else if (rv){
1128                                 rval_destroy(rv);
1129                                 rval_cache_clean(&c1);
1130                         }
1131                         break;
1132                 case WHILE_T:
1133                         i=0;
1134                         flags=0;
1135                         rve=(struct rval_expr*)a->val[0].u.data;
1136                         ret=1;
1137                         while(!(flags & BREAK_R_F) && 
1138                                         (rval_expr_eval_int(h, msg, &v, rve) == 0) && v){
1139                                 i++;
1140                                 if (unlikely(i > cfg_get(core, core_cfg, max_while_loops))){
1141                                         LOG(L_ERR, "ERROR: runaway while (%d, %d): more then"
1142                                                                 " %d loops\n", 
1143                                                                 rve->fpos.s_line, rve->fpos.s_col,
1144                                                                 cfg_get(core, core_cfg, max_while_loops));
1145                                         ret=-1;
1146                                         goto error;
1147                                 }
1148                                 if (likely(a->val[1].u.data)){
1149                                         ret=run_actions(h, (struct action*)a->val[1].u.data, msg);
1150                                         flags|=h->run_flags;
1151                                         h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
1152                                                                                                    returns passthrough */
1153                                 }
1154                         }
1155                         break;
1156                 case FORCE_RPORT_T:
1157                         msg->msg_flags|=FL_FORCE_RPORT;
1158                         ret=1; /* continue processing */
1159                         break;
1160                 case ADD_LOCAL_RPORT_T:
1161                         msg->msg_flags|=FL_ADD_LOCAL_RPORT;
1162                         ret=1; /* continue processing */
1163                         break;
1164                 case UDP_MTU_TRY_PROTO_T:
1165                         msg->msg_flags|= (unsigned int)a->val[0].u.number & FL_MTU_FB_MASK;
1166                         ret=1; /* continue processing */
1167                         break;
1168                 case SET_ADV_ADDR_T:
1169                         if (a->val[0].type!=STR_ST){
1170                                 LOG(L_CRIT, "BUG: do_action: bad set_advertised_address() "
1171                                                 "type %d\n", a->val[0].type);
1172                                 ret=E_BUG;
1173                                 goto error;
1174                         }
1175                         msg->set_global_address=*((str*)a->val[0].u.data);
1176                         ret=1; /* continue processing */
1177                         break;
1178                 case SET_ADV_PORT_T:
1179                         if (a->val[0].type!=STR_ST){
1180                                 LOG(L_CRIT, "BUG: do_action: bad set_advertised_port() "
1181                                                 "type %d\n", a->val[0].type);
1182                                 ret=E_BUG;
1183                                 goto error;
1184                         }
1185                         msg->set_global_port=*((str*)a->val[0].u.data);
1186                         ret=1; /* continue processing */
1187                         break;
1188 #ifdef USE_TCP
1189                 case FORCE_TCP_ALIAS_T:
1190                         if ( msg->rcv.proto==PROTO_TCP
1191 #ifdef USE_TLS
1192                                         || msg->rcv.proto==PROTO_TLS
1193 #endif
1194                            ){
1195
1196                                 if (a->val[0].type==NOSUBTYPE)  port=msg->via1->port;
1197                                 else if (a->val[0].type==NUMBER_ST) port=(int)a->val[0].u.number;
1198                                 else{
1199                                         LOG(L_CRIT, "BUG: do_action: bad force_tcp_alias"
1200                                                         " port type %d\n", a->val[0].type);
1201                                         ret=E_BUG;
1202                                         goto error;
1203                                 }
1204
1205                                 if (tcpconn_add_alias(msg->rcv.proto_reserved1, port,
1206                                                                         msg->rcv.proto)!=0){
1207                                         LOG(L_ERR, " ERROR: receive_msg: tcp alias failed\n");
1208                                         ret=E_UNSPEC;
1209                                         goto error;
1210                                 }
1211                         }
1212 #endif
1213                         ret=1; /* continue processing */
1214                         break;
1215                 case FORCE_SEND_SOCKET_T:
1216                         if (a->val[0].type!=SOCKETINFO_ST){
1217                                 LOG(L_CRIT, "BUG: do_action: bad force_send_socket argument"
1218                                                 " type: %d\n", a->val[0].type);
1219                                 ret=E_BUG;
1220                                 goto error;
1221                         }
1222                         set_force_socket(msg, (struct socket_info*)a->val[0].u.data);
1223                         ret=1; /* continue processing */
1224                         break;
1225
1226                 case ADD_T:
1227                 case ASSIGN_T:
1228                         v=lval_assign(h, msg, (struct lvalue*)a->val[0].u.data,
1229                                                                   (struct rval_expr*)a->val[1].u.data);
1230                         if (likely(v>=0))
1231                                 ret = 1;
1232                         else if (unlikely (v == EXPR_DROP)) /* hack to quit on DROP*/
1233                                 ret=0;
1234                         else
1235                                 ret=v;
1236                         break;
1237                 case SET_FWD_NO_CONNECT_T:
1238                         msg->fwd_send_flags.f|= SND_F_FORCE_CON_REUSE;
1239                         ret=1; /* continue processing */
1240                         break;
1241                 case SET_RPL_NO_CONNECT_T:
1242                         msg->rpl_send_flags.f|= SND_F_FORCE_CON_REUSE;
1243                         ret=1; /* continue processing */
1244                         break;
1245                 case SET_FWD_CLOSE_T:
1246                         msg->fwd_send_flags.f|= SND_F_CON_CLOSE;
1247                         ret=1; /* continue processing */
1248                         break;
1249                 case SET_RPL_CLOSE_T:
1250                         msg->rpl_send_flags.f|= SND_F_CON_CLOSE;
1251                         ret=1; /* continue processing */
1252                         break;
1253 /*
1254                 default:
1255                         LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
1256 */
1257         }
1258 skip:
1259         return ret;
1260
1261 error_uri:
1262         LOG(L_ERR, "ERROR: do_action: set*: uri too long\n");
1263         if (new_uri) pkg_free(new_uri);
1264         LM_ERR("run action error at: %s:%d\n", (a->cfile)?a->cfile:"", a->cline);
1265         return E_UNSPEC;
1266 error_fwd_uri:
1267         /*free_uri(&uri); -- not needed anymore, using msg->parsed_uri*/
1268 error:
1269         LM_ERR("run action error at: %s:%d\n", (a->cfile)?a->cfile:"", a->cline);
1270         return ret;
1271 }
1272
1273
1274
1275 /* returns: 0, or 1 on success, <0 on error */
1276 /* (0 if drop or break encountered, 1 if not ) */
1277 int run_actions(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
1278 {
1279         struct action* t;
1280         int ret;
1281         struct sr_module *mod;
1282
1283         ret=E_UNSPEC;
1284         h->rec_lev++;
1285         if (h->rec_lev>ROUTE_MAX_REC_LEV){
1286                 LOG(L_ERR, "WARNING: too many recursive routing table lookups (%d)"
1287                                         " giving up!\n", h->rec_lev);
1288                 ret=E_UNSPEC;
1289                 goto error;
1290         }
1291         if (h->rec_lev==1){
1292                 h->run_flags=0;
1293                 h->last_retcode=0;
1294                 _last_returned_code = h->last_retcode;
1295 #ifdef USE_LONGJMP
1296                 if (setjmp(h->jmp_env)){
1297                         h->rec_lev=0;
1298                         ret=h->last_retcode;
1299                         goto end;
1300                 }
1301 #endif
1302         }
1303
1304         if (a==0){
1305                 DBG("DEBUG: run_actions: null action list (rec_level=%d)\n",
1306                                 h->rec_lev);
1307                 ret=1;
1308         }
1309
1310         for (t=a; t!=0; t=t->next){
1311                 ret=do_action(h, t, msg);
1312                 /* break, return or drop/exit stop execution of the current
1313                    block */
1314                 if (h->run_flags & (BREAK_R_F|RETURN_R_F|EXIT_R_F)){
1315                         if (h->run_flags & EXIT_R_F){
1316 #ifdef USE_LONGJMP
1317                                 h->last_retcode=ret;
1318                                 _last_returned_code = h->last_retcode;
1319                                 longjmp(h->jmp_env, ret);
1320 #endif
1321                         }
1322                         break;
1323                 }
1324                 /* ignore error returns */
1325         }
1326
1327         h->rec_lev--;
1328 end:
1329         /* process module onbreak handlers if present */
1330         if (h->rec_lev==0 && ret==0)
1331                 for (mod=modules;mod;mod=mod->next)
1332                         if ((mod->mod_interface_ver==0) && mod->exports && 
1333                                         mod->exports->v0.onbreak_f) {
1334                                 mod->exports->v0.onbreak_f( msg );
1335                                 DBG("DEBUG: %s onbreak handler called\n",
1336                                                 mod->exports->c.name);
1337                         }
1338         return ret;
1339
1340
1341 error:
1342         h->rec_lev--;
1343         return ret;
1344 }
1345
1346
1347 int run_top_route(struct action* a, sip_msg_t* msg, struct run_act_ctx *c)
1348 {
1349         struct run_act_ctx ctx;
1350         struct run_act_ctx *p;
1351         int ret;
1352         flag_t sfbk;
1353
1354         p = (c)?c:&ctx;
1355         sfbk = getsflags();
1356         setsflagsval(0);
1357         reset_static_buffer();
1358         init_run_actions_ctx(p);
1359         ret = run_actions(p, a, msg);
1360         setsflagsval(sfbk);
1361         return ret;
1362 }