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)
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)
58 * \brief SIP-router core ::
65 #include "comp_defs.h"
73 #include "udp_server.h"
75 #include "parser/msg_parser.h"
76 #include "parser/parse_uri.h"
79 #include "sr_module.h"
80 #include "select_buf.h"
87 #include "tcp_server.h"
90 #include "sctp_server.h"
95 #include <sys/types.h>
96 #include <sys/socket.h>
99 #include <netinet/in.h>
100 #include <arpa/inet.h>
108 int _last_returned_code = 0;
109 struct onsend_info* p_onsend=0; /* onsend route send info */
111 /* ret= 0! if action -> end of list(e.g DROP),
112 > 0 to continue processing next actions
114 int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
118 struct dest_info dst;
120 char *new_uri, *end, *crt;
124 struct sip_uri uri, next_hop;
129 struct switch_cond_table* sct;
130 struct switch_jmp_table* sjt;
131 struct rval_expr* rve;
132 struct match_cond_table* mct;
135 struct rval_cache c1;
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;
146 /* hook for every executed action (in use by cfg debugger) */
147 if(unlikely(sr_event_enabled(SREV_CFG_RUN_ACTION)))
150 srevp[1] = (void*)msg;
151 sr_event_exec(SREV_CFG_RUN_ACTION, (void*)srevp);
155 switch ((unsigned char)a->type){
157 switch(a->val[0].type){
159 ret=(int) a->val[0].u.number;
162 rve=(struct rval_expr*)a->val[0].u.data;
163 rval_expr_eval_int(h, msg, &ret, rve);
169 BUG("unexpected subtype %d in DROP_T\n",
174 h->run_flags|=(unsigned int)a->val[1].u.number;
188 init_dest_info(&dst);
189 if (a->type==FORWARD_UDP_T) dst.proto=PROTO_UDP;
191 else if (a->type==FORWARD_TCP_T) dst.proto= PROTO_TCP;
194 else if (a->type==FORWARD_TLS_T) dst.proto= PROTO_TLS;
197 else if (a->type==FORWARD_SCTP_T) dst.proto=PROTO_SCTP;
199 else dst.proto=PROTO_NONE;
200 if (a->val[0].type==URIHOST_ST){
203 if (msg->dst_uri.len) {
204 ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len,
208 ret = parse_sip_msg_uri(msg);
209 u = &msg->parsed_uri;
213 LOG(L_ERR, "ERROR: do_action: forward: bad_uri "
214 " dropping packet\n");
218 switch (a->val[1].type){
223 port=a->val[1].u.number;
226 LOG(L_CRIT, "BUG: do_action bad forward 2nd"
227 " param type (%d)\n", a->val[1].type);
231 if (dst.proto == PROTO_NONE){ /* only if proto not set get it
235 /*dst.proto=PROTO_UDP; */
236 /* no proto, try to get it from the dns */
251 LOG(L_ERR,"ERROR: do action: forward: bad uri"
252 " transport %d\n", u->proto);
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",
271 if (u->maddr_val.s && u->maddr_val.len)
272 dst_host=&u->maddr_val;
279 ret=forward_request(msg, dst_host, port, &dst);
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);
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);
295 LOG(L_CRIT, "BUG: do_action: bad forward() types %d, %d\n",
296 a->val[0].type, a->val[1].type);
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);
310 init_dest_info(&dst);
311 ret=proxy2su(&dst.to, (struct proxy_l*)a->val[0].u.data);
320 if (a->type==SEND_T){
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);
335 ret=tcp_send(&dst, 0, tmp, len);
342 proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
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);
353 LOG_(DEFAULT_FACILITY, a->val[0].u.number, "<script>: ", "%s",
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",
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);
372 /* jku begin: is_length_greater_than */
374 if (a->val[0].type!=NUMBER_ST) {
375 LOG(L_CRIT, "BUG: do_action: bad len_gt type %d\n",
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;
384 /* jku end: is_length_greater_than */
386 /* jku - begin : flag processing */
389 if (a->val[0].type!=NUMBER_ST) {
390 LOG(L_CRIT, "BUG: do_action: bad setflag() type %d\n",
395 if (!flag_in_range( a->val[0].u.number )) {
399 setflag( msg, a->val[0].u.number );
404 if (a->val[0].type!=NUMBER_ST) {
405 LOG(L_CRIT, "BUG: do_action: bad resetflag() type %d\n",
410 if (!flag_in_range( a->val[0].u.number )) {
414 resetflag( msg, a->val[0].u.number );
419 if (a->val[0].type!=NUMBER_ST) {
420 LOG(L_CRIT, "BUG: do_action: bad isflagset() type %d\n",
425 if (!flag_in_range( a->val[0].u.number )) {
429 ret=isflagset( msg, a->val[0].u.number );
431 /* jku - end : flag processing */
433 case AVPFLAG_OPER_T: {
434 struct search_state st;
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 */
443 avp->flags &= ~(avp_flags_t)a->val[1].u.number;
446 avp->flags |= (avp_flags_t)a->val[1].u.number;
450 ret = ret || ((avp->flags & (avp_flags_t)a->val[1].u.number) != 0);
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);
456 switch (a->val[2].u.number) { /* oper: 0..reset, 1..set, -1..no change */
458 avp->flags &= ~(avp_flags_t)a->val[1].u.number;
461 avp->flags |= (avp_flags_t)a->val[1].u.number;
465 ret = (avp->flags & (avp_flags_t)a->val[1].u.number) != 0;
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);
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);
484 if (a->val[0].type!=NUMBER_ST){
485 LOG(L_CRIT, "BUG: do_action: bad route() type %d\n",
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);
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);
499 _last_returned_code = h->last_retcode;
500 h->run_flags&=~(RETURN_R_F|BREAK_R_F); /* absorb return & break */
503 if (a->val[0].type!=STRING_ST){
504 LOG(L_CRIT, "BUG: do_action: bad exec() type %d\n",
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);
513 LOG(L_NOTICE, "WARNING: exec() returned %d\n", ret);
518 if (msg->new_uri.s) {
519 pkg_free(msg->new_uri.s);
522 msg->parsed_uri_ok=0; /* invalidate current parsed uri*/
528 case SET_HOSTPORTTRANS_T:
537 case SET_USERPHONE_T:
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",
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",
554 if (a->type==SET_URI_T){
555 if (msg->new_uri.s) {
556 pkg_free(msg->new_uri.s);
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"
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;
575 if (msg->parsed_uri_ok==0) {
576 if (msg->new_uri.s) {
578 len=msg->new_uri.len;
580 tmp=msg->first_line.u.request.uri.s;
581 len=msg->first_line.u.request.uri.len;
583 if (parse_uri(tmp, len, &uri)<0){
584 LOG(L_ERR, "ERROR: do_action: bad uri <%s>, dropping"
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)))
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)
607 LOG(L_ERR, "ERROR: do_action: port number of a tel: URI cannot be set\n");
612 new_uri=pkg_malloc(MAX_URI_SIZE);
614 LOG(L_ERR, "ERROR: do_action: memory allocation "
619 end=new_uri+MAX_URI_SIZE;
622 /* Preserve the URI scheme unless the host part needs
623 * to be rewritten, and the shceme is tel: or tels: */
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)
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)
664 LOG(L_ERR, "ERROR: Unsupported URI scheme (%d), "
665 "reverted to sip:\n",
670 if(crt+len+1 /* colon */ >end) goto error_uri;
671 memcpy(crt,tmp,len);crt+=len;
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
686 if ((a->type==SET_USER_T)||(a->type==SET_USERPASS_T)) {
687 tmp=a->val[0].u.string;
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 );
695 } else if (a->val[0].u.number==uri.user.len) {
698 tmp=uri.user.s + a->val[0].u.number;
699 len=uri.user.len - a->val[0].u.number;
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 );
707 } else if (a->val[0].u.number==uri.user.len) {
711 len=uri.user.len - a->val[0].u.number;
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 */
724 if (a->type==SET_USERPASS_T) tmp=0;
725 else tmp=uri.passwd.s;
728 len=uri.passwd.len; if(crt+len+1>end) goto error_uri;
730 memcpy(crt,tmp,len);crt+=len;
732 /* tel: URI parameters */
733 if ((uri.type==TEL_URI_T)
734 || (uri.type==TELS_URI_T)
738 len=uri.params.len; if(crt+len+1>end) goto error_uri;
740 memcpy(crt,tmp,len);crt+=len;
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)
749 tmp=a->val[0].u.string;
750 if (tmp) len = strlen(tmp);
752 } else if ((uri.type==SIP_URI_T)
753 || (uri.type==SIPS_URI_T)
754 || (uri.flags & URI_SIP_USER_PHONE)
762 if (user) { /* add @ */
763 if(crt+1>end) goto error_uri;
766 if(crt+len>end) goto error_uri;
767 memcpy(crt,tmp,len);crt+=len;
769 if(a->type==SET_HOSTALL_T)
772 if ((a->type==SET_HOSTPORT_T)
773 || (a->type==SET_HOSTPORTTRANS_T))
775 else if (a->type==SET_PORT_T) {
776 tmp=a->val[0].u.string;
777 if (tmp) len = strlen(tmp);
784 if(crt+len+1>end) goto error_uri;
786 memcpy(crt,tmp,len);crt+=len;
789 if ((a->type==SET_HOSTPORTTRANS_T)
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;
800 memcpy(crt,uri.sip_params.s,len);crt+=len;
802 len = (uri.sip_params.s + uri.sip_params.len) -
803 (uri.transport.s + uri.transport.len);
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;
811 tmp=uri.sip_params.s;
813 len=uri.sip_params.len; if(crt+len+1>end) goto error_uri;
815 memcpy(crt,tmp,len);crt+=len;
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)
831 if(crt+len>end) goto error_uri;
832 memcpy(crt,tmp,len);crt+=len;
837 len=uri.headers.len; if(crt+len+1>end) goto error_uri;
839 memcpy(crt,tmp,len);crt+=len;
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;
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);
858 if (unlikely(h->run_flags & EXIT_R_F)){
862 h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return &
864 ret=1; /*default is continue */
866 if ((a->val[1].type==ACTIONS_ST)&&a->val[1].u.data){
868 (struct action*)a->val[1].u.data, msg);
870 }else if ((a->val[2].type==ACTIONS_ST)&&a->val[2].u.data){
872 (struct action*)a->val[2].u.data, msg);
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
882 if (ret==0) h->run_flags|=EXIT_R_F;
884 _last_returned_code = h->last_retcode;
886 LOG(L_CRIT,"BUG: do_action: bad module call\n");
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 */
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
901 if (ret==0) h->run_flags|=EXIT_R_F;
903 _last_returned_code = h->last_retcode;
905 LOG(L_CRIT,"BUG: do_action: bad module call\n");
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
918 if (ret==0) h->run_flags|=EXIT_R_F;
920 _last_returned_code = h->last_retcode;
922 LOG(L_CRIT,"BUG: do_action: bad module call\n");
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
936 if (ret==0) h->run_flags|=EXIT_R_F;
938 _last_returned_code = h->last_retcode;
940 LOG(L_CRIT,"BUG: do_action: bad module call\n");
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
955 if (ret==0) h->run_flags|=EXIT_R_F;
957 _last_returned_code = h->last_retcode;
959 LOG(L_CRIT,"BUG: do_action: bad module call\n");
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,
970 if (ret==0) h->run_flags|=EXIT_R_F;
972 _last_returned_code = h->last_retcode;
974 LOG(L_CRIT,"BUG: do_action: bad module call\n");
979 /* only eval the expression to account for possible
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){
987 h->run_flags &= ~RETURN_R_F|BREAK_R_F; /* catch return & break in
989 ret=1; /* default is continue */
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 */
999 if (h->run_flags & EXIT_R_F){
1003 h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return & break
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 */
1017 ret=run_actions(h, sct->def, msg);
1018 h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
1019 returns passthrough */
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 */
1030 if (h->run_flags & EXIT_R_F){
1034 h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return & break
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 */
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
1055 /* not found => try default */
1058 ret=run_actions(h, sjt->rest.def, msg);
1059 h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
1060 returns passthrough */
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 */
1071 mct=(struct match_cond_table*)a->val[1].u.data;
1072 rval_cache_init(&c1);
1075 ret=rval_expr_eval_rvint(h, msg, &rv, &v,
1076 (struct rval_expr*)a->val[0].u.data, &c1);
1078 if (unlikely( ret<0)){
1079 /* handle error in expression => use default */
1081 goto match_cond_def;
1083 if (h->run_flags & EXIT_R_F){
1087 h->run_flags &= ~(RETURN_R_F|BREAK_R_F); /* catch return & break
1090 rv1=rval_convert(h, msg, RV_STR, rv, &c1);
1091 if (unlikely(rv1==0)){
1093 goto match_cond_def;
1097 /* int result in v */
1098 rval_cache_clean(&c1);
1099 s.s=sint2str(v, &s.len);
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)
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 */
1118 ret=run_actions(h, mct->def, msg);
1119 h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
1120 returns passthrough */
1126 rval_cache_clean(&c1);
1129 rval_cache_clean(&c1);
1135 rve=(struct rval_expr*)a->val[0].u.data;
1137 while(!(flags & BREAK_R_F) &&
1138 (rval_expr_eval_int(h, msg, &v, rve) == 0) && v){
1140 if (unlikely(i > cfg_get(core, core_cfg, max_while_loops))){
1141 LOG(L_ERR, "ERROR: runaway while (%d, %d): more then"
1143 rve->fpos.s_line, rve->fpos.s_col,
1144 cfg_get(core, core_cfg, max_while_loops));
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 */
1157 msg->msg_flags|=FL_FORCE_RPORT;
1158 ret=1; /* continue processing */
1160 case ADD_LOCAL_RPORT_T:
1161 msg->msg_flags|=FL_ADD_LOCAL_RPORT;
1162 ret=1; /* continue processing */
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 */
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);
1175 msg->set_global_address=*((str*)a->val[0].u.data);
1176 ret=1; /* continue processing */
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);
1185 msg->set_global_port=*((str*)a->val[0].u.data);
1186 ret=1; /* continue processing */
1189 case FORCE_TCP_ALIAS_T:
1190 if ( msg->rcv.proto==PROTO_TCP
1192 || msg->rcv.proto==PROTO_TLS
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;
1199 LOG(L_CRIT, "BUG: do_action: bad force_tcp_alias"
1200 " port type %d\n", a->val[0].type);
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");
1213 ret=1; /* continue processing */
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);
1222 set_force_socket(msg, (struct socket_info*)a->val[0].u.data);
1223 ret=1; /* continue processing */
1228 v=lval_assign(h, msg, (struct lvalue*)a->val[0].u.data,
1229 (struct rval_expr*)a->val[1].u.data);
1232 else if (unlikely (v == EXPR_DROP)) /* hack to quit on DROP*/
1237 case SET_FWD_NO_CONNECT_T:
1238 msg->fwd_send_flags.f|= SND_F_FORCE_CON_REUSE;
1239 ret=1; /* continue processing */
1241 case SET_RPL_NO_CONNECT_T:
1242 msg->rpl_send_flags.f|= SND_F_FORCE_CON_REUSE;
1243 ret=1; /* continue processing */
1245 case SET_FWD_CLOSE_T:
1246 msg->fwd_send_flags.f|= SND_F_CON_CLOSE;
1247 ret=1; /* continue processing */
1249 case SET_RPL_CLOSE_T:
1250 msg->rpl_send_flags.f|= SND_F_CON_CLOSE;
1251 ret=1; /* continue processing */
1255 LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
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);
1267 /*free_uri(&uri); -- not needed anymore, using msg->parsed_uri*/
1269 LM_ERR("run action error at: %s:%d\n", (a->cfile)?a->cfile:"", a->cline);
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)
1281 struct sr_module *mod;
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);
1294 _last_returned_code = h->last_retcode;
1296 if (setjmp(h->jmp_env)){
1298 ret=h->last_retcode;
1305 DBG("DEBUG: run_actions: null action list (rec_level=%d)\n",
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
1314 if (h->run_flags & (BREAK_R_F|RETURN_R_F|EXIT_R_F)){
1315 if (h->run_flags & EXIT_R_F){
1317 h->last_retcode=ret;
1318 _last_returned_code = h->last_retcode;
1319 longjmp(h->jmp_env, ret);
1324 /* ignore error returns */
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);
1347 int run_top_route(struct action* a, sip_msg_t* msg, struct run_act_ctx *c)
1349 struct run_act_ctx ctx;
1350 struct run_act_ctx *p;
1357 reset_static_buffer();
1358 init_run_actions_ctx(p);
1359 ret = run_actions(p, a, msg);