5 * Copyright (C) 2001-2003 FhG Fokus
7 * This file is part of ser, a free SIP server.
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
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:
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.
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
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
47 * 2007-06-14 run_actions & do_action need a ctx or handle now, no more
48 * static vars (andrei)
52 #include "comp_defs.h"
60 #include "udp_server.h"
62 #include "parser/msg_parser.h"
63 #include "parser/parse_uri.h"
65 #include "sr_module.h"
72 #include "tcp_server.h"
75 #include <sys/types.h>
76 #include <sys/socket.h>
79 #include <netinet/in.h>
80 #include <arpa/inet.h>
89 struct onsend_info* p_onsend=0; /* onsend route send info */
91 /* ret= 0! if action -> end of list(e.g DROP),
92 > 0 to continue processing next actions
94 int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
100 char *new_uri, *end, *crt;
103 struct sip_uri uri, next_hop;
106 unsigned short flags;
110 /* reset the value of error to E_UNSPEC so avoid unknowledgable
111 functions to return with error (status<0) and not setting it
112 leaving there previous error; cache the previous value though
113 for functions which want to process it */
114 prev_ser_error=ser_error;
118 switch ((unsigned char)a->type){
120 if (a->val[0].type==RETCODE_ST)
123 ret=(int) a->val[0].u.number;
124 h->run_flags|=(unsigned int)a->val[1].u.number;
135 init_dest_info(&dst);
136 if (a->type==FORWARD_UDP_T) dst.proto=PROTO_UDP;
138 else if (a->type==FORWARD_TCP_T) dst.proto= PROTO_TCP;
141 else if (a->type==FORWARD_TLS_T) dst.proto= PROTO_TLS;
143 else dst.proto= PROTO_NONE;
144 if (a->val[0].type==URIHOST_ST){
147 if (msg->dst_uri.len) {
148 ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len,
152 ret = parse_sip_msg_uri(msg);
153 u = &msg->parsed_uri;
157 LOG(L_ERR, "ERROR: do_action: forward: bad_uri "
158 " dropping packet\n");
162 switch (a->val[1].type){
167 port=a->val[1].u.number;
170 LOG(L_CRIT, "BUG: do_action bad forward 2nd"
171 " param type (%d)\n", a->val[1].type);
175 if (dst.proto == PROTO_NONE){ /* only if proto not set get it
179 /*dst.proto=PROTO_UDP; */
180 /* no proto, try to get it from the dns */
192 LOG(L_ERR,"ERROR: do action: forward: bad uri"
193 " transport %d\n", u->proto);
198 if (u->type==SIPS_URI_T){
199 if (u->proto==PROTO_UDP){
200 LOG(L_ERR, "ERROR: do_action: forward: secure uri"
201 " incompatible with transport %d\n",
212 if (u->maddr_val.s && u->maddr_val.len)
213 dst_host=&u->maddr_val;
220 ret=forward_request(msg, dst_host, port, &dst);
224 }else if ((a->val[0].type==PROXY_ST) && (a->val[1].type==NUMBER_ST)){
225 if (dst.proto==PROTO_NONE)
226 dst.proto=msg->rcv.proto;
227 proxy2su(&dst.to, (struct proxy_l*)a->val[0].u.data);
228 ret=forward_request(msg, 0, 0, &dst);
231 proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
232 }else if (ser_error!=E_OK){
233 proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
236 LOG(L_CRIT, "BUG: do_action: bad forward() types %d, %d\n",
237 a->val[0].type, a->val[1].type);
243 if ((a->val[0].type!= PROXY_ST)|(a->val[1].type!=NUMBER_ST)){
244 LOG(L_CRIT, "BUG: do_action: bad send() types %d, %d\n",
245 a->val[0].type, a->val[1].type);
250 init_dest_info(&dst);
251 ret=proxy2su(&dst.to, (struct proxy_l*)a->val[0].u.data);
260 if (a->type==SEND_T){
262 dst.proto=PROTO_UDP; /* not really needed for udp_send */
263 dst.send_sock=get_send_socket(msg, &dst.to, PROTO_UDP);
264 if (dst.send_sock!=0){
265 ret=udp_send(&dst, tmp, len);
275 ret=tcp_send(&dst, 0, tmp, len);
282 proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
287 if ((a->val[0].type!=NUMBER_ST)|(a->val[1].type!=STRING_ST)){
288 LOG(L_CRIT, "BUG: do_action: bad log() types %d, %d\n",
289 a->val[0].type, a->val[1].type);
293 LOG(a->val[0].u.number, "%s", a->val[1].u.string);
297 /* jku -- introduce a new branch */
298 case APPEND_BRANCH_T:
299 if ((a->val[0].type!=STRING_ST)) {
300 LOG(L_CRIT, "BUG: do_action: bad append_branch_t %d\n",
305 ret=append_branch( msg, a->val[0].u.string,
306 a->val[0].u.string ? strlen(a->val[0].u.string):0,
307 0, 0, a->val[1].u.number, 0);
310 /* jku begin: is_length_greater_than */
312 if (a->val[0].type!=NUMBER_ST) {
313 LOG(L_CRIT, "BUG: do_action: bad len_gt type %d\n",
318 /* DBG("XXX: message length %d, max %d\n",
319 msg->len, a->val[0].u.number ); */
320 ret = msg->len >= a->val[0].u.number ? 1 : -1;
322 /* jku end: is_length_greater_than */
324 /* jku - begin : flag processing */
327 if (a->val[0].type!=NUMBER_ST) {
328 LOG(L_CRIT, "BUG: do_action: bad setflag() type %d\n",
333 if (!flag_in_range( a->val[0].u.number )) {
337 setflag( msg, a->val[0].u.number );
342 if (a->val[0].type!=NUMBER_ST) {
343 LOG(L_CRIT, "BUG: do_action: bad resetflag() type %d\n",
348 if (!flag_in_range( a->val[0].u.number )) {
352 resetflag( msg, a->val[0].u.number );
357 if (a->val[0].type!=NUMBER_ST) {
358 LOG(L_CRIT, "BUG: do_action: bad isflagset() type %d\n",
363 if (!flag_in_range( a->val[0].u.number )) {
367 ret=isflagset( msg, a->val[0].u.number );
369 /* jku - end : flag processing */
371 case AVPFLAG_OPER_T: {
372 struct search_state st;
376 flag = a->val[1].u.number;
377 if ((a->val[0].u.attr->type & AVP_INDEX_ALL) == AVP_INDEX_ALL || (a->val[0].u.attr->type & AVP_NAME_RE)!=0) {
378 for (avp=search_first_avp(a->val[0].u.attr->type, a->val[0].u.attr->name, NULL, &st); avp; avp = search_next_avp(&st, NULL)) {
379 switch (a->val[2].u.number) { /* oper: 0..reset, 1..set, -1..no change */
381 avp->flags &= ~(avp_flags_t)a->val[1].u.number;
384 avp->flags |= (avp_flags_t)a->val[1].u.number;
388 ret = ret || ((avp->flags & (avp_flags_t)a->val[1].u.number) != 0);
392 avp = search_avp_by_index(a->val[0].u.attr->type, a->val[0].u.attr->name, NULL, a->val[0].u.attr->index);
394 switch (a->val[2].u.number) { /* oper: 0..reset, 1..set, -1..no change */
396 avp->flags &= ~(avp_flags_t)a->val[1].u.number;
399 avp->flags |= (avp_flags_t)a->val[1].u.number;
403 ret = (avp->flags & (avp_flags_t)a->val[1].u.number) != 0;
411 if ((a->val[0].type!=STRING_ST)|(a->val[1].type!=STRING_ST)){
412 LOG(L_CRIT, "BUG: do_action: bad error() types %d, %d\n",
413 a->val[0].type, a->val[1].type);
417 LOG(L_NOTICE, "WARNING: do_action: error(\"%s\", \"%s\") "
418 "not implemented yet\n", a->val[0].u.string, a->val[1].u.string);
422 if (a->val[0].type!=NUMBER_ST){
423 LOG(L_CRIT, "BUG: do_action: bad route() type %d\n",
428 if ((a->val[0].u.number>=main_rt.idx)||(a->val[0].u.number<0)){
429 LOG(L_ERR, "ERROR: invalid routing table number in"
430 "route(%lu)\n", a->val[0].u.number);
434 /*ret=((ret=run_actions(rlist[a->val[0].u.number], msg))<0)?ret:1;*/
435 ret=run_actions(h, main_rt.rlist[a->val[0].u.number], msg);
437 h->run_flags&=~RETURN_R_F; /* absorb returns */
440 if (a->val[0].type!=STRING_ST){
441 LOG(L_CRIT, "BUG: do_action: bad exec() type %d\n",
446 LOG(L_NOTICE, "WARNING: exec(\"%s\") not fully implemented,"
447 " using dumb version...\n", a->val[0].u.string);
448 ret=system(a->val[0].u.string);
450 LOG(L_NOTICE, "WARNING: exec() returned %d\n", ret);
455 if (msg->new_uri.s) {
456 pkg_free(msg->new_uri.s);
459 msg->parsed_uri_ok=0; /* invalidate current parsed uri*/
465 case SET_HOSTPORTTRANS_T:
474 if (a->type==STRIP_T || a->type==STRIP_TAIL_T) {
475 if (a->val[0].type!=NUMBER_ST) {
476 LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
480 } else if (a->val[0].type!=STRING_ST){
481 LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
486 if (a->type==SET_URI_T){
487 if (msg->new_uri.s) {
488 pkg_free(msg->new_uri.s);
491 msg->parsed_uri_ok=0;
492 len=strlen(a->val[0].u.string);
493 msg->new_uri.s=pkg_malloc(len+1);
494 if (msg->new_uri.s==0){
495 LOG(L_ERR, "ERROR: do_action: memory allocation"
500 memcpy(msg->new_uri.s, a->val[0].u.string, len);
501 msg->new_uri.s[len]=0;
502 msg->new_uri.len=len;
507 if (msg->parsed_uri_ok==0) {
508 if (msg->new_uri.s) {
510 len=msg->new_uri.len;
512 tmp=msg->first_line.u.request.uri.s;
513 len=msg->first_line.u.request.uri.len;
515 if (parse_uri(tmp, len, &uri)<0){
516 LOG(L_ERR, "ERROR: do_action: bad uri <%s>, dropping"
525 new_uri=pkg_malloc(MAX_URI_SIZE);
527 LOG(L_ERR, "ERROR: do_action: memory allocation "
532 end=new_uri+MAX_URI_SIZE;
535 len=strlen("sip:"); if(crt+len>end) goto error_uri;
536 memcpy(crt,"sip:",len);crt+=len;
541 if (a->type==PREFIX_T) {
542 tmp=a->val[0].u.string;
543 len=strlen(tmp); if(crt+len>end) goto error_uri;
544 memcpy(crt,tmp,len);crt+=len;
545 /* whatever we had before, with prefix we have username
550 if ((a->type==SET_USER_T)||(a->type==SET_USERPASS_T)) {
551 tmp=a->val[0].u.string;
553 } else if (a->type==STRIP_T) {
554 if (a->val[0].u.number>uri.user.len) {
555 LOG(L_WARN, "Error: too long strip asked; "
556 " deleting username: %lu of <%.*s>\n",
557 a->val[0].u.number, uri.user.len, uri.user.s );
559 } else if (a->val[0].u.number==uri.user.len) {
562 tmp=uri.user.s + a->val[0].u.number;
563 len=uri.user.len - a->val[0].u.number;
565 } else if (a->type==STRIP_TAIL_T) {
566 if (a->val[0].u.number>uri.user.len) {
567 LOG(L_WARN, "WARNING: too long strip_tail asked; "
568 " deleting username: %lu of <%.*s>\n",
569 a->val[0].u.number, uri.user.len, uri.user.s );
571 } else if (a->val[0].u.number==uri.user.len) {
575 len=uri.user.len - a->val[0].u.number;
583 if(crt+len>end) goto error_uri;
584 memcpy(crt,tmp,len);crt+=len;
585 user=1; /* we have an user field so mark it */
588 if (a->type==SET_USERPASS_T) tmp=0;
589 else tmp=uri.passwd.s;
592 len=uri.passwd.len; if(crt+len+1>end) goto error_uri;
594 memcpy(crt,tmp,len);crt+=len;
597 if (user || tmp){ /* add @ */
598 if(crt+1>end) goto error_uri;
601 if ((a->type==SET_HOST_T)
602 || (a->type==SET_HOSTPORT_T)
603 || (a->type==SET_HOSTPORTTRANS_T)) {
604 tmp=a->val[0].u.string;
605 if (tmp) len = strlen(tmp);
612 if(crt+len>end) goto error_uri;
613 memcpy(crt,tmp,len);crt+=len;
616 if ((a->type==SET_HOSTPORT_T)
617 || (a->type==SET_HOSTPORTTRANS_T))
619 else if (a->type==SET_PORT_T) {
620 tmp=a->val[0].u.string;
621 if (tmp) len = strlen(tmp);
628 if(crt+len+1>end) goto error_uri;
630 memcpy(crt,tmp,len);crt+=len;
633 if ((a->type==SET_HOSTPORTTRANS_T) && uri.transport.s) {
634 /* bypass the transport parameter */
635 if (uri.params.s < uri.transport.s) {
636 /* there are parameters before transport */
637 len = uri.transport.s - uri.params.s - 1;
638 /* ignore the ';' at the end */
639 if (crt+len+1>end) goto error_uri;
641 memcpy(crt,uri.params.s,len);crt+=len;
643 len = (uri.params.s + uri.params.len) -
644 (uri.transport.s + uri.transport.len);
646 /* there are parameters after transport */
647 if (crt+len>end) goto error_uri;
648 tmp = uri.transport.s + uri.transport.len;
649 memcpy(crt,tmp,len);crt+=len;
654 len=uri.params.len; if(crt+len+1>end) goto error_uri;
656 memcpy(crt,tmp,len);crt+=len;
662 len=uri.headers.len; if(crt+len+1>end) goto error_uri;
664 memcpy(crt,tmp,len);crt+=len;
666 *crt=0; /* null terminate the thing */
667 /* copy it to the msg */
668 if (msg->new_uri.s) pkg_free(msg->new_uri.s);
669 msg->new_uri.s=new_uri;
670 msg->new_uri.len=crt-new_uri;
671 msg->parsed_uri_ok=0;
675 /* if null expr => ignore if? */
676 if ((a->val[0].type==EXPR_ST)&&a->val[0].u.data){
677 v=eval_expr(h, (struct expr*)a->val[0].u.data, msg);
680 if (v==EXPR_DROP){ /* hack to quit on DROP*/
684 LOG(L_WARN,"WARNING: do_action:"
685 "error in expression\n");
689 if (h->run_flags & EXIT_R_F){
693 h->run_flags &= ~RETURN_R_F; /* catch returns in expr */
694 ret=1; /*default is continue */
696 if ((a->val[1].type==ACTIONS_ST)&&a->val[1].u.data){
698 (struct action*)a->val[1].u.data, msg);
700 }else if ((a->val[2].type==ACTIONS_ST)&&a->val[2].u.data){
702 (struct action*)a->val[2].u.data, msg);
707 if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && ((cmd_export_t*)a->val[0].u.data)->function ){
708 ret=((cmd_export_t*)a->val[0].u.data)->function(msg,
709 (char*)a->val[2].u.data,
710 (char*)a->val[3].u.data
712 if (ret==0) h->run_flags|=EXIT_R_F;
715 LOG(L_CRIT,"BUG: do_action: bad module call\n");
719 msg->msg_flags|=FL_FORCE_RPORT;
720 ret=1; /* continue processing */
723 if (a->val[0].type!=STR_ST){
724 LOG(L_CRIT, "BUG: do_action: bad set_advertised_address() "
725 "type %d\n", a->val[0].type);
729 msg->set_global_address=*((str*)a->val[0].u.data);
730 ret=1; /* continue processing */
733 if (a->val[0].type!=STR_ST){
734 LOG(L_CRIT, "BUG: do_action: bad set_advertised_port() "
735 "type %d\n", a->val[0].type);
739 msg->set_global_port=*((str*)a->val[0].u.data);
740 ret=1; /* continue processing */
743 case FORCE_TCP_ALIAS_T:
744 if ( msg->rcv.proto==PROTO_TCP
746 || msg->rcv.proto==PROTO_TLS
750 if (a->val[0].type==NOSUBTYPE) port=msg->via1->port;
751 else if (a->val[0].type==NUMBER_ST) port=(int)a->val[0].u.number;
753 LOG(L_CRIT, "BUG: do_action: bad force_tcp_alias"
754 " port type %d\n", a->val[0].type);
759 if (tcpconn_add_alias(msg->rcv.proto_reserved1, port,
761 LOG(L_ERR, " ERROR: receive_msg: tcp alias failed\n");
767 ret=1; /* continue processing */
769 case FORCE_SEND_SOCKET_T:
770 if (a->val[0].type!=SOCKETINFO_ST){
771 LOG(L_CRIT, "BUG: do_action: bad force_send_socket argument"
772 " type: %d\n", a->val[0].type);
776 msg->force_send_socket=(struct socket_info*)a->val[0].u.data;
777 ret=1; /* continue processing */
783 /* If the left attr was specified without indexing brackets delete
784 * existing AVPs before adding new ones
786 if ((a->val[0].u.attr->type & AVP_INDEX_ALL) != AVP_INDEX_ALL) delete_avp(a->val[0].u.attr->type, a->val[0].u.attr->name);
788 if (a->val[1].type == STRING_ST) {
789 value.s = a->val[1].u.str;
790 flags = a->val[0].u.attr->type | AVP_VAL_STR;
791 name = a->val[0].u.attr->name;
793 } else if (a->val[1].type == NUMBER_ST) {
794 value.n = a->val[1].u.number;
795 flags = a->val[0].u.attr->type;
796 name = a->val[0].u.attr->name;
798 } else if (a->val[1].type == ACTION_ST) {
799 flags = a->val[0].u.attr->type;
800 name = a->val[0].u.attr->name;
801 if (a->val[1].u.data) {
802 value.n = run_actions(h, (struct action*)a->val[1].u.data,
808 } else if(a->val[1].type == EXPR_ST && a->val[1].u.data) {
809 v = eval_expr(h, (struct expr*)a->val[1].u.data, msg);
811 if (v == EXPR_DROP){ /* hack to quit on DROP*/
815 LOG(L_WARN,"WARNING: do_action: error in expression\n");
816 v = 0; /* error is treated as false (Miklos) */
820 flags = a->val[0].u.attr->type;
821 name = a->val[0].u.attr->name;
823 } else if (a->val[1].type == AVP_ST) {
824 struct search_state st;
829 if ((a->val[1].u.attr->type & AVP_INDEX_ALL) == AVP_INDEX_ALL) {
830 avp = search_first_avp(a->val[1].u.attr->type, a->val[1].u.attr->name, &value, &st);
832 /* We take only the type of value and name from the source avp
833 * and reset class and track flags
835 flags = (a->val[0].u.attr->type & ~AVP_INDEX_ALL) | (avp->flags & ~(AVP_CLASS_ALL|AVP_TRACK_ALL));
837 if (add_avp_before(avp_mark, flags, a->val[0].u.attr->name, value) < 0) {
838 LOG(L_CRIT, "ERROR: Failed to assign value to attribute\n");
843 /* move the mark, so the next found AVP will come before the one currently added
844 * so they will have the same order as in the source list
847 avp_mark=avp_mark->next;
849 avp_mark=search_first_avp(flags, a->val[0].u.attr->name, NULL, NULL);
852 avp = search_next_avp(&st, &value);
857 avp = search_avp_by_index(a->val[1].u.attr->type, a->val[1].u.attr->name, &value, a->val[1].u.attr->index);
859 flags = a->val[0].u.attr->type | (avp->flags & ~(AVP_CLASS_ALL|AVP_TRACK_ALL));
860 name = a->val[0].u.attr->name;
867 } else if (a->val[1].type == SELECT_ST) {
869 r = run_select(&value.s, a->val[1].u.select, msg);
878 flags = a->val[0].u.attr->type | AVP_VAL_STR;
879 name = a->val[0].u.attr->name;
882 LOG(L_CRIT, "BUG: do_action: Bad right side of avp assignment\n");
887 /* If the action is assign then remove the old avp value
888 * before adding new ones */
889 /* if ((unsigned char)a->type == ASSIGN_T) delete_avp(flags, name); */
890 if (add_avp(flags & ~AVP_INDEX_ALL, name, value) < 0) {
891 LOG(L_CRIT, "ERROR: Failed to assign value to attribute\n");
898 LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
904 LOG(L_ERR, "ERROR: do_action: set*: uri too long\n");
905 if (new_uri) pkg_free(new_uri);
908 /*free_uri(&uri); -- not needed anymore, using msg->parsed_uri*/
914 /* returns: 0, or 1 on success, <0 on error */
915 /* (0 if drop or break encountered, 1 if not ) */
916 int run_actions(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
920 struct sr_module *mod;
924 if (h->rec_lev>ROUTE_MAX_REC_LEV){
925 LOG(L_ERR, "WARNING: too many recursive routing table lookups (%d)"
926 " giving up!\n", h->rec_lev);
934 if (setjmp(h->jmp_env)){
943 DBG("DEBUG: run_actions: null action list (rec_level=%d)\n",
948 for (t=a; t!=0; t=t->next){
949 ret=do_action(h, t, msg);
950 if (h->run_flags & (RETURN_R_F|EXIT_R_F)){
951 if (h->run_flags & EXIT_R_F){
954 longjmp(h->jmp_env, ret);
959 /* ignore error returns */
964 /* process module onbreak handlers if present */
965 if (h->rec_lev==0 && ret==0)
966 for (mod=modules;mod;mod=mod->next)
967 if (mod->exports && mod->exports->onbreak_f) {
968 mod->exports->onbreak_f( msg );
969 DBG("DEBUG: %s onbreak handler called\n", mod->exports->name);