16ca40f867dbf79ae755ee2d643c684900251db5
[sip-router] / action.c
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2001-2003 FhG Fokus
5  *
6  * This file is part of ser, a free SIP server.
7  *
8  * ser is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * For a license to use the ser software under conditions
14  * other than those described here, or to purchase support for this
15  * software, please contact iptel.org by e-mail at the following addresses:
16  *    info@iptel.org
17  *
18  * ser is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License 
24  * along with this program; if not, write to the Free Software 
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  *
27  * History:
28  * ---------
29  *  2003-02-28  scratchpad compatibility abandoned (jiri)
30  *  2003-01-29  removed scratchpad (jiri)
31  *  2003-03-19  fixed set* len calculation bug & simplified a little the code
32  *              (should be a little faster now) (andrei)
33  *              replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei)
34  *  2003-04-01  Added support for loose routing in forward (janakj)
35  *  2003-04-12  FORCE_RPORT_T added (andrei)
36  *  2003-04-22  strip_tail added (jiri)
37  *  2003-10-02  added SET_ADV_ADDR_T & SET_ADV_PORT_T (andrei)
38  *  2003-10-29  added FORCE_TCP_ALIAS_T (andrei)
39  */
40
41
42 #include "comp_defs.h"
43
44 #include "action.h"
45 #include "config.h"
46 #include "error.h"
47 #include "dprint.h"
48 #include "proxy.h"
49 #include "forward.h"
50 #include "udp_server.h"
51 #include "route.h"
52 #include "parser/msg_parser.h"
53 #include "parser/parse_uri.h"
54 #include "ut.h"
55 #include "sr_module.h"
56 #include "mem/mem.h"
57 #include "globals.h"
58 #include "dset.h"
59 #ifdef USE_TCP
60 #include "tcp_server.h"
61 #endif
62
63 #include <sys/types.h>
64 #include <sys/socket.h>
65 #include <netdb.h>
66 #include <stdlib.h>
67 #include <netinet/in.h>
68 #include <arpa/inet.h>
69 #include <string.h>
70
71 #ifdef DEBUG_DMALLOC
72 #include <dmalloc.h>
73 #endif
74
75
76 /* ret= 0! if action -> end of list(e.g DROP), 
77       > 0 to continue processing next actions
78    and <0 on error */
79 int do_action(struct action* a, struct sip_msg* msg)
80 {
81         int ret;
82         int v;
83         union sockaddr_union* to;
84         struct socket_info* send_sock;
85         struct proxy_l* p;
86         char* tmp;
87         char *new_uri, *end, *crt;
88         int len;
89         int user;
90         struct sip_uri uri, next_hop;
91         struct sip_uri *u;
92         unsigned short port;
93         int proto;
94
95         /* reset the value of error to E_UNSPEC so avoid unknowledgable
96            functions to return with error (status<0) and not setting it
97            leaving there previous error; cache the previous value though
98            for functions which want to process it */
99         prev_ser_error=ser_error;
100         ser_error=E_UNSPEC;
101
102         ret=E_BUG;
103         switch ((unsigned char)a->type){
104                 case DROP_T:
105                                 ret=0;
106                         break;
107                 case FORWARD_T:
108 #ifdef USE_TCP
109                 case FORWARD_TCP_T:
110 #endif
111 #ifdef USE_TLS
112                 case FORWARD_TLS_T:
113 #endif
114                 case FORWARD_UDP_T:
115
116                         if (a->type==FORWARD_UDP_T) proto=PROTO_UDP;
117 #ifdef USE_TCP
118                         else if (a->type==FORWARD_TCP_T) proto= PROTO_TCP;
119 #endif
120 #ifdef USE_TLS
121                         else if (a->type==FORWARD_TLS_T) proto= PROTO_TLS;
122 #endif
123                         else proto= PROTO_NONE;
124                         if (a->p1_type==URIHOST_ST){
125                                 /*parse uri*/
126
127                                 if (msg->dst_uri.len) {
128                                         ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len, &next_hop);
129                                         u = &next_hop;
130                                 } else {
131                                         ret = parse_sip_msg_uri(msg);
132                                         u = &msg->parsed_uri;
133                                 }
134
135                                 if (ret<0) {
136                                         LOG(L_ERR, "ERROR: do_action: forward: bad_uri "
137                                                                 " dropping packet\n");
138                                         break;
139                                 }
140                                 
141                                 switch (a->p2_type){
142                                         case URIPORT_ST:
143                                                                         port=u->port_no;
144                                                                         break;
145                                         case NUMBER_ST:
146                                                                         port=a->p2.number;
147                                                                         break;
148                                         default:
149                                                         LOG(L_CRIT, "BUG: do_action bad forward 2nd"
150                                                                                 " param type (%d)\n", a->p2_type);
151                                                         ret=E_UNSPEC;
152                                                         goto error_fwd_uri;
153                                 }
154                                 if (proto == PROTO_NONE){ /* only if proto not set get it
155                                                                                          from the uri */
156                                         switch(u->proto){
157                                                 case PROTO_NONE:
158                                                         proto=PROTO_UDP;
159                                                         break;
160                                                 case PROTO_UDP:
161 #ifdef USE_TCP
162                                                 case PROTO_TCP:
163 #endif
164 #ifdef USE_TLS
165                                                 case PROTO_TLS:
166 #endif
167                                                         proto=u->proto;
168                                                         break;
169                                                 default:
170                                                         LOG(L_ERR,"ERROR: do action: forward: bad uri"
171                                                                         " transport %d\n", u->proto);
172                                                         ret=E_BAD_PROTO;
173                                                         goto error_fwd_uri;
174                                         }
175 #ifdef USE_TLS
176                                         if (u->secure){
177                                                 if (u->proto==PROTO_UDP){
178                                                         LOG(L_ERR, "ERROR: do_action: forward: secure uri"
179                                                                         " incompatible with transport %d\n", u->proto);
180                                                         ret=E_BAD_PROTO;
181                                                         goto error_fwd_uri;
182                                                 }
183                                                 proto=PROTO_TLS;
184                                         }
185 #endif
186                                 }
187                                 /* create a temporary proxy*/
188                                 p=mk_proxy(&u->host, port, proto);
189                                 if (p==0){
190                                         LOG(L_ERR, "ERROR:  bad host name in uri,"
191                                                         " dropping packet\n");
192                                         ret=E_BAD_ADDRESS;
193                                         goto error_fwd_uri;
194                                 }
195                                 ret=forward_request(msg, p, proto);
196                                 /*free_uri(&uri); -- no longer needed, in sip_msg*/
197                                 free_proxy(p); /* frees only p content, not p itself */
198                                 pkg_free(p);
199                                 if (ret>=0) ret=1;
200                         }else if ((a->p1_type==PROXY_ST) && (a->p2_type==NUMBER_ST)){
201                                 if (proto==PROTO_NONE)
202                                         proto=msg->rcv.proto;
203                                 ret=forward_request(msg,(struct proxy_l*)a->p1.data, proto);
204                                 if (ret>=0) ret=1;
205                         }else{
206                                 LOG(L_CRIT, "BUG: do_action: bad forward() types %d, %d\n",
207                                                 a->p1_type, a->p2_type);
208                                 ret=E_BUG;
209                         }
210                         break;
211                 case SEND_T:
212                 case SEND_TCP_T:
213                         if ((a->p1_type!= PROXY_ST)|(a->p2_type!=NUMBER_ST)){
214                                 LOG(L_CRIT, "BUG: do_action: bad send() types %d, %d\n",
215                                                 a->p1_type, a->p2_type);
216                                 ret=E_BUG;
217                                 break;
218                         }
219                         to=(union sockaddr_union*)
220                                         pkg_malloc(sizeof(union sockaddr_union));
221                         if (to==0){
222                                 LOG(L_ERR, "ERROR: do_action: "
223                                                         "memory allocation failure\n");
224                                 ret=E_OUT_OF_MEM;
225                                 break;
226                         }
227                         
228                         p=(struct proxy_l*)a->p1.data;
229                         
230                         if (p->ok==0){
231                                 if (p->host.h_addr_list[p->addr_idx+1])
232                                         p->addr_idx++;
233                                 else 
234                                         p->addr_idx=0;
235                                 p->ok=1;
236                         }
237                         ret=hostent2su( to, &p->host, p->addr_idx,
238                                                 (p->port)?p->port:SIP_PORT );
239                         if (ret==0){
240                                 p->tx++;
241                                 p->tx_bytes+=msg->len;
242                                 if (a->type==SEND_T){
243                                         /*udp*/
244                                         send_sock=get_send_socket(to, PROTO_UDP);
245                                         if (send_sock!=0){
246                                                 ret=udp_send(send_sock, msg->buf, msg->len, to);
247                                         }else{
248                                                 ret=-1;
249                                         }
250                                 }
251 #ifdef USE_TCP
252                                         else{
253                                         /*tcp*/
254                                         ret=tcp_send(PROTO_TCP, msg->buf, msg->len, to, 0);
255                                 }
256 #endif
257                         }
258                         pkg_free(to);
259                         if (ret<0){
260                                 p->errors++;
261                                 p->ok=0;
262                         }else ret=1;
263                         
264                         break;
265                 case LOG_T:
266                         if ((a->p1_type!=NUMBER_ST)|(a->p2_type!=STRING_ST)){
267                                 LOG(L_CRIT, "BUG: do_action: bad log() types %d, %d\n",
268                                                 a->p1_type, a->p2_type);
269                                 ret=E_BUG;
270                                 break;
271                         }
272                         LOG(a->p1.number, a->p2.string);
273                         ret=1;
274                         break;
275
276                 /* jku -- introduce a new branch */
277                 case APPEND_BRANCH_T:
278                         if ((a->p1_type!=STRING_ST)) {
279                                 LOG(L_CRIT, "BUG: do_action: bad append_branch_t %d\n",
280                                         a->p1_type );
281                                 ret=E_BUG;
282                                 break;
283                         }
284                         ret=append_branch( msg, a->p1.string, 
285                                            a->p1.string ? strlen(a->p1.string):0,
286                                            a->p2.number);
287                         break;
288
289                 /* jku begin: is_length_greater_than */
290                 case LEN_GT_T:
291                         if (a->p1_type!=NUMBER_ST) {
292                                 LOG(L_CRIT, "BUG: do_action: bad len_gt type %d\n",
293                                         a->p1_type );
294                                 ret=E_BUG;
295                                 break;
296                         }
297                         /* DBG("XXX: message length %d, max %d\n", 
298                                 msg->len, a->p1.number ); */
299                         ret = msg->len >= a->p1.number ? 1 : -1;
300                         break;
301                 /* jku end: is_length_greater_than */
302                         
303                 /* jku - begin : flag processing */
304
305                 case SETFLAG_T:
306                         if (a->p1_type!=NUMBER_ST) {
307                                 LOG(L_CRIT, "BUG: do_action: bad setflag() type %d\n",
308                                         a->p1_type );
309                                 ret=E_BUG;
310                                 break;
311                         }
312                         if (!flag_in_range( a->p1.number )) {
313                                 ret=E_CFG;
314                                 break;
315                         }
316                         setflag( msg, a->p1.number );
317                         ret=1;
318                         break;
319
320                 case RESETFLAG_T:
321                         if (a->p1_type!=NUMBER_ST) {
322                                 LOG(L_CRIT, "BUG: do_action: bad resetflag() type %d\n",
323                                         a->p1_type );
324                                 ret=E_BUG;
325                                 break;
326                         }
327                         if (!flag_in_range( a->p1.number )) {
328                                 ret=E_CFG;
329                                 break;
330                         }
331                         resetflag( msg, a->p1.number );
332                         ret=1;
333                         break;
334                         
335                 case ISFLAGSET_T:
336                         if (a->p1_type!=NUMBER_ST) {
337                                 LOG(L_CRIT, "BUG: do_action: bad isflagset() type %d\n",
338                                         a->p1_type );
339                                 ret=E_BUG;
340                                 break;
341                         }
342                         if (!flag_in_range( a->p1.number )) {
343                                 ret=E_CFG;
344                                 break;
345                         }
346                         ret=isflagset( msg, a->p1.number );
347                         break;
348                 /* jku - end : flag processing */
349
350                 case ERROR_T:
351                         if ((a->p1_type!=STRING_ST)|(a->p2_type!=STRING_ST)){
352                                 LOG(L_CRIT, "BUG: do_action: bad error() types %d, %d\n",
353                                                 a->p1_type, a->p2_type);
354                                 ret=E_BUG;
355                                 break;
356                         }
357                         LOG(L_NOTICE, "WARNING: do_action: error(\"%s\", \"%s\") "
358                                         "not implemented yet\n", a->p1.string, a->p2.string);
359                         ret=1;
360                         break;
361                 case ROUTE_T:
362                         if (a->p1_type!=NUMBER_ST){
363                                 LOG(L_CRIT, "BUG: do_action: bad route() type %d\n",
364                                                 a->p1_type);
365                                 ret=E_BUG;
366                                 break;
367                         }
368                         if ((a->p1.number>RT_NO)||(a->p1.number<0)){
369                                 LOG(L_ERR, "ERROR: invalid routing table number in"
370                                                         "route(%lu)\n", a->p1.number);
371                                 ret=E_CFG;
372                                 break;
373                         }
374                         ret=((ret=run_actions(rlist[a->p1.number], msg))<0)?ret:1;
375                         break;
376                 case EXEC_T:
377                         if (a->p1_type!=STRING_ST){
378                                 LOG(L_CRIT, "BUG: do_action: bad exec() type %d\n",
379                                                 a->p1_type);
380                                 ret=E_BUG;
381                                 break;
382                         }
383                         LOG(L_NOTICE, "WARNING: exec(\"%s\") not fully implemented,"
384                                                 " using dumb version...\n", a->p1.string);
385                         ret=system(a->p1.string);
386                         if (ret!=0){
387                                 LOG(L_NOTICE, "WARNING: exec() returned %d\n", ret);
388                         }
389                         ret=1;
390                         break;
391                 case REVERT_URI_T:
392                         if (msg->new_uri.s) {
393                                 pkg_free(msg->new_uri.s);
394                                 msg->new_uri.len=0;
395                                 msg->new_uri.s=0;
396                                 msg->parsed_uri_ok=0; /* invalidate current parsed uri*/
397                         };
398                         ret=1;
399                         break;
400                 case SET_HOST_T:
401                 case SET_HOSTPORT_T:
402                 case SET_USER_T:
403                 case SET_USERPASS_T:
404                 case SET_PORT_T:
405                 case SET_URI_T:
406                 case PREFIX_T:
407                 case STRIP_T:
408                 case STRIP_TAIL_T:
409                                 user=0;
410                                 if (a->type==STRIP_T || a->type==STRIP_TAIL_T) {
411                                         if (a->p1_type!=NUMBER_ST) {
412                                                 LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
413                                                         a->p1_type);
414                                                 break;
415                                         }
416                                 } else if (a->p1_type!=STRING_ST){
417                                         LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
418                                                         a->p1_type);
419                                         ret=E_BUG;
420                                         break;
421                                 }
422                                 if (a->type==SET_URI_T){
423                                         if (msg->new_uri.s) {
424                                                         pkg_free(msg->new_uri.s);
425                                                         msg->new_uri.len=0;
426                                         }
427                                         msg->parsed_uri_ok=0;
428                                         len=strlen(a->p1.string);
429                                         msg->new_uri.s=pkg_malloc(len+1);
430                                         if (msg->new_uri.s==0){
431                                                 LOG(L_ERR, "ERROR: do_action: memory allocation"
432                                                                 " failure\n");
433                                                 ret=E_OUT_OF_MEM;
434                                                 break;
435                                         }
436                                         memcpy(msg->new_uri.s, a->p1.string, len);
437                                         msg->new_uri.s[len]=0;
438                                         msg->new_uri.len=len;
439                                         
440                                         ret=1;
441                                         break;
442                                 }
443                                 if (msg->new_uri.s) {
444                                         tmp=msg->new_uri.s;
445                                         len=msg->new_uri.len;
446                                 }else{
447                                         tmp=msg->first_line.u.request.uri.s;
448                                         len=msg->first_line.u.request.uri.len;
449                                 }
450                                 if (parse_uri(tmp, len, &uri)<0){
451                                         LOG(L_ERR, "ERROR: do_action: bad uri <%s>, dropping"
452                                                                 " packet\n", tmp);
453                                         ret=E_UNSPEC;
454                                         break;
455                                 }
456                                 
457                                 new_uri=pkg_malloc(MAX_URI_SIZE);
458                                 if (new_uri==0){
459                                         LOG(L_ERR, "ERROR: do_action: memory allocation "
460                                                                 " failure\n");
461                                         ret=E_OUT_OF_MEM;
462                                         break;
463                                 }
464                                 end=new_uri+MAX_URI_SIZE;
465                                 crt=new_uri;
466                                 /* begin copying */
467                                 len=strlen("sip:"); if(crt+len>end) goto error_uri;
468                                 memcpy(crt,"sip:",len);crt+=len;
469
470                                 /* user */
471
472                                 /* prefix (-jiri) */
473                                 if (a->type==PREFIX_T) {
474                                         tmp=a->p1.string;
475                                         len=strlen(tmp); if(crt+len>end) goto error_uri;
476                                         memcpy(crt,tmp,len);crt+=len;
477                                         /* whatever we had before, with prefix we have username 
478                                            now */
479                                         user=1;
480                                 }
481
482                                 if ((a->type==SET_USER_T)||(a->type==SET_USERPASS_T)) {
483                                         tmp=a->p1.string;
484                                         len=strlen(tmp);
485                                 } else if (a->type==STRIP_T) {
486                                         if (a->p1.number>uri.user.len) {
487                                                 LOG(L_WARN, "Error: too long strip asked; "
488                                                                         " deleting username: %lu of <%.*s>\n",
489                                                                         a->p1.number, uri.user.len, uri.user.s );
490                                                 len=0;
491                                         } else if (a->p1.number==uri.user.len) {
492                                                 len=0;
493                                         } else {
494                                                 tmp=uri.user.s + a->p1.number;
495                                                 len=uri.user.len - a->p1.number;
496                                         }
497                                 } else if (a->type==STRIP_TAIL_T) {
498                                         if (a->p1.number>uri.user.len) {
499                                                 LOG(L_WARN, "WARNING: too long strip_tail asked; "
500                                                                         " deleting username: %lu of <%.*s>\n",
501                                                                         a->p1.number, uri.user.len, uri.user.s );
502                                                 len=0;
503                                         } else if (a->p1.number==uri.user.len) {
504                                                 len=0;
505                                         } else {
506                                                 tmp=uri.user.s;
507                                                 len=uri.user.len - a->p1.number;
508                                         }
509                                 } else {
510                                         tmp=uri.user.s;
511                                         len=uri.user.len;
512                                 }
513
514                                 if (len){
515                                         if(crt+len>end) goto error_uri;
516                                         memcpy(crt,tmp,len);crt+=len;
517                                         user=1; /* we have an user field so mark it */
518                                 }
519
520                                 if (a->type==SET_USERPASS_T) tmp=0;
521                                 else tmp=uri.passwd.s;
522                                 /* passwd */
523                                 if (tmp){
524                                         len=uri.passwd.len; if(crt+len+1>end) goto error_uri;
525                                         *crt=':'; crt++;
526                                         memcpy(crt,tmp,len);crt+=len;
527                                 }
528                                 /* host */
529                                 if (user || tmp){ /* add @ */
530                                         if(crt+1>end) goto error_uri;
531                                         *crt='@'; crt++;
532                                 }
533                                 if ((a->type==SET_HOST_T) ||(a->type==SET_HOSTPORT_T)) {
534                                         tmp=a->p1.string;
535                                         if (tmp) len = strlen(tmp);
536                                         else len=0;
537                                 } else {
538                                         tmp=uri.host.s;
539                                         len = uri.host.len;
540                                 }
541                                 if (tmp){
542                                         if(crt+len>end) goto error_uri;
543                                         memcpy(crt,tmp,len);crt+=len;
544                                 }
545                                 /* port */
546                                 if (a->type==SET_HOSTPORT_T) tmp=0;
547                                 else if (a->type==SET_PORT_T) {
548                                         tmp=a->p1.string;
549                                         if (tmp) len = strlen(tmp);
550                                         else len = 0;
551                                 } else {
552                                         tmp=uri.port.s;
553                                         len = uri.port.len;
554                                 }
555                                 if (tmp){
556                                         if(crt+len+1>end) goto error_uri;
557                                         *crt=':'; crt++;
558                                         memcpy(crt,tmp,len);crt+=len;
559                                 }
560                                 /* params */
561                                 tmp=uri.params.s;
562                                 if (tmp){
563                                         len=uri.params.len; if(crt+len+1>end) goto error_uri;
564                                         *crt=';'; crt++;
565                                         memcpy(crt,tmp,len);crt+=len;
566                                 }
567                                 /* headers */
568                                 tmp=uri.headers.s;
569                                 if (tmp){
570                                         len=uri.headers.len; if(crt+len+1>end) goto error_uri;
571                                         *crt='?'; crt++;
572                                         memcpy(crt,tmp,len);crt+=len;
573                                 }
574                                 *crt=0; /* null terminate the thing */
575                                 /* copy it to the msg */
576                                 if (msg->new_uri.s) pkg_free(msg->new_uri.s);
577                                 msg->new_uri.s=new_uri;
578                                 msg->new_uri.len=crt-new_uri;
579                                 msg->parsed_uri_ok=0;
580                                 ret=1;
581                                 break;
582                 case IF_T:
583                                 /* if null expr => ignore if? */
584                                 if ((a->p1_type==EXPR_ST)&&a->p1.data){
585                                         v=eval_expr((struct expr*)a->p1.data, msg);
586                                         if (v<0){
587                                                 if (v==EXPR_DROP){ /* hack to quit on DROP*/
588                                                         ret=0;
589                                                         break;
590                                                 }else{
591                                                         LOG(L_WARN,"WARNING: do_action:"
592                                                                                 "error in expression\n");
593                                                 }
594                                         }
595                                         
596                                         ret=1;  /*default is continue */
597                                         if (v>0) {
598                                                 if ((a->p2_type==ACTIONS_ST)&&a->p2.data){
599                                                         ret=run_actions((struct action*)a->p2.data, msg);
600                                                 }
601                                         }else if ((a->p3_type==ACTIONS_ST)&&a->p3.data){
602                                                         ret=run_actions((struct action*)a->p3.data, msg);
603                                         }
604                                 }
605                         break;
606                 case MODULE_T:
607                         if ( ((a->p1_type==CMDF_ST)&&a->p1.data)/*&&
608                                         ((a->p2_type==STRING_ST)&&a->p2.data)*/ ){
609                                 ret=((cmd_function)(a->p1.data))(msg, (char*)a->p2.data,
610                                                                                                           (char*)a->p3.data);
611                         }else{
612                                 LOG(L_CRIT,"BUG: do_action: bad module call\n");
613                         }
614                         break;
615                 case FORCE_RPORT_T:
616                         msg->msg_flags|=FL_FORCE_RPORT;
617                         ret=1; /* continue processing */
618                         break;
619                 case SET_ADV_ADDR_T:
620                         if (a->p1_type!=STR_ST){
621                                 LOG(L_CRIT, "BUG: do_action: bad set_advertised_address() "
622                                                 "type %d\n", a->p1_type);
623                                 ret=E_BUG;
624                                 break;
625                         }
626                         msg->set_global_address=*((str*)a->p1.data);
627                         ret=1; /* continue processing */
628                         break;
629                 case SET_ADV_PORT_T:
630                         if (a->p1_type!=STR_ST){
631                                 LOG(L_CRIT, "BUG: do_action: bad set_advertised_port() "
632                                                 "type %d\n", a->p1_type);
633                                 ret=E_BUG;
634                                 break;
635                         }
636                         msg->set_global_port=*((str*)a->p1.data);
637                         ret=1; /* continue processing */
638                         break;
639 #ifdef USE_TCP
640                 case FORCE_TCP_ALIAS_T:
641                         if ( msg->rcv.proto==PROTO_TCP
642 #ifdef USE_TLS
643                                         || msg->rcv.proto==PROTO_TLS
644 #endif
645                            ){
646                                 
647                                 if (a->p1_type==NOSUBTYPE)      port=msg->via1->port;
648                                 else if (a->p1_type==NUMBER_ST) port=(int)a->p1.number;
649                                 else{
650                                         LOG(L_CRIT, "BUG: do_action: bad force_tcp_alias"
651                                                         " port type %d\n", a->p1_type);
652                                         ret=E_BUG;
653                                         break;
654                                 }
655                                                 
656                                 if (tcpconn_add_alias(msg->rcv.proto_reserved1, port,
657                                                                         msg->rcv.proto)!=0){
658                                         LOG(L_ERR, " ERROR: receive_msg: tcp alias failed\n");
659                                         ret=E_UNSPEC;
660                                         break;
661                                 }
662                         }
663 #endif
664                         ret=1; /* continue processing */
665                         break;
666                 default:
667                         LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
668         }
669 /*skip:*/
670         return ret;
671         
672 error_uri:
673         LOG(L_ERR, "ERROR: do_action: set*: uri too long\n");
674         if (new_uri) pkg_free(new_uri);
675         return E_UNSPEC;
676 error_fwd_uri:
677         /*free_uri(&uri); -- not needed anymore, using msg->parsed_uri*/
678         return ret;
679 }
680
681
682
683 /* returns: 0, or 1 on success, <0 on error */
684 /* (0 if drop or break encountered, 1 if not ) */
685 int run_actions(struct action* a, struct sip_msg* msg)
686 {
687         struct action* t;
688         int ret=E_UNSPEC;
689         static int rec_lev=0;
690         struct sr_module *mod;
691
692         rec_lev++;
693         if (rec_lev>ROUTE_MAX_REC_LEV){
694                 LOG(L_ERR, "WARNING: too many recursive routing table lookups (%d)"
695                                         " giving up!\n", rec_lev);
696                 ret=E_UNSPEC;
697                 goto error;
698         }
699                 
700         if (a==0){
701                 LOG(L_ERR, "WARNING: run_actions: null action list (rec_level=%d)\n", 
702                         rec_lev);
703                 ret=0;
704         }
705
706         for (t=a; t!=0; t=t->next){
707                 ret=do_action(t, msg);
708                 if(ret==0) break;
709                 /* ignore errors */
710                 /*else if (ret<0){ ret=-1; goto error; }*/
711         }
712         
713         rec_lev--;
714         /* process module onbreak handlers if present */
715         if (rec_lev==0 && ret==0) 
716                 for (mod=modules;mod;mod=mod->next) 
717                         if (mod->exports && mod->exports->onbreak_f) {
718                                 mod->exports->onbreak_f( msg );
719                                 DBG("DEBUG: %s onbreak handler called\n", mod->exports->name);
720                         }
721         return ret;
722         
723
724 error:
725         rec_lev--;
726         return ret;
727 }
728
729
730