From 525b30a2a08e4c960e2448d746d5926cca33cbe1 Mon Sep 17 00:00:00 2001 From: Vlad Patrascu Date: Tue, 30 Jul 2019 20:48:26 +0300 Subject: [PATCH] port core script functions to the same interface as module functions --- action.c | 1370 +---------------------------- action.h | 3 + cfg.lex | 120 --- cfg.y | 563 +----------- cmds.c | 86 ++ cmds.h | 80 ++ core_cmds.c | 1253 ++++++++++++++++++++++++++ modules/avpops/avpops_impl.c | 29 +- modules/carrierroute/route_func.c | 16 +- modules/dispatcher/dispatch.c | 15 +- modules/drouting/drouting.c | 28 +- modules/lua/sipapi.c | 2 +- modules/perl/opensipsxs.xs | 72 +- modules/python/python_msgobj.c | 21 +- modules/textops/textops.c | 13 +- msg_translator.c | 8 +- parser/msg_parser.c | 278 ++++++ parser/msg_parser.h | 21 + pvar.c | 136 +-- route.c | 397 +-------- route_struct.c | 75 +- route_struct.h | 36 +- sr_module.c | 61 +- sr_module.h | 54 +- ut.h | 2 +- 25 files changed, 1855 insertions(+), 2884 deletions(-) create mode 100644 cmds.c create mode 100644 cmds.h create mode 100644 core_cmds.c diff --git a/action.c b/action.c index dc2d813295..b60298a0bc 100644 --- a/action.c +++ b/action.c @@ -49,36 +49,17 @@ #include "config.h" #include "error.h" #include "dprint.h" -#include "proxy.h" -#include "forward.h" #include "route.h" #include "parser/msg_parser.h" -#include "parser/parse_uri.h" #include "ut.h" #include "sr_module.h" #include "mem/mem.h" -#include "globals.h" -#include "dset.h" -#include "flags.h" #include "errinfo.h" -#include "serialize.h" -#include "blacklists.h" -#include "cachedb/cachedb.h" #include "msg_translator.h" #include "mod_fix.h" -/* needed by tcpconn_add_alias() */ -#include "net/tcp_conn_defs.h" - #include "script_var.h" #include "xlog.h" -#include "evi/evi_modules.h" - -#include -#include -#include -#include -#include -#include + #include #ifdef DEBUG_DMALLOC @@ -314,81 +295,6 @@ int do_assign(struct sip_msg* msg, struct action* a) return -1; } -static int do_action_set_adv_address(struct sip_msg *msg, struct action *a) -{ - str adv_addr; - int ret = 1; /* continue processing */ - - if (a->elem[0].type != STR_ST) { - LM_BUG("set_advertised_address type %d", a->elem[0].type); - ret = E_BUG; - goto out; - } - - if (pv_printf_s(msg, (pv_elem_t *)a->elem[0].u.data, &adv_addr) != 0 - || adv_addr.len <= 0) { - LM_WARN("cannot get string for value (%s:%d)\n",a->file,a->line); - ret = E_BUG; - goto out; - } - - LM_DBG("setting adv address = [%.*s]\n", adv_addr.len, adv_addr.s); - - /* duplicate the advertised address into private memory */ - if (adv_addr.len > msg->set_global_address.len) { - msg->set_global_address.s = pkg_realloc(msg->set_global_address.s, - adv_addr.len); - if (!msg->set_global_address.s) { - LM_ERR("out of pkg mem\n"); - ret = E_OUT_OF_MEM; - goto out; - } - } - memcpy(msg->set_global_address.s, adv_addr.s, adv_addr.len); - msg->set_global_address.len = adv_addr.len; - -out: - return ret; -} - -static int do_action_set_adv_port(struct sip_msg *msg, struct action *a) -{ - str adv_port; - int ret = 1; - - if (a->elem[0].type != STR_ST) { - LM_BUG("set_advertised_port type %d", a->elem[0].type); - ret = E_BUG; - goto out; - } - - if (pv_printf_s(msg, (pv_elem_t *)a->elem[0].u.data, &adv_port) != 0 - || adv_port.len <= 0) { - - LM_WARN("cannot get string for value (%s:%d)\n", a->file,a->line); - ret = E_BUG; - goto out; - } - - LM_DBG("setting adv port '%.*s'\n", adv_port.len, adv_port.s); - - /* duplicate the advertised port into private memory */ - if (adv_port.len > msg->set_global_port.len) { - msg->set_global_port.s = pkg_realloc(msg->set_global_port.s, - adv_port.len); - if (!msg->set_global_port.s) { - LM_ERR("out of pkg mem\n"); - ret = E_OUT_OF_MEM; - goto out; - } - } - memcpy(msg->set_global_port.s, adv_port.s, adv_port.len); - msg->set_global_port.len = adv_port.len; - -out: - return ret; -} - /* function used to get parameter from a route scope */ static int route_param_get(struct sip_msg *msg, pv_param_t *ip, @@ -514,30 +420,15 @@ int do_action(struct action* a, struct sip_msg* msg) { int ret; int v; - int sec,usec; - union sockaddr_union* to; - struct proxy_l* p; - char* tmp; - char *new_uri, *end, *crt; - int len,i; - int user = 0; - int expires = 0; - str vals[5]; - str result; - struct sip_uri uri, next_hop; - struct sip_uri *u; - unsigned short port; + int i; + int len; int cmatch; struct action *aitem; struct action *adefault; pv_spec_t *spec; - pv_elem_p model; pv_value_t val; - pv_elem_t *pve; - str name_s; struct timeval start; int end_time; - int aux_counter; cmd_export_t *cmd = NULL; acmd_export_t *acmd; void* cmdp[MAX_CMD_PARAMS]; @@ -612,123 +503,6 @@ int do_action(struct action* a, struct sip_msg* msg) } action_flags |= ACT_FL_RETURN; break; - case FORWARD_T: - script_trace("core", "forward", msg, a->file, a->line) ; - if (a->elem[0].type==NOSUBTYPE){ - /* parse uri and build a proxy */ - if (msg->dst_uri.len) { - ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len, - &next_hop); - u = &next_hop; - } else { - ret = parse_sip_msg_uri(msg); - u = &msg->parsed_uri; - } - if (ret<0) { - LM_ERR("forward: bad_uri dropping packet\n"); - break; - } - /* create a temporary proxy*/ - p=mk_proxy(u->maddr_val.len?&u->maddr_val:&u->host, - u->port_no, u->proto, (u->type==SIPS_URI_T)?1:0 ); - if (p==0){ - LM_ERR("bad host name in uri, dropping packet\n"); - ret=E_BAD_ADDRESS; - goto error_fwd_uri; - } - ret=forward_request(msg, p); - free_proxy(p); /* frees only p content, not p itself */ - pkg_free(p); - if (ret==0) ret=1; - }else if (a->elem[0].type==PROXY_ST) { - if (0==(p=clone_proxy((struct proxy_l*)a->elem[0].u.data))) { - LM_ERR("failed to clone proxy, dropping packet\n"); - ret=E_OUT_OF_MEM; - goto error_fwd_uri; - } - ret=forward_request(msg, p); - free_proxy(p); /* frees only p content, not p itself */ - pkg_free(p); - if (ret==0) ret=1; - }else{ - LM_ALERT("BUG in forward() types %d, %d\n", - a->elem[0].type, a->elem[1].type); - ret=E_BUG; - } - break; - case SEND_T: - script_trace("core", "send", msg, a->file, a->line) ; - if (a->elem[0].type!= PROXY_ST){ - LM_ALERT("BUG in send() type %d\n", a->elem[0].type); - ret=E_BUG; - break; - } - if (a->elem[1].u.data) { - if (a->elem[1].type != SCRIPTVAR_ELEM_ST){ - LM_ALERT("BUG in send() header type %d\n",a->elem[1].type); - ret=E_BUG; - break; - } else { - pve = (pv_elem_t *)a->elem[1].u.data; - } - } else { - pve = NULL; - } - to=(union sockaddr_union*) - pkg_malloc(sizeof(union sockaddr_union)); - if (to==0){ - LM_ERR("memory allocation failure\n"); - ret=E_OUT_OF_MEM; - break; - } - if (0==(p=clone_proxy((struct proxy_l*)a->elem[0].u.data))) { - LM_ERR("failed to clone proxy, dropping packet\n"); - ret=E_OUT_OF_MEM; - break; - } - ret=hostent2su(to, &p->host, p->addr_idx, - (p->port)?p->port:SIP_PORT ); - if (ret==0){ - if (pve) { - if ( pv_printf_s(msg, pve, &name_s)!=0 || - name_s.len == 0 || name_s.s == NULL) { - LM_WARN("cannot get string for value (%s:%d)\n", - a->file,a->line); - ret=E_UNSPEC; - break; - } - /* build new msg */ - tmp = pkg_malloc(msg->len + name_s.len); - if (!tmp) { - LM_ERR("memory allocation failure\n"); - ret = E_OUT_OF_MEM; - break; - } - LM_DBG("searching for first line %d\n", - msg->first_line.len); - /* search first line of previous msg */ - /* copy headers */ - len = msg->first_line.len; - memcpy(tmp, msg->buf, len); - memcpy(tmp + len, name_s.s, name_s.len); - memcpy(tmp + len + name_s.len, - msg->buf + len, msg->len - len); - ret = msg_send(0/*send_sock*/, p->proto, to, 0/*id*/, - tmp, msg->len + name_s.len, msg); - pkg_free(tmp); - } else { - ret = msg_send(0/*send_sock*/, p->proto, to, 0/*id*/, - msg->buf, msg->len, msg); - } - if (ret!=0 && p->host.h_addr_list[p->addr_idx+1]) - p->addr_idx++; - } - free_proxy(p); /* frees only p content, not p itself */ - pkg_free(p); - pkg_free(to); - if (ret==0) - ret=1; - break; case LOG_T: script_trace("core", "log", msg, a->file, a->line) ; if ((a->elem[0].type!=NUMBER_ST)|(a->elem[1].type!=STRING_ST)){ @@ -740,50 +514,6 @@ int do_action(struct action* a, struct sip_msg* msg) LM_GEN1(a->elem[0].u.number, "%s", a->elem[1].u.string); ret=1; break; - case APPEND_BRANCH_T: - script_trace("core", "append_branch", msg, a->file, a->line) ; - if ((a->elem[0].type!=STR_ST)) { - LM_ALERT("BUG in append_branch %d\n", - a->elem[0].type ); - ret=E_BUG; - break; - } - if (a->elem[0].u.s.s==NULL) { - ret = append_branch(msg, 0, &msg->dst_uri, &msg->path_vec, - get_ruri_q(msg), getb0flags(msg), msg->force_send_socket); - /* reset all branch info */ - msg->force_send_socket = 0; - setb0flags(msg,0); - set_ruri_q(msg,Q_UNSPECIFIED); - if(msg->dst_uri.s!=0) - pkg_free(msg->dst_uri.s); - msg->dst_uri.s = 0; - msg->dst_uri.len = 0; - if(msg->path_vec.s!=0) - pkg_free(msg->path_vec.s); - msg->path_vec.s = 0; - msg->path_vec.len = 0; - } else { - ret = append_branch(msg, &a->elem[0].u.s, &msg->dst_uri, - &msg->path_vec, a->elem[1].u.number, getb0flags(msg), - msg->force_send_socket); - } - break; - case REMOVE_BRANCH_T: - script_trace("core", "remove_branch", msg, a->file, a->line) ; - if (a->elem[0].type == SCRIPTVAR_ST) { - spec = (pv_spec_t*)a->elem[0].u.data; - if( pv_get_spec_value(msg, spec, &val)!=0 - || (val.flags&PV_VAL_NULL) || !(val.flags&PV_VAL_INT) ) { - ret=-1; - break; - } - i = val.ri; - } else { - i=a->elem[0].u.number; - } - ret = (remove_branch((unsigned int)i)==0)?1:-1; - break; case LEN_GT_T: script_trace("core", "len_gt", msg, a->file, a->line) ; if (a->elem[0].type!=NUMBER_ST) { @@ -794,30 +524,6 @@ int do_action(struct action* a, struct sip_msg* msg) } ret = (msg->len >= (unsigned int)a->elem[0].u.number) ? 1 : -1; break; - case SETFLAG_T: - script_trace("core", "setflag", msg, a->file, a->line) ; - ret = setflag( msg, a->elem[0].u.number ); - break; - case RESETFLAG_T: - script_trace("core", "resetflag", msg, a->file, a->line) ; - ret = resetflag( msg, a->elem[0].u.number ); - break; - case ISFLAGSET_T: - script_trace("core", "isflagset", msg, a->file, a->line) ; - ret = isflagset( msg, a->elem[0].u.number ); - break; - case SETBFLAG_T: - script_trace("core", "setbflag", msg, a->file, a->line) ; - ret = setbflag( msg, a->elem[0].u.number, a->elem[1].u.number ); - break; - case RESETBFLAG_T: - script_trace("core", "resetbflag", msg, a->file, a->line) ; - ret = resetbflag( msg, a->elem[0].u.number, a->elem[1].u.number ); - break; - case ISBFLAGSET_T: - script_trace("core", "isbflagset", msg, a->file, a->line) ; - ret = isbflagset( msg, a->elem[0].u.number, a->elem[1].u.number ); - break; case ERROR_T: script_trace("core", "error", msg, a->file, a->line) ; if ((a->elem[0].type!=STRING_ST)|(a->elem[1].type!=STRING_ST)){ @@ -864,342 +570,6 @@ int do_action(struct action* a, struct sip_msg* msg) } ret=return_code; break; - case REVERT_URI_T: - script_trace("core", "revert_uri", msg, a->file, a->line) ; - if (msg->new_uri.s) { - pkg_free(msg->new_uri.s); - msg->new_uri.len=0; - msg->new_uri.s=0; - msg->parsed_uri_ok=0; /* invalidate current parsed uri*/ - }; - ret=1; - break; - case SET_HOST_T: - case SET_HOSTPORT_T: - case SET_USER_T: - case SET_USERPASS_T: - case SET_PORT_T: - case SET_URI_T: - case PREFIX_T: - case STRIP_T: - case STRIP_TAIL_T: - script_trace("core", - (unsigned char)a->type == SET_HOST_T ? "set_host" : - (unsigned char)a->type == SET_HOSTPORT_T ? "set_hostport" : - (unsigned char)a->type == SET_USER_T ? "set_user" : - (unsigned char)a->type == SET_USERPASS_T ? "set_userpass" : - (unsigned char)a->type == SET_PORT_T ? "set_port" : - (unsigned char)a->type == SET_URI_T ? "set_uri" : - (unsigned char)a->type == PREFIX_T ? "prefix" : - (unsigned char)a->type == STRIP_T ? "strip" : "strip_tail", - msg, a->file, a->line); - user=0; - if (a->type==STRIP_T || a->type==STRIP_TAIL_T) { - if (a->elem[0].type!=NUMBER_ST) { - LM_ALERT("BUG in set*() type %d\n", - a->elem[0].type); - break; - } - } else if (a->elem[0].type!=STR_ST){ - LM_ALERT("BUG in set*() type %d\n", - a->elem[0].type); - ret=E_BUG; - break; - } - if (a->type==SET_URI_T) { - if (set_ruri( msg, &a->elem[0].u.s) ) { - LM_ERR("failed to set new RURI\n"); - ret=E_OUT_OF_MEM; - break; - } - ret=1; - break; - } - if (msg->new_uri.s) { - tmp=msg->new_uri.s; - len=msg->new_uri.len; - }else{ - tmp=msg->first_line.u.request.uri.s; - len=msg->first_line.u.request.uri.len; - } - if (parse_uri(tmp, len, &uri)<0){ - LM_ERR("bad uri <%.*s>, dropping packet\n", len, tmp); - ret=E_UNSPEC; - break; - } - - new_uri=pkg_malloc(MAX_URI_SIZE); - if (new_uri==0){ - LM_ERR("memory allocation failure\n"); - ret=E_OUT_OF_MEM; - break; - } - end=new_uri+MAX_URI_SIZE; - crt=new_uri; - /* begin copying */ - len = (uri.user.len?uri.user.s:uri.host.s) - tmp; - if (crt+len>end) goto error_uri; - memcpy(crt,tmp,len);crt+=len; - - if (a->type==PREFIX_T) { - if (crt+a->elem[0].u.s.len>end) goto error_uri; - memcpy( crt, a->elem[0].u.s.s, a->elem[0].u.s.len); - crt+=a->elem[0].u.s.len; - /* whatever we had before, with prefix we have username - now */ - user=1; - } - - if ((a->type==SET_USER_T)||(a->type==SET_USERPASS_T)) { - tmp=a->elem[0].u.s.s; - len=a->elem[0].u.s.len; - } else if (a->type==STRIP_T) { - if (a->elem[0].u.number>uri.user.len) { - LM_WARN("too long strip asked; " - " deleting username: %lu of <%.*s>\n", - a->elem[0].u.number, uri.user.len, uri.user.s); - len=0; - } else if (a->elem[0].u.number==uri.user.len) { - len=0; - } else { - tmp=uri.user.s + a->elem[0].u.number; - len=uri.user.len - a->elem[0].u.number; - } - } else if (a->type==STRIP_TAIL_T) { - if (a->elem[0].u.number>uri.user.len) { - LM_WARN("too long strip_tail asked;" - " deleting username: %lu of <%.*s>\n", - a->elem[0].u.number, uri.user.len, uri.user.s); - len=0; - } else if (a->elem[0].u.number==uri.user.len) { - len=0; - } else { - tmp=uri.user.s; - len=uri.user.len - a->elem[0].u.number; - } - } else { - tmp=uri.user.s; - len=uri.user.len; - } - - if (len){ - if(crt+len>end) goto error_uri; - memcpy(crt,tmp,len);crt+=len; - user=1; /* we have an user field so mark it */ - } - - if (a->type==SET_USERPASS_T) tmp=0; - else tmp=uri.passwd.s; - /* passwd */ - if (tmp){ - len=uri.passwd.len; if(crt+len+1>end) goto error_uri; - *crt=':'; crt++; - memcpy(crt,tmp,len);crt+=len; - } - /* host */ - if (user || tmp){ /* add @ */ - if(crt+1>end) goto error_uri; - *crt='@'; crt++; - } - if ((a->type==SET_HOST_T) ||(a->type==SET_HOSTPORT_T)) { - tmp=a->elem[0].u.s.s; - len=a->elem[0].u.s.len; - } else { - tmp=uri.host.s; - len = uri.host.len; - } - if (tmp){ - if(crt+len>end) goto error_uri; - memcpy(crt,tmp,len);crt+=len; - } - /* port */ - if (a->type==SET_HOSTPORT_T) tmp=0; - else if (a->type==SET_PORT_T) { - tmp=a->elem[0].u.s.s; - len=a->elem[0].u.s.len; - } else { - tmp=uri.port.s; - len = uri.port.len; - } - if (tmp && len>0){ - if(crt+len+1>end) goto error_uri; - *crt=':'; crt++; - memcpy(crt,tmp,len);crt+=len; - } - /* params */ - tmp=uri.params.s; - if (tmp){ - /* include in param string the starting ';' */ - len=uri.params.len+1; - tmp--; - if(crt+len+1>end) goto error_uri; - /* if a maddr param is present, strip it out */ - if (uri.maddr.len && - (a->type==SET_HOSTPORT_T || a->type==SET_HOST_T)) { - memcpy(crt,tmp,uri.maddr.s-tmp-1); - crt+=uri.maddr.s-tmp-1; - memcpy(crt,uri.maddr_val.s+uri.maddr_val.len, - tmp+len-uri.maddr_val.s-uri.maddr_val.len); - crt+=tmp+len-uri.maddr_val.s-uri.maddr_val.len; - } else { - memcpy(crt,tmp,len);crt+=len; - } - } - /* headers */ - tmp=uri.headers.s; - if (tmp){ - len=uri.headers.len; if(crt+len+1>end) goto error_uri; - *crt='?'; crt++; - memcpy(crt,tmp,len);crt+=len; - } - *crt=0; /* null terminate the thing */ - /* copy it to the msg */ - if (msg->new_uri.s) pkg_free(msg->new_uri.s); - msg->new_uri.s=new_uri; - msg->new_uri.len=crt-new_uri; - msg->parsed_uri_ok=0; - ret=1; - break; - case SET_DSTURI_T: - script_trace("core", "set_dsturi", msg, a->file, a->line) ; - if (a->elem[0].type!=STR_ST){ - LM_ALERT("BUG in setdsturi() type %d\n", - a->elem[0].type); - ret=E_BUG; - break; - } - if(set_dst_uri(msg, &a->elem[0].u.s)!=0) - ret = -1; - else - ret = 1; - break; - case SET_DSTHOST_T: - case SET_DSTPORT_T: - script_trace("core", (unsigned char) a->type == SET_DSTHOST_T ? - "set_dsturi" : "set_dstport", msg, a->file, a->line); - if (a->elem[0].type!=STR_ST){ - LM_ALERT("BUG in domain setting type %d\n", - a->elem[0].type); - ret=E_BUG; - break; - } - - tmp = msg->dst_uri.s; - len = msg->dst_uri.len; - - if (tmp == NULL || len == 0) { - LM_ERR("failure - null uri\n"); - ret = E_UNSPEC; - break; - } - if (a->type == SET_DSTHOST_T && - (a->elem[0].u.s.s == NULL || a->elem[0].u.s.len == 0)) { - LM_ERR("cannot set a null uri domain\n"); - break; - } - if (parse_uri(tmp, len, &uri)<0) { - LM_ERR("bad uri <%.*s>, dropping packet\n", len, tmp); - break; - } - new_uri=pkg_malloc(MAX_URI_SIZE); - if (new_uri == NULL) { - LM_ERR("memory allocation failure\n"); - ret=E_OUT_OF_MEM; - break; - } - end=new_uri+MAX_URI_SIZE; - crt=new_uri; - len = (uri.user.len?uri.user.s:uri.host.s) - tmp; - if (crt+len>end) goto error_uri; - memcpy(crt,tmp,len); - crt += len; - /* user */ - tmp = uri.user.s; - len = uri.user.len; - if (tmp) { - if (crt+len>end) goto error_uri; - memcpy(crt,tmp,len); - crt += len; - user = 1; - } - /* passwd */ - tmp = uri.passwd.s; - len = uri.passwd.len; - if (tmp) { - if (crt+len+1>end) goto error_uri; - *crt++=':'; - memcpy(crt, tmp, len); - crt += len; - } - /* host */ - if (a->type==SET_DSTHOST_T) { - tmp = a->elem[0].u.s.s; - len = a->elem[0].u.s.len; - } else { - tmp = uri.host.s; - len = uri.host.len; - } - if (tmp) { - if (user) { - if (crt+1>end) goto error_uri; - *crt++='@'; - } - if (crt+len+1>end) goto error_uri; - memcpy(crt, tmp, len); - crt += len; - } - /* port */ - if (a->type==SET_DSTPORT_T) { - tmp = a->elem[0].u.s.s; - len = a->elem[0].u.s.len; - } else { - tmp = uri.port.s; - len = uri.port.len; - } - if (tmp) { - if (crt+len+1>end) goto error_uri; - *crt++=':'; - memcpy(crt, tmp, len); - crt += len; - } - /* params */ - tmp=uri.params.s; - if (tmp){ - len=uri.params.len; if(crt+len+1>end) goto error_uri; - *crt++=';'; - memcpy(crt,tmp,len); - crt += len; - } - /* headers */ - tmp=uri.headers.s; - if (tmp){ - len=uri.headers.len; if(crt+len+1>end) goto error_uri; - *crt++='?'; - memcpy(crt,tmp,len); - crt += len; - } - *crt=0; /* null terminate the thing */ - /* copy it to the msg */ - pkg_free(msg->dst_uri.s); - msg->dst_uri.s=new_uri; - msg->dst_uri.len=crt-new_uri; - ret = 1; - break; - case RESET_DSTURI_T: - script_trace("core", "reset_dsturi", msg, a->file, a->line) ; - if(msg->dst_uri.s!=0) - pkg_free(msg->dst_uri.s); - msg->dst_uri.s = 0; - msg->dst_uri.len = 0; - ret = 1; - break; - case ISDSTURISET_T: - script_trace("core", "isdsturiset", msg, a->file, a->line) ; - if(msg->dst_uri.s==0 || msg->dst_uri.len<=0) - ret = -1; - else - ret = 1; - break; case IF_T: script_trace("core", "if", msg, a->file, a->line) ; /* if null expr => ignore if? */ @@ -1296,418 +666,6 @@ int do_action(struct action* a, struct sip_msg* msg) script_trace("core", "for-each", msg, a->file, a->line) ; ret = for_each_handler(msg, a); break; - case CACHE_STORE_T: - script_trace("core", "cache_store", msg, a->file, a->line) ; - if ((a->elem[0].type!=STR_ST)) { - LM_ALERT("BUG in cache_store() - first argument not of" - " type string [%d]\n", - a->elem[0].type ); - ret=E_BUG; - break; - } - - if ((a->elem[1].type!=STR_ST)) { - LM_ALERT("BUG in cache_store() - second argument not of " - "type string [%d]\n", a->elem[1].type ); - ret=E_BUG; - break; - } - - if ((a->elem[2].type!=STR_ST)) { - LM_ALERT("BUG in cache_store() - third argument not of type" - " string%d\n", a->elem[2].type ); - ret=E_BUG; - break; - } - - str val_s; - - /* parse the name argument */ - pve = (pv_elem_t *)a->elem[1].u.data; - if ( pv_printf_s(msg, pve, &name_s)!=0 || - name_s.len == 0 || name_s.s == NULL) { - LM_WARN("cannot get string for value\n"); - ret=E_BUG; - break; - } - - /* parse the value argument */ - pve = (pv_elem_t *)a->elem[2].u.data; - if ( pv_printf_s(msg, pve, &val_s)!=0 || - val_s.len == 0 || val_s.s == NULL) { - LM_WARN("cannot get string for value\n"); - ret=E_BUG; - break; - } - - /* get the expires value */ - if ( a->elem[3].type == SCRIPTVAR_ST ) - { - spec = (pv_spec_t*)a->elem[3].u.data; - memset(&val, 0, sizeof(pv_value_t)); - if(pv_get_spec_value(msg, spec, &val) < 0) - { - LM_DBG("Failed to get scriptvar value while executing cache_store\n"); - ret=E_BUG; - break; - } - if (!(val.flags&PV_VAL_INT)) - { - LM_ERR("Wrong value for cache_store expires, not an integer [%.*s]\n", - val.rs.len, val.rs.s); - } - expires = val.ri; - } - else - if ( a->elem[3].type == NUMBER_ST ) - { - expires = (int)a->elem[3].u.number; - } - - ret = cachedb_store( &a->elem[0].u.s, &name_s, &val_s,expires); - - break; - case CACHE_REMOVE_T: - script_trace("core", "cache_remove", msg, a->file, a->line) ; - if ((a->elem[0].type!=STR_ST)) { - LM_ALERT("BUG in cache_remove() %d\n", - a->elem[0].type ); - ret=E_BUG; - break; - } - if ((a->elem[1].type!=STR_ST)) { - LM_ALERT("BUG in cache_remove() %d\n", - a->elem[1].type ); - ret=E_BUG; - break; - } - /* parse the name argument */ - pve = (pv_elem_t *)a->elem[1].u.data; - if ( pv_printf_s(msg, pve, &name_s)!=0 || - name_s.len == 0 || name_s.s == NULL) { - LM_WARN("cannot get string for value\n"); - ret=E_BUG; - break; - } - ret = cachedb_remove( &a->elem[0].u.s, &name_s); - break; - case CACHE_FETCH_T: - script_trace("core", "cache_fetch", msg, a->file, a->line) ; - if ((a->elem[0].type!=STR_ST)) { - LM_ALERT("BUG in cache_fetch() %d\n", - a->elem[0].type ); - ret=E_BUG; - break; - } - if ((a->elem[1].type!=STR_ST)) { - LM_ALERT("BUG in cache_fetch() %d\n", - a->elem[1].type ); - ret=E_BUG; - break; - } - if (a->elem[2].type!=SCRIPTVAR_ST){ - LM_ALERT("BUG in cache_fetch() type %d\n", - a->elem[2].type); - ret=E_BUG; - break; - } - str aux = {0, 0}; - /* parse the name argument */ - pve = (pv_elem_t *)a->elem[1].u.data; - if ( pv_printf_s(msg, pve, &name_s)!=0 || - name_s.len == 0 || name_s.s == NULL) { - LM_WARN("cannot get string for value\n"); - ret=E_BUG; - break; - } - - ret = cachedb_fetch( &a->elem[0].u.s, &name_s, &aux); - if(ret > 0) - { - val.rs = aux; - val.flags = PV_VAL_STR; - fix_val_str_flags(val); - - spec = (pv_spec_t*)a->elem[2].u.data; - if (pv_set_value(msg, spec, 0, &val) < 0) { - LM_ERR("cannot set the variable value\n"); - pkg_free(aux.s); - return -1; - } - pkg_free(aux.s); - } - - break; - case CACHE_COUNTER_FETCH_T: - script_trace("core", "cache_counter_fetch", msg, a->file, a->line) ; - if ((a->elem[0].type!=STR_ST)) { - LM_ALERT("BUG in cache_fetch() %d\n", - a->elem[0].type ); - ret=E_BUG; - break; - } - if ((a->elem[1].type!=STR_ST)) { - LM_ALERT("BUG in cache_fetch() %d\n", - a->elem[1].type ); - ret=E_BUG; - break; - } - if (a->elem[2].type!=SCRIPTVAR_ST){ - LM_ALERT("BUG in cache_fetch() type %d\n", - a->elem[2].type); - ret=E_BUG; - break; - } - - /* parse the name argument */ - pve = (pv_elem_t *)a->elem[1].u.data; - if ( pv_printf_s(msg, pve, &name_s)!=0 || - name_s.len == 0 || name_s.s == NULL) { - LM_WARN("cannot get string for value\n"); - ret=E_BUG; - break; - } - - ret = cachedb_counter_fetch( &a->elem[0].u.s, &name_s, &aux_counter); - if(ret > 0) - { - val.ri = aux_counter; - val.flags = PV_TYPE_INT|PV_VAL_INT; - - spec = (pv_spec_t*)a->elem[2].u.data; - if (pv_set_value(msg, spec, 0, &val) < 0) { - LM_ERR("cannot set the variable value\n"); - return -1; - } - } - break; - case CACHE_ADD_T: - script_trace("core", "cache_add", msg, a->file, a->line) ; - if ((a->elem[0].type!=STR_ST)) { - LM_ALERT("BUG in cache_add() - first argument not of" - " type string [%d]\n", - a->elem[0].type ); - ret=E_BUG; - break; - } - - if ((a->elem[1].type!=STR_ST)) { - LM_ALERT("BUG in cache_add() - second argument not of " - "type string [%d]\n", a->elem[1].type ); - ret=E_BUG; - break; - } - - /* parse the name argument */ - pve = (pv_elem_t *)a->elem[1].u.data; - if ( pv_printf_s(msg, pve, &name_s)!=0 || - name_s.len == 0 || name_s.s == NULL) { - LM_WARN("cannot get string for value\n"); - ret=E_BUG; - break; - } - - int increment=0; - - /* get the increment value */ - if ( a->elem[2].type == SCRIPTVAR_ST ) - { - spec = (pv_spec_t*)a->elem[2].u.data; - memset(&val, 0, sizeof(pv_value_t)); - if(pv_get_spec_value(msg, spec, &val) < 0) - { - LM_DBG("Failed to get scriptvar value while executing cache_add\n"); - ret=E_BUG; - break; - } - if (!(val.flags&PV_VAL_INT)) - { - LM_ERR("Wrong value for cache_add, not an integer [%.*s]\n", - val.rs.len, val.rs.s); - } - increment = val.ri; - } - else if ( a->elem[2].type == NUMBER_ST ) - { - increment = (int)a->elem[2].u.number; - } - - expires = (int)a->elem[3].u.number; - - ret = cachedb_add(&a->elem[0].u.s, &name_s, increment, expires, &aux_counter); - - /* Return the new value */ - if (ret > 0 && a->elem[4].u.data != NULL) { - val.ri = aux_counter; - val.flags = PV_TYPE_INT|PV_VAL_INT; - - spec = (pv_spec_t*)a->elem[4].u.data; - if (pv_set_value(msg, spec, 0, &val) < 0) { - LM_ERR("cannot set the variable value\n"); - return -1; - } - } - - break; - case CACHE_SUB_T: - script_trace("core", "cache_sub", msg, a->file, a->line) ; - if ((a->elem[0].type!=STR_ST)) { - LM_ALERT("BUG in cache_sub() - first argument not of" - " type string [%d]\n", - a->elem[0].type ); - ret=E_BUG; - break; - } - - if ((a->elem[1].type!=STR_ST)) { - LM_ALERT("BUG in cache_sub() - second argument not of " - "type string [%d]\n", a->elem[1].type ); - ret=E_BUG; - break; - } - - /* parse the name argument */ - pve = (pv_elem_t *)a->elem[1].u.data; - if ( pv_printf_s(msg, pve, &name_s)!=0 || - name_s.len == 0 || name_s.s == NULL) { - LM_WARN("cannot get string for value\n"); - ret=E_BUG; - break; - } - - int decrement=0; - - /* get the increment value */ - if ( a->elem[2].type == SCRIPTVAR_ST ) - { - spec = (pv_spec_t*)a->elem[2].u.data; - memset(&val, 0, sizeof(pv_value_t)); - if(pv_get_spec_value(msg, spec, &val) < 0) - { - LM_DBG("Failed to get scriptvar value while executing cache_sub\n"); - ret=E_BUG; - break; - } - if (!(val.flags&PV_VAL_INT)) - { - LM_ERR("Wrong value for cache_sub, not an integer [%.*s]\n", - val.rs.len, val.rs.s); - } - decrement = val.ri; - } - else if ( a->elem[2].type == NUMBER_ST ) - { - decrement = (int)a->elem[2].u.number; - } - - expires = (int)a->elem[3].u.number; - - ret = cachedb_sub(&a->elem[0].u.s, &name_s, decrement,expires,&aux_counter); - - /* Return the new value */ - if (ret > 0 && a->elem[4].u.data != NULL) { - val.ri = aux_counter; - val.flags = PV_TYPE_INT|PV_VAL_INT; - - spec = (pv_spec_t*)a->elem[4].u.data; - if (pv_set_value(msg, spec, 0, &val) < 0) { - LM_ERR("cannot set the variable value\n"); - return -1; - } - } - - break; - case CACHE_RAW_QUERY_T: - if ((a->elem[0].type!=STR_ST)) { - LM_ALERT("BUG in cache_fetch() %d\n", - a->elem[0].type ); - ret=E_BUG; - break; - } - if ((a->elem[1].type!=STR_ST)) { - LM_ALERT("BUG in cache_fetch() %d\n", - a->elem[1].type ); - ret=E_BUG; - break; - } - if (a->elem[2].u.data != NULL && - a->elem[2].type!=STR_ST){ - LM_ALERT("BUG in cache_raw_query() type %d\n", - a->elem[2].type); - ret=E_BUG; - break; - } - /* parse the name argument */ - pve = (pv_elem_t *)a->elem[1].u.data; - if ( pv_printf_s(msg, pve, &name_s)!=0 || - name_s.len == 0 || name_s.s == NULL) { - LM_WARN("cannot get string for value\n"); - ret=E_BUG; - break; - } - - cdb_raw_entry **cdb_reply = NULL; - int num_cols=0,i,j; - int num_rows=0; - pvname_list_t *cdb_res,*it; - int_str avp_val; - int_str avp_name; - unsigned short avp_type; - - if (a->elem[2].u.data) { - cdb_res = (pvname_list_t*)a->elem[2].u.data; - for (it=cdb_res;it;it=it->next) - num_cols++; - - LM_DBG("The query expects %d fields per result\n", num_cols); - - ret = cachedb_raw_query( &a->elem[0].u.s, &name_s, &cdb_reply,num_cols,&num_rows); - if (ret >= 0 && num_cols > 0) { - for (i=num_rows-1; i>=0;i--) { - it=cdb_res; - for (j=0;j < num_cols;j++) { - avp_type = 0; - if (pv_get_avp_name(msg,&it->sname.pvp,&avp_name.n, - &avp_type) != 0) { - LM_ERR("cannot get avp name [%d/%d]\n",i,j); - goto next_avp; - } - - switch (cdb_reply[i][j].type) { - case CDB_INT32: - avp_val.n = cdb_reply[i][j].val.n; - break; - case CDB_STR: - avp_type |= AVP_VAL_STR; - avp_val.s = cdb_reply[i][j].val.s; - break; - case CDB_NULL: - avp_type |= AVP_VAL_NULL; - avp_val.s = cdb_reply[i][j].val.s; - break; - default: - LM_WARN("Unknown type %d\n",cdb_reply[i][j].type); - goto next_avp; - } - if (add_avp(avp_type,avp_name.n,avp_val) != 0) { - LM_ERR("Unable to add AVP\n"); - free_raw_fetch(cdb_reply,num_cols,num_rows); - return -1; - } -next_avp: - if (it) { - it = it->next; - if (it==NULL) - break; - } - } - } - free_raw_fetch(cdb_reply,num_cols,num_rows); - } - } - else - ret = cachedb_raw_query( &a->elem[0].u.s, &name_s, NULL,0,NULL); - break; case XDBG_T: script_trace("core", "xdbg", msg, a->file, a->line) ; if (a->elem[0].type == SCRIPTVAR_ELEM_ST) @@ -1764,135 +722,6 @@ int do_action(struct action* a, struct sip_msg* msg) } } - break; - case RAISE_EVENT_T: - script_trace("core", "raise_event", msg, a->file, a->line) ; - if (a->elem[0].type != NUMBER_ST) { - LM_ERR("invalid event id\n"); - ret=E_BUG; - break; - } - if (a->elem[2].u.data) { - /* three parameters specified */ - ret = evi_raise_script_event(msg, (event_id_t)a->elem[0].u.number, - a->elem[1].u.data, a->elem[2].u.data); - } else { - /* two parameters specified */ - ret = evi_raise_script_event(msg, (event_id_t)a->elem[0].u.number, - NULL, a->elem[1].u.data); - } - if (ret <= 0) { - LM_ERR("cannot raise event\n"); - ret=E_UNSPEC; - break; - } - break; - case SUBSCRIBE_EVENT_T: - script_trace("core", "subscribe_event", msg, a->file, a->line) ; - if (a->elem[0].type != STR_ST || a->elem[1].type != STR_ST) { - LM_ERR("BUG in subscribe arguments\n"); - ret=E_BUG; - break; - } - if (a->elem[2].u.data) { - if (a->elem[2].type != NUMBER_ST) { - LM_ERR("BUG in subscribe expiration time\n"); - ret=E_BUG; - break; - } else { - i = a->elem[2].u.number; - } - } else { - i = 0; - } - - name_s.s = a->elem[0].u.data; - name_s.len = strlen(name_s.s); - /* result should be the socket */ - result.s = a->elem[1].u.data; - result.len = strlen(result.s); - ret = evi_event_subscribe(name_s, result, i, 0); - break; - - case CONSTRUCT_URI_T: - script_trace("core", "construct_uri", msg, a->file, a->line) ; - for (i=0;i<5;i++) - { - pve = (pv_elem_t *)a->elem[i].u.data; - if (pve->spec.getf) - { - if ( pv_printf_s(msg, pve, &vals[i])!=0 || - vals[i].len == 0 || vals[i].s == NULL) - { - LM_WARN("cannot get string for value\n"); - ret=E_BUG; - return -1; - } - } - else - vals[i] = pve->text; - } - - result.s = construct_uri(&vals[0],&vals[1],&vals[2],&vals[3],&vals[4], - &result.len); - - if (result.s) - { - int_str res; - int avp_name; - unsigned short avp_type; - - spec = (pv_spec_t*)a->elem[5].u.data; - if (pv_get_avp_name( msg, &(spec->pvp), &avp_name, - &avp_type)!=0){ - LM_CRIT("BUG in getting AVP name\n"); - return -1; - } - - res.s = result; - if (add_avp(AVP_VAL_STR|avp_type, avp_name, res)<0){ - LM_ERR("cannot add AVP\n"); - return -1; - } - } - - break; - case GET_TIMESTAMP_T: - script_trace("core", "get_timestamp", msg, a->file, a->line) ; - if (get_timestamp(&sec,&usec) == 0) { - int avp_name; - int_str res; - unsigned short avp_type; - - spec = (pv_spec_t*)a->elem[0].u.data; - if (pv_get_avp_name(msg, &(spec->pvp), &avp_name, - &avp_type) != 0) { - LM_CRIT("BUG in getting AVP name\n"); - return -1; - } - - res.n = sec; - if (add_avp(avp_type, avp_name, res) < 0) { - LM_ERR("cannot add AVP\n"); - return -1; - } - - spec = (pv_spec_t*)a->elem[1].u.data; - if (pv_get_avp_name(msg, &(spec->pvp), &avp_name, - &avp_type) != 0) { - LM_CRIT("BUG in getting AVP name\n"); - return -1; - } - - res.n = usec; - if (add_avp(avp_type, avp_name, res) < 0) { - LM_ERR("cannot add AVP\n"); - return -1; - } - } else { - LM_ERR("failed to get time\n"); - return -1; - } break; case SWITCH_T: script_trace("core", "switch", msg, a->file, a->line) ; @@ -1964,7 +793,7 @@ int do_action(struct action* a, struct sip_msg* msg) } ret=return_code; break; - case MODULE_T: + case CMD_T: if (a->elem[0].type != CMD_ST || ((cmd = (cmd_export_t*)a->elem[0].u.data) == NULL)) { LM_ALERT("BUG in module call\n"); @@ -2053,75 +882,6 @@ int do_action(struct action* a, struct sip_msg* msg) } } break; - case FORCE_RPORT_T: - script_trace("core", "force_rport", msg, a->file, a->line) ; - msg->msg_flags|=FL_FORCE_RPORT; - ret=1; /* continue processing */ - break; - case FORCE_LOCAL_RPORT_T: - script_trace("core", "force_local_rport", msg, a->file, a->line) ; - msg->msg_flags|=FL_FORCE_LOCAL_RPORT; - ret=1; /* continue processing */ - break; - - case SET_ADV_ADDR_T: - script_trace("core", "set_adv_addr", msg, a->file, a->line); - ret = do_action_set_adv_address(msg, a); - break; - - case SET_ADV_PORT_T: - script_trace("core", "set_adv_port", msg, a->file, a->line); - ret = do_action_set_adv_port(msg, a); - break; - - case FORCE_TCP_ALIAS_T: - script_trace("core", "force_tcp_alias", msg, a->file, a->line) ; - if (is_tcp_based_proto(msg->rcv.proto)) { - if (a->elem[0].type==NOSUBTYPE) port=msg->via1->port; - else if (a->elem[0].type==NUMBER_ST) - port=(int)a->elem[0].u.number; - else{ - LM_ALERT("BUG in force_tcp_alias" - " port type %d\n", a->elem[0].type); - ret=E_BUG; - break; - } - - if (tcpconn_add_alias(msg->rcv.proto_reserved1, port, - msg->rcv.proto)!=0){ - LM_WARN("tcp alias failed\n"); - ret=E_UNSPEC; - break; - } - } - ret=1; /* continue processing */ - break; - case FORCE_SEND_SOCKET_T: - script_trace("core", "force_send_socket", msg, a->file, a->line) ; - if (a->elem[0].type!=SOCKETINFO_ST){ - LM_ALERT("BUG in force_send_socket argument" - " type: %d\n", a->elem[0].type); - ret=E_BUG; - break; - } - msg->force_send_socket=(struct socket_info*)a->elem[0].u.data; - ret=1; /* continue processing */ - break; - case SERIALIZE_BRANCHES_T: - script_trace("core", "serialize_branches", msg, a->file, a->line) ; - if (serialize_branches(msg,(int)a->elem[0].u.number, - a->elem[1].u.data ? (int)a->elem[1].u.number : 0)!=0) { - LM_ERR("serialize_branches failed\n"); - ret=E_UNSPEC; - break; - } - ret=1; - break; - case NEXT_BRANCHES_T: - script_trace("core", "next_branches", msg, a->file, a->line) ; - if ((ret = next_branches(msg)) < 0) - LM_DBG("no more branches\n"); - break; case EQ_T: case COLONEQ_T: case PLUSEQ_T: @@ -2134,117 +894,6 @@ int do_action(struct action* a, struct sip_msg* msg) case BXOREQ_T: ret = do_assign(msg, a); break; - case USE_BLACKLIST_T: - script_trace("core", "use_blacklist", msg, a->file, a->line) ; - mark_for_search((struct bl_head*)a->elem[0].u.data, 1); - break; - case UNUSE_BLACKLIST_T: - script_trace("core", "unuse_blacklist", msg, a->file, a->line); - mark_for_search((struct bl_head*)a->elem[0].u.data, 0); - break; - case PV_PRINTF_T: - script_trace("core", "pv_printf", msg, a->file, a->line); - ret = -1; - spec = (pv_spec_p)a->elem[0].u.data; - if(!pv_is_w(spec)) - { - LM_ERR("read only PV in first parameter of pv_printf\n"); - goto error; - } - - model = (pv_elem_p)a->elem[1].u.data; - - memset(&val, 0, sizeof(pv_value_t)); - if(pv_printf_s(msg, model, &val.rs)!=0) - { - LM_ERR("cannot eval second parameter\n"); - goto error; - } - val.flags = PV_VAL_STR; - if(pv_set_value(msg, spec, EQ_T, &val)<0) - { - LM_ERR("setting PV failed\n"); - goto error; - } - - ret = 1; - break; - case SCRIPT_TRACE_T: - script_trace("core", "script_trace", msg, a->file, a->line); - if (a->elem[0].type==NOSUBTYPE) { - use_script_trace = 0; - } else { - - use_script_trace = 1; - - if (a->elem[0].type != NUMBER_ST || - a->elem[1].type != SCRIPTVAR_ELEM_ST) { - - LM_ERR("BUG in use_script_trace() arguments\n"); - ret=E_BUG; - break; - } - - if (a->elem[2].type!=NOSUBTYPE) { - script_trace_info = (char *)a->elem[2].u.data; - } else { - script_trace_info = NULL; - } - - script_trace_log_level = (int)a->elem[0].u.number; - script_trace_elem = *(pv_elem_p)a->elem[1].u.data; - } - - break; - case IS_MYSELF_T: - script_trace("core", "is_myself", msg, a->file, a->line); - - if ((a->elem[0].type != SCRIPTVAR_ELEM_ST)) { - LM_ALERT("BUG in is_myself() - first argument not of" - " type [%d]\n", a->elem[0].type ); - ret = E_BUG; - break; - } - - /* parse the host argument */ - name_s.s = NULL; name_s.len = 0; - pve = (pv_elem_t *)a->elem[0].u.data; - if (pv_printf_s(msg, pve, &name_s) || name_s.len == 0 || !name_s.s ) { - LM_WARN("cannot get string for value\n"); - ret = E_UNSPEC; - break; - } - - /* get the port */ - if (a->elem[1].type == SCRIPTVAR_ST) { - spec = (pv_spec_t*)a->elem[1].u.data; - memset(&val, 0, sizeof(pv_value_t)); - if (pv_get_spec_value(msg, spec, &val) < 0) { - LM_DBG("Failed to get scriptvar value while executing is_myself\n"); - ret = E_UNSPEC; - break; - } - if (val.flags & PV_VAL_INT) - port = val.ri; - else if (val.flags & PV_VAL_STR) { - if (str2int(&val.rs, (unsigned int*)&port) < 0) { - LM_WARN("Wrong value for is_myself 'port', not an integer [%.*s]\n", - val.rs.len, val.rs.s); - port = 0; - } - } else { - LM_ERR("Wrong value for is_myself 'port'\n"); - ret = E_BUG; - break; - } - - } else if (a->elem[1].type == NUMBER_ST) { - port = (int)a->elem[1].u.number; - } else /* port not specified, ignore port number */ - port = 0; - - ret = check_self(&name_s, port, 0) ? 1 : -1; - break; default: LM_ALERT("BUG - unknown type %d\n", a->type); goto error; @@ -2261,17 +910,6 @@ int do_action(struct action* a, struct sip_msg* msg) LM_ERR("error in %s:%d\n", a->file, a->line); update_longest_action(a); return ret; - -error_uri: - LM_ERR("set*: uri too long\n"); - if (new_uri) - pkg_free(new_uri); - update_longest_action(a); - return E_UNSPEC; - -error_fwd_uri: - update_longest_action(a); - return ret; } static int for_each_handler(struct sip_msg *msg, struct action *a) diff --git a/action.h b/action.h index 3c2977cbf5..be5710f74c 100644 --- a/action.h +++ b/action.h @@ -38,6 +38,9 @@ extern int action_flags; extern int use_script_trace; +extern int script_trace_log_level; +extern char *script_trace_info; +extern pv_elem_t script_trace_elem; #define LONGEST_ACTION_SIZE 5 diff --git a/cfg.lex b/cfg.lex index 362cd1d231..20979abe28 100644 --- a/cfg.lex +++ b/cfg.lex @@ -111,12 +111,10 @@ %x PPTOK_LINE PPTOK_FILEBEG PPTOK_FILEEND /* action keywords */ -FORWARD forward ASSERT "assert" DROP "drop" EXIT "exit" RETURN "return" -SEND send SEND_TCP send_tcp LOG log ERROR error @@ -129,31 +127,6 @@ ROUTE_LOCAL local_route ROUTE_STARTUP startup_route ROUTE_TIMER timer_route ROUTE_EVENT event_route -FORCE_RPORT "force_rport"|"add_rport" -FORCE_LOCAL_RPORT "force_local_rport"|"add_local_rport" -FORCE_TCP_ALIAS "force_tcp_alias"|"add_tcp_alias" -SETFLAG setflag -RESETFLAG resetflag -ISFLAGSET isflagset -SETBFLAG "setbflag"|"setbranchflag" -RESETBFLAG "resetbflag"|"resetbranchflag" -ISBFLAGSET "isbflagset"|"isbranchflagset" -SET_HOST "rewritehost"|"sethost"|"seth" -SET_HOSTPORT "rewritehostport"|"sethostport"|"sethp" -SET_USER "rewriteuser"|"setuser"|"setu" -SET_USERPASS "rewriteuserpass"|"setuserpass"|"setup" -SET_PORT "rewriteport"|"setport"|"setp" -SET_URI "rewriteuri"|"seturi" -REVERT_URI "revert_uri" -SET_DSTURI "setdsturi"|"setduri" -RESET_DSTURI "resetdsturi"|"resetduri" -ISDSTURISET "isdsturiset"|"isduriset" -PREFIX "prefix" -STRIP "strip" -STRIP_TAIL "strip_tail" -APPEND_BRANCH "append_branch" -REMOVE_BRANCH "remove_branch" -PV_PRINTF "pv_printf"|"avp_printf" IF "if" ELSE "else" SWITCH "switch" @@ -163,20 +136,6 @@ BREAK "break" WHILE "while" FOR "for" IN "in" -SET_ADV_ADDRESS "set_advertised_address" -SET_ADV_PORT "set_advertised_port" -FORCE_SEND_SOCKET "force_send_socket" -SERIALIZE_BRANCHES "serialize_branches" -NEXT_BRANCHES "next_branches" -USE_BLACKLIST "use_blacklist" -UNUSE_BLACKLIST "unuse_blacklist" -CACHE_STORE "cache_store" -CACHE_FETCH "cache_fetch" -CACHE_COUNTER_FETCH "cache_counter_fetch" -CACHE_REMOVE "cache_remove" -CACHE_ADD "cache_add" -CACHE_SUB "cache_sub" -CACHE_RAW_QUERY "cache_raw_query" XDBG "xdbg" PV_PRINT_BUF_SIZE "pv_print_buf_size" XLOG_BUF_SIZE "xlog_buf_size" @@ -184,15 +143,9 @@ XLOG_FORCE_COLOR "xlog_force_color" XLOG_PRINT_LEVEL "xlog_print_level" XLOG_LEVEL "xlog_level" XLOG "xlog" -RAISE_EVENT "raise_event" -SUBSCRIBE_EVENT "subscribe_event" -CONSTRUCT_URI "construct_uri" -GET_TIMESTAMP "get_timestamp" -SCRIPT_TRACE "script_trace" SYNC_TOKEN "sync" ASYNC_TOKEN "async" LAUNCH_TOKEN "launch" -IS_MYSELF "is_myself" PPTOK_LINE "__OSSPP_LINE__" PPTOK_FILEBEG "__OSSPP_FILEBEGIN__" PPTOK_FILEEND "__OSSPP_FILEEND__" @@ -389,20 +342,12 @@ SPACE [ ] {EAT_ABLE} { count(); } -{FORWARD} {count(); yylval.strval=yytext; return FORWARD; } {ASSERT} {count(); yylval.strval=yytext; return ASSERT; } {DROP} { count(); yylval.strval=yytext; return DROP; } {EXIT} { count(); yylval.strval=yytext; return EXIT; } {RETURN} { count(); yylval.strval=yytext; return RETURN; } -{SEND} { count(); yylval.strval=yytext; return SEND; } {LOG} { count(); yylval.strval=yytext; return LOG_TOK; } {ERROR} { count(); yylval.strval=yytext; return ERROR; } -{SETFLAG} { count(); yylval.strval=yytext; return SETFLAG; } -{RESETFLAG} { count(); yylval.strval=yytext; return RESETFLAG; } -{ISFLAGSET} { count(); yylval.strval=yytext; return ISFLAGSET; } -{SETBFLAG} { count(); yylval.strval=yytext; return SETBFLAG; } -{RESETBFLAG} { count(); yylval.strval=yytext; return RESETBFLAG; } -{ISBFLAGSET} { count(); yylval.strval=yytext; return ISBFLAGSET; } {ROUTE} { count(); yylval.strval=yytext; return ROUTE; } {ROUTE_ONREPLY} { count(); yylval.strval=yytext; return ROUTE_ONREPLY; } @@ -417,29 +362,6 @@ SPACE [ ] return ROUTE_TIMER; } {ROUTE_EVENT} { count(); yylval.strval=yytext; return ROUTE_EVENT; } -{SET_HOST} { count(); yylval.strval=yytext; return SET_HOST; } -{SET_HOSTPORT} { count(); yylval.strval=yytext; return SET_HOSTPORT; } -{SET_USER} { count(); yylval.strval=yytext; return SET_USER; } -{SET_USERPASS} { count(); yylval.strval=yytext; return SET_USERPASS; } -{SET_PORT} { count(); yylval.strval=yytext; return SET_PORT; } -{SET_URI} { count(); yylval.strval=yytext; return SET_URI; } -{REVERT_URI} { count(); yylval.strval=yytext; return REVERT_URI; } -{SET_DSTURI} { count(); yylval.strval=yytext; return SET_DSTURI; } -{RESET_DSTURI} { count(); yylval.strval=yytext; return RESET_DSTURI; } -{ISDSTURISET} { count(); yylval.strval=yytext; return ISDSTURISET; } -{PREFIX} { count(); yylval.strval=yytext; return PREFIX; } -{STRIP} { count(); yylval.strval=yytext; return STRIP; } -{STRIP_TAIL} { count(); yylval.strval=yytext; return STRIP_TAIL; } -{APPEND_BRANCH} { count(); yylval.strval=yytext; - return APPEND_BRANCH; } -{REMOVE_BRANCH} { count(); yylval.strval=yytext; - return REMOVE_BRANCH; } -{PV_PRINTF} { count(); yylval.strval=yytext; - return PV_PRINTF; } -{FORCE_RPORT} { count(); yylval.strval=yytext; return FORCE_RPORT; } -{FORCE_LOCAL_RPORT} { count(); yylval.strval=yytext; return FORCE_LOCAL_RPORT; } -{FORCE_TCP_ALIAS} { count(); yylval.strval=yytext; - return FORCE_TCP_ALIAS; } {IF} { count(); yylval.strval=yytext; return IF; } {ELSE} { count(); yylval.strval=yytext; return ELSE; } @@ -455,36 +377,6 @@ SPACE [ ] {PPTOK_FILEBEG} { count(); BEGIN(PPTOK_FILEBEG); } {PPTOK_FILEEND} { count(); BEGIN(PPTOK_FILEEND); } -{SET_ADV_ADDRESS} { count(); yylval.strval=yytext; - return SET_ADV_ADDRESS; } -{SET_ADV_PORT} { count(); yylval.strval=yytext; - return SET_ADV_PORT; } -{FORCE_SEND_SOCKET} { count(); yylval.strval=yytext; - return FORCE_SEND_SOCKET; } -{SERIALIZE_BRANCHES} { count(); yylval.strval=yytext; - return SERIALIZE_BRANCHES; } -{NEXT_BRANCHES} { count(); yylval.strval=yytext; - return NEXT_BRANCHES; } -{USE_BLACKLIST} { count(); yylval.strval=yytext; - return USE_BLACKLIST; } -{UNUSE_BLACKLIST} { count(); yylval.strval=yytext; - return UNUSE_BLACKLIST; } - -{CACHE_STORE} { count(); yylval.strval=yytext; - return CACHE_STORE; } -{CACHE_FETCH} { count(); yylval.strval=yytext; - return CACHE_FETCH; } -{CACHE_COUNTER_FETCH} { count(); yylval.strval=yytext; - return CACHE_COUNTER_FETCH; } -{CACHE_REMOVE} { count(); yylval.strval=yytext; - return CACHE_REMOVE; } -{CACHE_ADD} { count(); yylval.strval=yytext; - return CACHE_ADD; } -{CACHE_SUB} { count(); yylval.strval=yytext; - return CACHE_SUB; } -{CACHE_RAW_QUERY} { count(); yylval.strval=yytext; - return CACHE_RAW_QUERY; } - {XDBG} { count(); yylval.strval=yytext; return XDBG; } {PV_PRINT_BUF_SIZE} { count(); yylval.strval=yytext; @@ -499,24 +391,12 @@ SPACE [ ] return XLOG_PRINT_LEVEL;} {XLOG_LEVEL} { count(); yylval.strval=yytext; return XLOG_LEVEL;} -{RAISE_EVENT} { count(); yylval.strval=yytext; - return RAISE_EVENT;} -{SUBSCRIBE_EVENT} { count(); yylval.strval=yytext; - return SUBSCRIBE_EVENT;} -{CONSTRUCT_URI} { count(); yylval.strval=yytext; - return CONSTRUCT_URI;} -{GET_TIMESTAMP} { count(); yylval.strval=yytext; - return GET_TIMESTAMP;} -{SCRIPT_TRACE} { count(); yylval.strval=yytext; - return SCRIPT_TRACE;} {SYNC_TOKEN} { count(); yylval.strval=yytext; return SYNC_TOKEN;} {ASYNC_TOKEN} { count(); yylval.strval=yytext; return ASYNC_TOKEN;} {LAUNCH_TOKEN} { count(); yylval.strval=yytext; return LAUNCH_TOKEN;} -{IS_MYSELF} { count(); yylval.strval=yytext; - return IS_MYSELF;} {FORK} { count(); yylval.strval=yytext; return FORK; /*obsolete*/ } {DEBUG_MODE} { count(); yylval.strval=yytext; return DEBUG_MODE; } diff --git a/cfg.y b/cfg.y index a40f3e6d9a..7f18600330 100644 --- a/cfg.y +++ b/cfg.y @@ -136,7 +136,6 @@ static str s_tmp; static str tstr; static struct net* net_tmp; static pv_spec_t *spec; -static pv_elem_t *pvmodel; static struct bl_rule *bl_head = 0; static struct bl_rule *bl_tail = 0; @@ -485,7 +484,7 @@ extern int cfg_parse_only_routes; %type action actions brk_action brk_actions cmd if_cmd stm brk_stm %type exp_stm assign_cmd while_cmd foreach_cmd async_func brk_if_cmd %type switch_cmd switch_stm case_stms case_stm default_stm -%type module_func_param +%type func_param %type ipv4 ipv6 ipv6addr ip %type ipnet %type script_var @@ -1885,12 +1884,12 @@ default_stm: DEFAULT COLON brk_actions { mk_action1( $$, DEFAULT_T, | DEFAULT COLON { mk_action1( $$, DEFAULT_T, ACTIONS_ST, NULL); } ; -module_func_param: STRING { +func_param: STRING { elems[1].type = STR_ST; elems[1].u.data = $1; $$=1; } - | module_func_param COMMA STRING { + | func_param COMMA STRING { if ($1+1>=MAX_ACTION_ELEMS) { yyerror("too many arguments " "in function\n"); @@ -1914,7 +1913,7 @@ module_func_param: STRING { elems[2].u.data = $2; $$=2; } - | module_func_param COMMA { + | func_param COMMA { if ($1+1>=MAX_ACTION_ELEMS) { yyerror("too many arguments " "in function\n"); @@ -1936,7 +1935,7 @@ module_func_param: STRING { elems[2].u.number = $2; $$=2; } - | module_func_param COMMA snumber { + | func_param COMMA snumber { if ($1+1>=MAX_ACTION_ELEMS) { yyerror("too many arguments " "in function\n"); @@ -1958,7 +1957,7 @@ module_func_param: STRING { elems[2].u.data = $2; $$=2; } - | module_func_param COMMA script_var { + | func_param COMMA script_var { if ($1+1>=MAX_ACTION_ELEMS) { yyerror("too many arguments " "in function\n"); @@ -2033,7 +2032,7 @@ route_param: STRING { ; async_func: ID LPAREN RPAREN { - cmd_tmp=(void*)find_acmd_export_t($1); + cmd_tmp=(void*)find_mod_acmd_export_t($1); if (cmd_tmp==0){ yyerrorf("unknown async command <%s>, " "missing loadmodule?", $1); @@ -2050,8 +2049,8 @@ async_func: ID LPAREN RPAREN { } } } - | ID LPAREN module_func_param RPAREN { - cmd_tmp=(void*)find_acmd_export_t($1); + | ID LPAREN func_param RPAREN { + cmd_tmp=(void*)find_mod_acmd_export_t($1); if (cmd_tmp==0){ yyerrorf("unknown async command <%s>, " "missing loadmodule?", $1); @@ -2091,39 +2090,7 @@ async_func: ID LPAREN RPAREN { } ; -cmd: FORWARD LPAREN STRING RPAREN { mk_action2( $$, FORWARD_T, - STRING_ST, - 0, - $3, - 0); - } - | FORWARD LPAREN RPAREN { - mk_action2( $$, FORWARD_T, - 0, - 0, - 0, - 0); - } - | FORWARD error { $$=0; yyerror("missing '(' or ')' ?"); } - | FORWARD LPAREN error RPAREN { $$=0; yyerror("bad forward " - "argument"); } - - | SEND LPAREN STRING RPAREN { mk_action2( $$, SEND_T, - STRING_ST, - 0, - $3, - 0); - } - | SEND LPAREN STRING COMMA STRING RPAREN { mk_action2( $$, SEND_T, - STRING_ST, - STRING_ST, - $3, - $5); - } - | SEND error { $$=0; yyerror("missing '(' or ')' ?"); } - | SEND LPAREN error RPAREN { $$=0; yyerror("bad send" - "argument"); } - | ASSERT LPAREN exp COMMA STRING RPAREN { +cmd: ASSERT LPAREN exp COMMA STRING RPAREN { mk_action2( $$, ASSERT_T, EXPR_ST, STRING_ST, $3, $5); } | DROP LPAREN RPAREN {mk_action2( $$, DROP_T,0, 0, 0, 0); } @@ -2166,71 +2133,6 @@ cmd: FORWARD LPAREN STRING RPAREN { mk_action2( $$, FORWARD_T, | LOG_TOK error { $$=0; yyerror("missing '(' or ')' ?"); } | LOG_TOK LPAREN error RPAREN { $$=0; yyerror("bad log" "argument"); } - | SETFLAG LPAREN NUMBER RPAREN { - mk_action2($$, SETFLAG_T, NUMBER_ST, 0, (void *)$3, 0 ); - } - | SETFLAG LPAREN ID RPAREN {mk_action2($$, SETFLAG_T, STR_ST, 0, - (void *)$3, 0 ); } - | SETFLAG error { $$=0; yyerror("missing '(' or ')'?"); } - | RESETFLAG LPAREN NUMBER RPAREN {mk_action2( $$, RESETFLAG_T, - NUMBER_ST, 0, (void *)$3, 0 ); } - | RESETFLAG LPAREN ID RPAREN {mk_action2( $$, RESETFLAG_T, - STR_ST, 0, (void *)$3, 0 ); } - | RESETFLAG error { $$=0; yyerror("missing '(' or ')'?"); } - | ISFLAGSET LPAREN NUMBER RPAREN {mk_action2( $$, ISFLAGSET_T, - NUMBER_ST, 0, (void *)$3, 0 ); } - | ISFLAGSET LPAREN ID RPAREN {mk_action2( $$, ISFLAGSET_T, - STR_ST, 0, (void *)$3, 0 ); } - | ISFLAGSET error { $$=0; yyerror("missing '(' or ')'?"); } - | SETBFLAG LPAREN NUMBER COMMA NUMBER RPAREN {mk_action2( $$, - SETBFLAG_T, - NUMBER_ST, NUMBER_ST, - (void *)$3, (void *)$5 ); } - | SETBFLAG LPAREN NUMBER COMMA ID RPAREN {mk_action2( $$, - SETBFLAG_T, - NUMBER_ST, STR_ST, - (void *)$3, (void *)$5 ); } - | SETBFLAG LPAREN NUMBER RPAREN {mk_action2( $$, SETBFLAG_T, - NUMBER_ST, NUMBER_ST, - 0, (void *)$3 ); } - | SETBFLAG LPAREN ID RPAREN {mk_action2( $$, SETBFLAG_T, - NUMBER_ST, STR_ST, - 0, (void *)$3 ); } - | SETBFLAG error { $$=0; yyerror("missing '(' or ')'?"); } - | RESETBFLAG LPAREN NUMBER COMMA NUMBER RPAREN {mk_action2( $$, - RESETBFLAG_T, - NUMBER_ST, NUMBER_ST, - (void *)$3, (void *)$5 ); } - | RESETBFLAG LPAREN NUMBER COMMA ID RPAREN {mk_action2( $$, - RESETBFLAG_T, - NUMBER_ST, STR_ST, - (void *)$3, (void *)$5 ); } - | RESETBFLAG LPAREN NUMBER RPAREN {mk_action2( $$, - RESETBFLAG_T, - NUMBER_ST, NUMBER_ST, - 0, (void *)$3 ); } - | RESETBFLAG LPAREN ID RPAREN {mk_action2( $$, - RESETBFLAG_T, - NUMBER_ST, STR_ST, - 0, (void *)$3 ); } - | RESETBFLAG error { $$=0; yyerror("missing '(' or ')'?"); } - | ISBFLAGSET LPAREN NUMBER COMMA NUMBER RPAREN {mk_action2( $$, - ISBFLAGSET_T, - NUMBER_ST, NUMBER_ST, - (void *)$3, (void *)$5 ); } - | ISBFLAGSET LPAREN NUMBER COMMA ID RPAREN {mk_action2( $$, - ISBFLAGSET_T, - NUMBER_ST, STR_ST, - (void *)$3, (void *)$5 ); } - | ISBFLAGSET LPAREN NUMBER RPAREN {mk_action2( $$, - ISBFLAGSET_T, - NUMBER_ST, NUMBER_ST, - 0, (void *)$3 ); } - | ISBFLAGSET LPAREN ID RPAREN {mk_action2( $$, - ISBFLAGSET_T, - NUMBER_ST, STR_ST, - 0, (void *)$3 ); } - | ISBFLAGSET error { $$=0; yyerror("missing '(' or ')'?"); } | ERROR LPAREN STRING COMMA STRING RPAREN {mk_action2( $$, ERROR_T, STRING_ST, STRING_ST, @@ -2273,389 +2175,6 @@ cmd: FORWARD LPAREN STRING RPAREN { mk_action2( $$, FORWARD_T, | ROUTE error { $$=0; yyerror("missing '(' or ')' ?"); } | ROUTE LPAREN error RPAREN { $$=0; yyerror("bad route" "argument"); } - | SET_HOST LPAREN STRING RPAREN { mk_action2( $$, SET_HOST_T, STR_ST, - 0, $3, 0); } - | SET_HOST error { $$=0; yyerror("missing '(' or ')' ?"); } - | SET_HOST LPAREN error RPAREN { $$=0; yyerror("bad argument, " - "string expected"); } - - | PREFIX LPAREN STRING RPAREN { mk_action2( $$, PREFIX_T, STR_ST, - 0, $3, 0); } - | PREFIX error { $$=0; yyerror("missing '(' or ')' ?"); } - | PREFIX LPAREN error RPAREN { $$=0; yyerror("bad argument, " - "string expected"); } - | STRIP_TAIL LPAREN NUMBER RPAREN { mk_action2( $$, STRIP_TAIL_T, - NUMBER_ST, 0, (void *) $3, 0); } - | STRIP_TAIL error { $$=0; yyerror("missing '(' or ')' ?"); } - | STRIP_TAIL LPAREN error RPAREN { $$=0; yyerror("bad argument, " - "number expected"); } - - | STRIP LPAREN NUMBER RPAREN { mk_action2( $$, STRIP_T, NUMBER_ST, - 0, (void *) $3, 0); } - | STRIP error { $$=0; yyerror("missing '(' or ')' ?"); } - | STRIP LPAREN error RPAREN { $$=0; yyerror("bad argument, " - "number expected"); } - | APPEND_BRANCH LPAREN STRING COMMA STRING RPAREN { - { - qvalue_t q; - - rc = str2q(&q, $5, strlen($5)); - if (rc < 0) - yyerrorf("bad qvalue (%.*s): %s", - strlen($5), $5, qverr2str(rc)); - - mk_action2( $$, APPEND_BRANCH_T, STR_ST, NUMBER_ST, $3, - (void *)(long)q); - } - } - | APPEND_BRANCH LPAREN STRING RPAREN { mk_action2( $$, APPEND_BRANCH_T, - STR_ST, NUMBER_ST, $3, (void *)Q_UNSPECIFIED) ; } - | APPEND_BRANCH LPAREN RPAREN { mk_action2( $$, APPEND_BRANCH_T, - STR_ST, NUMBER_ST, 0, (void *)Q_UNSPECIFIED) ; } - | APPEND_BRANCH { mk_action2( $$, APPEND_BRANCH_T, - STR_ST, NUMBER_ST, 0, (void *)Q_UNSPECIFIED ) ; } - | REMOVE_BRANCH LPAREN NUMBER RPAREN { - mk_action1($$, REMOVE_BRANCH_T, NUMBER_ST, (void*)$3);} - | REMOVE_BRANCH LPAREN script_var RPAREN { - mk_action1( $$, REMOVE_BRANCH_T, SCRIPTVAR_ST, $3);} - | PV_PRINTF LPAREN STRING COMMA STRING RPAREN { - spec = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t)); - memset(spec, 0, sizeof(pv_spec_t)); - tstr.s = $3; - tstr.len = strlen(tstr.s); - if(pv_parse_spec(&tstr, spec)==NULL) - { - yyerror("unknown script variable in first parameter"); - } - if(!pv_is_w(spec)) - yyerror("read-only script variable in first parameter"); - - pvmodel = 0; - tstr.s = $5; - tstr.len = strlen(tstr.s); - if(pv_parse_format(&tstr, &pvmodel)<0) - { - yyerror("error in second parameter"); - } - - mk_action2( $$, PV_PRINTF_T, - SCRIPTVAR_ST, SCRIPTVAR_ELEM_ST, spec, pvmodel) ; - } - | PV_PRINTF LPAREN script_var COMMA STRING RPAREN { - if(!pv_is_w($3)) - yyerror("read-only script variable in first parameter"); - pvmodel = 0; - tstr.s = $5; - tstr.len = strlen(tstr.s); - if(pv_parse_format(&tstr, &pvmodel)<0) - { - yyerror("error in second parameter"); - } - - mk_action2( $$, PV_PRINTF_T, - SCRIPTVAR_ST, SCRIPTVAR_ELEM_ST, $3, pvmodel) ; - } - - | SET_HOSTPORT LPAREN STRING RPAREN { mk_action2( $$, SET_HOSTPORT_T, - STR_ST, 0, $3, 0); } - | SET_HOSTPORT error { $$=0; yyerror("missing '(' or ')' ?"); } - | SET_HOSTPORT LPAREN error RPAREN { $$=0; yyerror("bad argument," - " string expected"); } - | SET_PORT LPAREN STRING RPAREN { mk_action2( $$, SET_PORT_T, STR_ST, - 0, $3, 0); } - | SET_PORT error { $$=0; yyerror("missing '(' or ')' ?"); } - | SET_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, " - "string expected"); } - | SET_USER LPAREN STRING RPAREN { mk_action2( $$, SET_USER_T, - STR_ST, 0, $3, 0); } - | SET_USER error { $$=0; yyerror("missing '(' or ')' ?"); } - | SET_USER LPAREN error RPAREN { $$=0; yyerror("bad argument, " - "string expected"); } - | SET_USERPASS LPAREN STRING RPAREN { mk_action2( $$, SET_USERPASS_T, - STR_ST, 0, $3, 0); } - | SET_USERPASS error { $$=0; yyerror("missing '(' or ')' ?"); } - | SET_USERPASS LPAREN error RPAREN { $$=0; yyerror("bad argument, " - "string expected"); } - | SET_URI LPAREN STRING RPAREN { mk_action2( $$, SET_URI_T, STR_ST, - 0, $3, 0); } - | SET_URI error { $$=0; yyerror("missing '(' or ')' ?"); } - | SET_URI LPAREN error RPAREN { $$=0; yyerror("bad argument, " - "string expected"); } - | REVERT_URI LPAREN RPAREN { mk_action2( $$, REVERT_URI_T, 0,0,0,0); } - | REVERT_URI { mk_action2( $$, REVERT_URI_T, 0,0,0,0); } - | SET_DSTURI LPAREN STRING RPAREN { mk_action2( $$, SET_DSTURI_T, - STR_ST, 0, $3, 0); } - | SET_DSTURI error { $$=0; yyerror("missing '(' or ')' ?"); } - | SET_DSTURI LPAREN error RPAREN { $$=0; yyerror("bad argument, " - "string expected"); } - | RESET_DSTURI LPAREN RPAREN { mk_action2( $$, RESET_DSTURI_T, - 0,0,0,0); } - | RESET_DSTURI { mk_action2( $$, RESET_DSTURI_T, 0,0,0,0); } - | ISDSTURISET LPAREN RPAREN { mk_action2( $$, ISDSTURISET_T, 0,0,0,0);} - | ISDSTURISET { mk_action2( $$, ISDSTURISET_T, 0,0,0,0); } - | FORCE_RPORT LPAREN RPAREN { mk_action2( $$, FORCE_RPORT_T, - 0, 0, 0, 0); } - | FORCE_RPORT { mk_action2( $$, FORCE_RPORT_T,0, 0, 0, 0); } - | FORCE_LOCAL_RPORT LPAREN RPAREN { - mk_action2( $$, FORCE_LOCAL_RPORT_T,0, 0, 0, 0); } - | FORCE_LOCAL_RPORT { - mk_action2( $$, FORCE_LOCAL_RPORT_T,0, 0, 0, 0); } - | FORCE_TCP_ALIAS LPAREN NUMBER RPAREN { - mk_action2( $$, FORCE_TCP_ALIAS_T,NUMBER_ST, 0, - (void*)$3, 0); - } - | FORCE_TCP_ALIAS LPAREN RPAREN { - mk_action2( $$, FORCE_TCP_ALIAS_T,0, 0, 0, 0); - } - | FORCE_TCP_ALIAS { - mk_action2( $$, FORCE_TCP_ALIAS_T,0, 0, 0, 0); - } - | FORCE_TCP_ALIAS LPAREN error RPAREN {$$=0; - yyerror("bad argument, number expected"); - } - | SET_ADV_ADDRESS LPAREN listen_id RPAREN { - mk_action2( $$, SET_ADV_ADDR_T, STR_ST, - 0, $3, 0); - } - | SET_ADV_ADDRESS LPAREN error RPAREN { $$=0; yyerror("bad argument, " - "string expected"); } - | SET_ADV_ADDRESS error {$$=0; yyerror("missing '(' or ')' ?"); } - | SET_ADV_PORT LPAREN NUMBER RPAREN { - tstr.s = int2str($3, &tstr.len); - if (!(tmp = pkg_malloc(tstr.len + 1))) { - LM_CRIT("out of pkg memory\n"); - $$ = 0; - YYABORT; - } else { - memcpy(tmp, tstr.s, tstr.len); - tmp[tstr.len] = '\0'; - mk_action2($$, SET_ADV_PORT_T, STR_ST, - 0, tmp, 0); - } - } - | SET_ADV_PORT LPAREN STRING RPAREN { - mk_action2($$, SET_ADV_PORT_T, - STR_ST, NOSUBTYPE, - $3, NULL); - } - | SET_ADV_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument " - "(string or integer expected)"); } - | SET_ADV_PORT error {$$=0; yyerror("missing '(' or ')' ?"); } - | FORCE_SEND_SOCKET LPAREN phostport RPAREN { - mk_action2( $$, FORCE_SEND_SOCKET_T, - SOCKID_ST, 0, $3, 0); - } - | FORCE_SEND_SOCKET LPAREN error RPAREN { $$=0; yyerror("bad argument," - " proto:host[:port] expected"); - } - | FORCE_SEND_SOCKET error {$$=0; yyerror("missing '(' or ')' ?"); } - | SERIALIZE_BRANCHES LPAREN NUMBER RPAREN { - mk_action1( $$, SERIALIZE_BRANCHES_T, - NUMBER_ST, (void*)(long)$3); - } - | SERIALIZE_BRANCHES LPAREN NUMBER COMMA NUMBER RPAREN { - mk_action2( $$, SERIALIZE_BRANCHES_T, - NUMBER_ST, NUMBER_ST, - (void*)(long)$3, (void*)(long)$5); - } - | SERIALIZE_BRANCHES LPAREN error RPAREN {$$=0; yyerror("bad argument," - " number expected"); - } - | SERIALIZE_BRANCHES error {$$=0; yyerror("missing '(' or ')' ?"); } - | NEXT_BRANCHES LPAREN RPAREN { - mk_action2( $$, NEXT_BRANCHES_T, 0, 0, 0, 0); - } - | NEXT_BRANCHES LPAREN error RPAREN {$$=0; yyerror("no argument is" - " expected"); - } - | NEXT_BRANCHES error {$$=0; yyerror("missing '(' or ')' ?"); } - | USE_BLACKLIST LPAREN STRING RPAREN { - mk_action2( $$, USE_BLACKLIST_T, - STRING_ST, 0, $3, 0); - } - | USE_BLACKLIST LPAREN error RPAREN {$$=0; yyerror("bad argument," - " string expected"); - } - | USE_BLACKLIST error {$$=0; yyerror("missing '(' or ')' ?"); } - | UNUSE_BLACKLIST LPAREN STRING RPAREN { - mk_action2( $$, UNUSE_BLACKLIST_T, - STRING_ST, 0, $3, 0); - } - | UNUSE_BLACKLIST LPAREN error RPAREN {$$=0; yyerror("bad argument," - " string expected"); - } - | UNUSE_BLACKLIST error {$$=0; yyerror("missing '(' or ')' ?"); } - | CACHE_STORE LPAREN STRING COMMA STRING COMMA STRING RPAREN { - mk_action3( $$, CACHE_STORE_T, - STR_ST, - STR_ST, - STR_ST, - $3, - $5, - $7); - } - | CACHE_STORE LPAREN STRING COMMA STRING COMMA STRING COMMA NUMBER - RPAREN { - elems[0].type = STR_ST; - elems[0].u.data = $3; - elems[1].type = STR_ST; - elems[1].u.data = $5; - elems[2].type = STR_ST; - elems[2].u.data = $7; - elems[3].type = NUMBER_ST; - elems[3].u.number = $9; - mk_action_($$, CACHE_STORE_T, 4, elems); - } - | CACHE_STORE LPAREN STRING COMMA STRING COMMA STRING COMMA script_var - RPAREN { - elems[0].type = STR_ST; - elems[0].u.data = $3; - elems[1].type = STR_ST; - elems[1].u.data = $5; - elems[2].type = STR_ST; - elems[2].u.data = $7; - elems[3].type = SCRIPTVAR_ST; - elems[3].u.data = $9; - mk_action_($$, CACHE_STORE_T, 4, elems); - } - - | CACHE_REMOVE LPAREN STRING COMMA STRING RPAREN { - mk_action2( $$, CACHE_REMOVE_T, - STR_ST, - STR_ST, - $3, - $5); - } - | CACHE_FETCH LPAREN STRING COMMA STRING COMMA script_var RPAREN { - mk_action3( $$, CACHE_FETCH_T, - STR_ST, - STR_ST, - SCRIPTVAR_ST, - $3, - $5, - $7); - } - | CACHE_COUNTER_FETCH LPAREN STRING COMMA STRING COMMA script_var RPAREN { - mk_action3( $$, CACHE_COUNTER_FETCH_T, - STR_ST, - STR_ST, - SCRIPTVAR_ST, - $3, - $5, - $7); - } - | CACHE_ADD LPAREN STRING COMMA STRING COMMA NUMBER COMMA NUMBER RPAREN { - elems[0].type = STR_ST; - elems[0].u.data = $3; - elems[1].type = STR_ST; - elems[1].u.data = $5; - elems[2].type = NUMBER_ST; - elems[2].u.number = $7; - elems[3].type = NUMBER_ST; - elems[3].u.number = $9; - mk_action_($$, CACHE_ADD_T, 4, elems); - } - | CACHE_ADD LPAREN STRING COMMA STRING COMMA script_var COMMA NUMBER RPAREN { - elems[0].type = STR_ST; - elems[0].u.data = $3; - elems[1].type = STR_ST; - elems[1].u.data = $5; - elems[2].type = SCRIPTVAR_ST; - elems[2].u.data = $7; - elems[3].type = NUMBER_ST; - elems[3].u.number = $9; - mk_action_($$, CACHE_ADD_T, 4, elems); - } - | CACHE_ADD LPAREN STRING COMMA STRING COMMA NUMBER COMMA NUMBER COMMA script_var RPAREN { - elems[0].type = STR_ST; - elems[0].u.data = $3; - elems[1].type = STR_ST; - elems[1].u.data = $5; - elems[2].type = NUMBER_ST; - elems[2].u.number = $7; - elems[3].type = NUMBER_ST; - elems[3].u.number = $9; - elems[4].type = SCRIPTVAR_ST; - elems[4].u.data = $11; - mk_action_($$, CACHE_ADD_T, 5, elems); - } - | CACHE_ADD LPAREN STRING COMMA STRING COMMA script_var COMMA NUMBER COMMA script_var RPAREN { - elems[0].type = STR_ST; - elems[0].u.data = $3; - elems[1].type = STR_ST; - elems[1].u.data = $5; - elems[2].type = SCRIPTVAR_ST; - elems[2].u.data = $7; - elems[3].type = NUMBER_ST; - elems[3].u.number = $9; - elems[4].type = SCRIPTVAR_ST; - elems[4].u.data = $11; - mk_action_($$, CACHE_ADD_T, 5, elems); - } - | CACHE_SUB LPAREN STRING COMMA STRING COMMA NUMBER COMMA NUMBER RPAREN { - elems[0].type = STR_ST; - elems[0].u.data = $3; - elems[1].type = STR_ST; - elems[1].u.data = $5; - elems[2].type = NUMBER_ST; - elems[2].u.number = $7; - elems[3].type = NUMBER_ST; - elems[3].u.number = $9; - mk_action_($$, CACHE_SUB_T, 4, elems); - } - | CACHE_SUB LPAREN STRING COMMA STRING COMMA script_var COMMA NUMBER RPAREN { - elems[0].type = STR_ST; - elems[0].u.data = $3; - elems[1].type = STR_ST; - elems[1].u.data = $5; - elems[2].type = SCRIPTVAR_ST; - elems[2].u.data = $7; - elems[3].type = NUMBER_ST; - elems[3].u.number = $9; - mk_action_($$, CACHE_SUB_T, 4, elems); - } - | CACHE_SUB LPAREN STRING COMMA STRING COMMA NUMBER COMMA NUMBER COMMA script_var RPAREN { - elems[0].type = STR_ST; - elems[0].u.data = $3; - elems[1].type = STR_ST; - elems[1].u.data = $5; - elems[2].type = NUMBER_ST; - elems[2].u.number = $7; - elems[3].type = NUMBER_ST; - elems[3].u.number = $9; - elems[4].type = SCRIPTVAR_ST; - elems[4].u.data = $11; - mk_action_($$, CACHE_SUB_T, 5, elems); - } - | CACHE_SUB LPAREN STRING COMMA STRING COMMA script_var COMMA NUMBER COMMA script_var RPAREN { - elems[0].type = STR_ST; - elems[0].u.data = $3; - elems[1].type = STR_ST; - elems[1].u.data = $5; - elems[2].type = SCRIPTVAR_ST; - elems[2].u.data = $7; - elems[3].type = NUMBER_ST; - elems[3].u.number = $9; - elems[4].type = SCRIPTVAR_ST; - elems[4].u.data = $11; - mk_action_($$, CACHE_SUB_T, 5, elems); - } - | CACHE_RAW_QUERY LPAREN STRING COMMA STRING COMMA STRING RPAREN { - elems[0].type = STR_ST; - elems[0].u.data = $3; - elems[1].type = STR_ST; - elems[1].u.data = $5; - elems[2].type = STR_ST; - elems[2].u.data = $7; - mk_action_($$, CACHE_RAW_QUERY_T, 3, elems); - } - | CACHE_RAW_QUERY LPAREN STRING COMMA STRING RPAREN { - elems[0].type = STR_ST; - elems[0].u.data = $3; - elems[1].type = STR_ST; - elems[1].u.data = $5; - mk_action_($$, CACHE_RAW_QUERY_T, 2, elems); - } | ID LPAREN RPAREN { cmd_tmp=(void*)find_cmd_export_t($1, rt); if (cmd_tmp==0){ @@ -2675,11 +2194,11 @@ cmd: FORWARD LPAREN STRING RPAREN { mk_action2( $$, FORWARD_T, } else { elems[0].type = CMD_ST; elems[0].u.data = cmd_tmp; - mk_action_($$, MODULE_T, 1, elems); + mk_action_($$, CMD_T, 1, elems); } } } - | ID LPAREN module_func_param RPAREN { + | ID LPAREN func_param RPAREN { cmd_tmp=(void*)find_cmd_export_t($1, rt); if (cmd_tmp==0){ if (find_cmd_export_t($1, 0)) { @@ -2711,7 +2230,7 @@ cmd: FORWARD LPAREN STRING RPAREN { mk_action2( $$, FORWARD_T, default: elems[0].type = CMD_ST; elems[0].u.data = cmd_tmp; - mk_action_($$, MODULE_T, $3+1, elems); + mk_action_($$, CMD_T, $3+1, elems); } } } @@ -2732,56 +2251,6 @@ cmd: FORWARD LPAREN STRING RPAREN { mk_action2( $$, FORWARD_T, mk_action2($$, XLOG_T, STR_ST, STR_ST, $3, $5); } | XLOG LPAREN STRING COMMA folded_string RPAREN { mk_action2($$, XLOG_T, STR_ST, STR_ST, $3, $5); } - | RAISE_EVENT LPAREN STRING RPAREN { - mk_action1($$, RAISE_EVENT_T, STR_ST, $3); } - | RAISE_EVENT LPAREN STRING COMMA script_var RPAREN { - mk_action2($$, RAISE_EVENT_T, STR_ST, SCRIPTVAR_ST, $3, $5); } - | RAISE_EVENT LPAREN STRING COMMA script_var COMMA script_var RPAREN { - mk_action3($$, RAISE_EVENT_T, STR_ST, SCRIPTVAR_ST, - SCRIPTVAR_ST, $3, $5, $7); } - | SUBSCRIBE_EVENT LPAREN STRING COMMA STRING RPAREN { - mk_action2($$, SUBSCRIBE_EVENT_T, STR_ST, STR_ST, $3, $5); } - | SUBSCRIBE_EVENT LPAREN STRING COMMA STRING COMMA NUMBER RPAREN { - mk_action3($$, SUBSCRIBE_EVENT_T, STR_ST, STR_ST, - NUMBER_ST, $3, $5, (void*)(long)$7); } - | CONSTRUCT_URI LPAREN STRING COMMA STRING COMMA STRING COMMA STRING COMMA STRING COMMA script_var RPAREN { - elems[0].type = STR_ST; - elems[0].u.data = $3; - elems[1].type = STR_ST; - elems[1].u.data = $5; - elems[2].type = STR_ST; - elems[2].u.data = $7; - elems[3].type = STR_ST; - elems[3].u.data = $9; - elems[4].type = STR_ST; - elems[4].u.data = $11; - elems[5].type = SCRIPTVAR_ST; - elems[5].u.data = $13; - mk_action_($$, CONSTRUCT_URI_T,6,elems); } - | GET_TIMESTAMP LPAREN script_var COMMA script_var RPAREN { - elems[0].type = SCRIPTVAR_ST; - elems[0].u.data = $3; - elems[1].type = SCRIPTVAR_ST; - elems[1].u.data = $5; - mk_action_($$, GET_TIMESTAMP_T,2,elems); } - | SCRIPT_TRACE LPAREN RPAREN { - mk_action2($$, SCRIPT_TRACE_T, 0, 0, 0, 0); } - | SCRIPT_TRACE LPAREN NUMBER COMMA STRING RPAREN { - pvmodel = 0; - tstr.s = $5; - tstr.len = strlen(tstr.s); - if(pv_parse_format(&tstr, &pvmodel)<0) - yyerror("error in second parameter"); - mk_action2($$, SCRIPT_TRACE_T, NUMBER_ST, - SCRIPTVAR_ELEM_ST, (void *)$3, pvmodel); } - | SCRIPT_TRACE LPAREN NUMBER COMMA STRING COMMA STRING RPAREN { - pvmodel = 0; - tstr.s = $5; - tstr.len = strlen(tstr.s); - if(pv_parse_format(&tstr, &pvmodel)<0) - yyerror("error in second parameter"); - mk_action3($$, SCRIPT_TRACE_T, NUMBER_ST, - SCRIPTVAR_ELEM_ST, STR_ST, (void *)$3, pvmodel, $7); } | ASYNC_TOKEN LPAREN async_func COMMA route_name RPAREN { i_tmp = get_script_route_idx( $5, sroutes->request, RT_NO, 0); if (i_tmp==-1) yyerror("too many script routes"); @@ -2798,12 +2267,6 @@ cmd: FORWARD LPAREN STRING RPAREN { mk_action2( $$, FORWARD_T, mk_action2($$, LAUNCH_T, ACTIONS_ST, NUMBER_ST, $3, (void*)(long)-1); } - | IS_MYSELF LPAREN STRING RPAREN { - mk_action2($$, IS_MYSELF_T, STR_ST, 0, $3, 0); - } - | IS_MYSELF LPAREN STRING COMMA STRING RPAREN { - mk_action2($$, IS_MYSELF_T, STR_ST, STR_ST, $3, $5); - } ; diff --git a/cmds.c b/cmds.c new file mode 100644 index 0000000000..0a45a4d484 --- /dev/null +++ b/cmds.c @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2019 OpenSIPS Solutions + * + * This file is part of opensips, a free SIP server. + * + * opensips is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version + * + * opensips is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "cmds.h" + +cmd_export_t* find_cmd_export_t(char* name, int flags) +{ + cmd_export_t* cmd; + + cmd = find_core_cmd_export_t(name, flags); + if (!cmd) + cmd = find_mod_cmd_export_t(name, flags); + + return cmd; +} + +/* Checks if the module function is called with the right number of parameters + * and all mandatory parameters are given + * Return: + * 0 - correct call + * -1 - too few parameters + * -2 - too many parameters + * -3 - mandatory parameter omitted + */ +int check_cmd_call_params(cmd_export_t *cmd, action_elem_t *elems, int no_params) +{ + struct cmd_param *param; + int n=0, m=0, i; + + for (param=cmd->params; param->flags; param++, n++) + if (!(param->flags & CMD_PARAM_OPT)) + m = n+1; + + if (no_params < m) /* check the minimum number of arguments for the call, + * including optional params that must be explicitly omitted */ + return -1; + else if (no_params > n) + return -2; + + for (i=1, param=cmd->params; i<=no_params; i++, param++) + if (!(param->flags & CMD_PARAM_OPT) && elems[i].type == NULLV_ST) + return -3; + + return 0; +} + +/* simillar function to check_cmd_call_params but for async cmds */ +int check_acmd_call_params(acmd_export_t *acmd, action_elem_t *elems, int no_params) +{ + struct cmd_param *param; + int n=0, m=0, i; + + for (param=acmd->params; param->flags; param++, n++) + if (!(param->flags & CMD_PARAM_OPT)) + m = n+1; + + if (no_params < m) /* check the minimum number of arguments for the call, + * including optional params that must be explicitly omitted */ + return -1; + else if (no_params > n) + return -2; + + for (i=1, param=acmd->params; i<=no_params; i++, param++) + if (!(param->flags & CMD_PARAM_OPT) && elems[i].type == NULLV_ST) + return -3; + + return 0; +} diff --git a/cmds.h b/cmds.h new file mode 100644 index 0000000000..8d624f3937 --- /dev/null +++ b/cmds.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2019 OpenSIPS Solutions + * + * This file is part of opensips, a free SIP server. + * + * opensips is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version + * + * opensips is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "parser/msg_parser.h" +#include "route_struct.h" +#include "async.h" + +#define MAX_CMD_PARAMS (MAX_ACTION_ELEMS-1) + +/* parameter type flags */ +#define CMD_PARAM_INT (1<<0) /* integer parameter */ +#define CMD_PARAM_STR (1<<1) /* string parameter */ +#define CMD_PARAM_VAR (1<<2) /* PV spec parameter */ +#define CMD_PARAM_REGEX (1<<3) /* regexp string parameter */ + +#define CMD_PARAM_OPT (1<<4) /* optional parameter */ +#define CMD_PARAM_FIX_NULL (1<<5) /* run fixup even if optional parameter is omitted */ +#define CMD_PARAM_NO_EXPAND (1<<6) /* TMPHACK: do not pv-expand strings */ +#define CMD_PARAM_STATIC (1<<7) /* don't accept variables or formatted string */ + +typedef int (*cmd_function)(struct sip_msg*, void*, void*, void*, void*, + void*, void*, void *, void *); +typedef int (*acmd_function)(struct sip_msg*, async_ctx *ctx, + void*, void*, void*, void*, void*, void*, void *, void *); +typedef int (*fixup_function)(void** param); +typedef int (*free_fixup_function)(void** param); + +struct cmd_param { + int flags; /* parameter flags */ + fixup_function fixup; /* pointer to the function called to "fix" the + parameter */ + free_fixup_function + free_fixup; /* pointer to the function called to free the + "fixed" parameter */ +}; + +struct cmd_export_ { + char* name; /* null terminated command name */ + cmd_function function; /* pointer to the corresponding function */ + struct cmd_param + params[MAX_CMD_PARAMS+1]; /* array of parameters */ + int flags; /* Function flags */ +}; + + +struct acmd_export_ { + char* name; /* null terminated command name */ + acmd_function function; /* pointer to the corresponding function */ + struct cmd_param + params[MAX_CMD_PARAMS+1]; /* array of parameters */ +}; + +typedef struct cmd_export_ cmd_export_t; +typedef struct acmd_export_ acmd_export_t; + +cmd_export_t* find_cmd_export_t(char* name, int flags); +int check_cmd_call_params(cmd_export_t *cmd, action_elem_t *elems, int no_params); +int check_acmd_call_params(acmd_export_t *acmd, action_elem_t *elems, int no_params); + +cmd_export_t* find_core_cmd_export_t(char* name, int flags); +cmd_export_t* find_mod_cmd_export_t(char* name, int flags); +acmd_export_t* find_mod_acmd_export_t(char* name); diff --git a/core_cmds.c b/core_cmds.c new file mode 100644 index 0000000000..f69fe5dff4 --- /dev/null +++ b/core_cmds.c @@ -0,0 +1,1253 @@ +/* + * Copyright (C) 2019 OpenSIPS Solutions + * + * This file is part of opensips, a free SIP server. + * + * opensips is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version + * + * opensips is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/* + * Script functions exported by the OpenSIPS core + */ + +#include "action.h" +#include "dprint.h" +#include "proxy.h" +#include "forward.h" +#include "parser/msg_parser.h" +#include "parser/parse_uri.h" +#include "ut.h" +#include "mem/mem.h" +#include "globals.h" +#include "dset.h" +#include "flags.h" +#include "serialize.h" +#include "blacklists.h" +#include "cachedb/cachedb.h" +#include "msg_translator.h" +/* needed by tcpconn_add_alias() */ +#include "net/tcp_conn_defs.h" + +static int fixup_forward_dest(void** param); +static int fixup_destination(void** param); +static int fixup_free_destination(void** param); +static int fixup_mflag(void** param); +static int fixup_bflag(void** param); +static int fixup_qvalue(void** param); +static int fixup_f_send_sock(void** param); +static int fixup_blacklist(void** param); +static int fixup_check_wrvar(void** param); +static int fixup_avp_list(void** param); +static int fixup_check_avp(void** param); +static int fixup_event_name(void** param); +static int fixup_format_string(void** param); +static int fixup_nt_string(void** param); + +static int w_forward(struct sip_msg *msg, struct proxy_l *dest); +static int w_send(struct sip_msg *msg, struct proxy_l *dest, str *headers); +static int w_setflag(struct sip_msg *msg, void *flag); +static int w_resetflag(struct sip_msg *msg, void *flag); +static int w_isflagset(struct sip_msg *msg, void *flag); +static int w_setbflag(struct sip_msg *msg, void *flag, int *branch_idx); +static int w_resetbflag(struct sip_msg *msg, void *flag, int *branch_idx); +static int w_isbflagset(struct sip_msg *msg, void *flag, int *branch_idx); +static int w_sethost(struct sip_msg *msg, str *host); +static int w_sethostport(struct sip_msg *msg, str *hostport); +static int w_setuser(struct sip_msg *msg, str *user); +static int w_setuserpass(struct sip_msg *msg, str *userpass); +static int w_setport(struct sip_msg *msg, str *port); +static int w_seturi(struct sip_msg *msg, str *uri); +static int w_prefix(struct sip_msg *msg, str *prefix); +static int w_strip(struct sip_msg *msg, int *nchars); +static int w_strip_tail(struct sip_msg *msg, int *nchars); +static int w_append_branch(struct sip_msg *msg, str *uri, int *qvalue); +static int w_remove_branch(struct sip_msg *msg, int *branch); +static int w_pv_printf(struct sip_msg *msg, pv_spec_t *var, str *fmt_str); +static int w_revert_uri(struct sip_msg *msg); +static int w_setdsturi(struct sip_msg *msg, str *uri); +static int w_resetdsturi(struct sip_msg *msg); +static int w_isdsturiset(struct sip_msg *msg); +static int w_force_rport(struct sip_msg *msg); +static int w_add_local_rport(struct sip_msg *msg); +static int w_force_tcp_alias(struct sip_msg *msg, int *port); +static int w_set_adv_address(struct sip_msg *msg, str *adv_addr); +static int w_set_adv_port(struct sip_msg *msg, str *adv_port); +static int w_f_send_sock(struct sip_msg *msg, struct socket_info *si); +static int w_serialize_branches(struct sip_msg *msg, int *clear_prev, + int *keep_ord); +static int w_next_branches(struct sip_msg *msg); +static int w_use_blacklist(struct sip_msg *msg, struct bl_head *list); +static int w_unuse_blacklist(struct sip_msg *msg, struct bl_head *list); +static int w_cache_store(struct sip_msg *msg, str *id, str *attr, str *val, + int *expire); +static int w_cache_remove(struct sip_msg *msg, str *id, str *attr); +static int w_cache_fetch(struct sip_msg *msg, str *id, str *attr, + pv_spec_t *res); +static int w_cache_counter_fetch(struct sip_msg *msg, str *id, str *attr, + pv_spec_t *res); +static int w_cache_add(struct sip_msg *msg, str *id, str *attr, + int *inc, int *expire, pv_spec_t *new_val); +static int w_cache_sub(struct sip_msg *msg, str *id, str *attr, + int *dec, int *expire, pv_spec_t *new_val); +static int w_cache_raw_query(struct sip_msg *msg, str *id, str *raw_query, + pvname_list_t *avp_list); +static int w_raise_event(struct sip_msg *msg, void *ev_id, pv_spec_t *attrs_avp, + pv_spec_t *vals_avp); +static int w_subscribe_event(struct sip_msg *msg, str *name, str *socket, + int *expire); +static int w_construct_uri(struct sip_msg *msg, str *proto, str *user, + str *domain, str *port, str *extra, pv_spec_t *result); +static int w_get_timestamp(struct sip_msg *msg, pv_spec_t *sec_avp, + pv_spec_t *usec_avp); +static int w_script_trace(struct sip_msg *msg, int *log_level, + pv_elem_t *fmt_string, void *info_str); +static int w_is_myself(struct sip_msg *msg, str *host, int *port); + +static cmd_export_t core_cmds[]={ + {"forward", (cmd_function)w_forward, { + {CMD_PARAM_STR|CMD_PARAM_OPT|CMD_PARAM_FIX_NULL, + fixup_forward_dest, fixup_free_destination}, {0,0,0}}, + ALL_ROUTES}, + {"send", (cmd_function)w_send, { + {CMD_PARAM_STR, fixup_destination, 0}, + {CMD_PARAM_STR|CMD_PARAM_OPT, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"setflag", (cmd_function)w_setflag, { + {CMD_PARAM_STR|CMD_PARAM_STATIC, fixup_mflag, 0}, {0,0,0}}, + ALL_ROUTES}, + {"resetflag", (cmd_function)w_resetflag, { + {CMD_PARAM_STR|CMD_PARAM_STATIC, fixup_mflag, 0}, {0,0,0}}, + ALL_ROUTES}, + {"isflagset", (cmd_function)w_isflagset, { + {CMD_PARAM_STR|CMD_PARAM_STATIC, fixup_mflag, 0}, {0,0,0}}, + ALL_ROUTES}, + {"setbflag", (cmd_function)w_setbflag, { + {CMD_PARAM_STR|CMD_PARAM_STATIC, fixup_bflag, 0}, + {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"resetbflag", (cmd_function)w_resetbflag, { + {CMD_PARAM_STR|CMD_PARAM_STATIC, fixup_bflag, 0}, + {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"isbflagset", (cmd_function)w_isbflagset, { + {CMD_PARAM_STR|CMD_PARAM_STATIC, fixup_bflag, 0}, + {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"sethost", (cmd_function)w_sethost, { + {CMD_PARAM_STR, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"sethostport", (cmd_function)w_sethostport, { + {CMD_PARAM_STR, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"setuser", (cmd_function)w_setuser, { + {CMD_PARAM_STR, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"setuserpass", (cmd_function)w_setuserpass, { + {CMD_PARAM_STR, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"setport", (cmd_function)w_setport, { + {CMD_PARAM_STR, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"seturi", (cmd_function)w_seturi, { + {CMD_PARAM_STR, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"prefix", (cmd_function)w_prefix, { + {CMD_PARAM_STR, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"strip", (cmd_function)w_strip, { + {CMD_PARAM_INT, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"strip_tail", (cmd_function)w_strip_tail, { + {CMD_PARAM_INT, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"append_branch", (cmd_function)w_append_branch, { + {CMD_PARAM_STR|CMD_PARAM_OPT, 0, 0}, + {CMD_PARAM_STR|CMD_PARAM_OPT|CMD_PARAM_FIX_NULL, + fixup_qvalue, 0}, {0,0,0}}, + ALL_ROUTES}, + {"remove_branch", (cmd_function)w_remove_branch, { + {CMD_PARAM_INT, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"pv_printf", (cmd_function)w_pv_printf, { + {CMD_PARAM_VAR, 0, 0}, + {CMD_PARAM_STR, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"revert_uri", (cmd_function)w_revert_uri, { + {0, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"setdsturi", (cmd_function)w_setdsturi, { + {CMD_PARAM_STR, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"resetdsturi", (cmd_function)w_resetdsturi, { + {0, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"isdsturiset", (cmd_function)w_isdsturiset, { + {0, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"force_rport", (cmd_function)w_force_rport, { + {0, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"add_local_rport", (cmd_function)w_add_local_rport, { + {0, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"force_tcp_alias", (cmd_function)w_force_tcp_alias, { + {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"set_advertised_address", (cmd_function)w_set_adv_address, { + {CMD_PARAM_STR, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"set_advertised_port", (cmd_function)w_set_adv_port, { + {CMD_PARAM_STR, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"force_send_socket", (cmd_function)w_f_send_sock, { + {CMD_PARAM_STR, fixup_f_send_sock, 0}, {0,0,0}}, + ALL_ROUTES}, + {"serialize_branches", (cmd_function)w_serialize_branches, { + {CMD_PARAM_INT, 0, 0}, + {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"next_branches", (cmd_function)w_next_branches, { + {0, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"use_blacklist", (cmd_function)w_use_blacklist, { + {CMD_PARAM_STR, fixup_blacklist, 0}, {0,0,0}}, + ALL_ROUTES}, + {"unuse_blacklist", (cmd_function)w_unuse_blacklist, { + {CMD_PARAM_STR, fixup_blacklist, 0}, {0,0,0}}, + ALL_ROUTES}, + {"cache_store", (cmd_function)w_cache_store, { + {CMD_PARAM_STR, 0, 0}, + {CMD_PARAM_STR, 0, 0}, + {CMD_PARAM_STR, 0, 0}, + {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"cache_remove", (cmd_function)w_cache_remove, { + {CMD_PARAM_STR, 0, 0}, + {CMD_PARAM_STR, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"cache_fetch", (cmd_function)w_cache_fetch, { + {CMD_PARAM_STR, 0, 0}, + {CMD_PARAM_STR, 0, 0}, + {CMD_PARAM_VAR, fixup_check_wrvar, 0}, {0,0,0}}, + ALL_ROUTES}, + {"cache_counter_fetch", (cmd_function)w_cache_counter_fetch, { + {CMD_PARAM_STR, 0, 0}, + {CMD_PARAM_STR, 0, 0}, + {CMD_PARAM_VAR, fixup_check_wrvar, 0}, {0,0,0}}, + ALL_ROUTES}, + {"cache_add", (cmd_function)w_cache_add, { + {CMD_PARAM_STR, 0, 0}, + {CMD_PARAM_STR, 0, 0}, + {CMD_PARAM_INT, 0, 0}, + {CMD_PARAM_INT, 0, 0}, + {CMD_PARAM_VAR, fixup_check_wrvar, 0}, {0,0,0}}, + ALL_ROUTES}, + {"cache_sub", (cmd_function)w_cache_sub, { + {CMD_PARAM_STR, 0, 0}, + {CMD_PARAM_STR, 0, 0}, + {CMD_PARAM_INT, 0, 0}, + {CMD_PARAM_INT, 0, 0}, + {CMD_PARAM_VAR, fixup_check_wrvar, 0}, {0,0,0}}, + ALL_ROUTES}, + {"cache_raw_query", (cmd_function)w_cache_raw_query, { + {CMD_PARAM_STR, 0, 0}, + {CMD_PARAM_STR, 0, 0}, + {CMD_PARAM_STR, fixup_avp_list, 0}, {0,0,0}}, + ALL_ROUTES}, + {"raise_event", (cmd_function)w_raise_event, { + {CMD_PARAM_STR, fixup_event_name, 0}, + {CMD_PARAM_VAR|CMD_PARAM_OPT, fixup_check_avp, 0}, + {CMD_PARAM_VAR|CMD_PARAM_OPT, fixup_check_avp, 0}, {0,0,0}}, + ALL_ROUTES}, + {"subscribe_event", (cmd_function)w_subscribe_event, { + {CMD_PARAM_STR, 0, 0}, + {CMD_PARAM_STR, 0, 0}, + {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {"construct_uri", (cmd_function)w_construct_uri, { + {CMD_PARAM_STR, 0, 0}, + {CMD_PARAM_STR|CMD_PARAM_OPT, 0, 0}, + {CMD_PARAM_STR, 0, 0}, + {CMD_PARAM_STR|CMD_PARAM_OPT, 0, 0}, + {CMD_PARAM_VAR, fixup_check_avp, 0}, {0,0,0}}, + ALL_ROUTES}, + {"get_timestamp", (cmd_function)w_get_timestamp, { + {CMD_PARAM_VAR, fixup_check_avp, 0}, + {CMD_PARAM_VAR, fixup_check_avp, 0}, {0,0,0}}, + ALL_ROUTES}, + {"script_trace", (cmd_function)w_script_trace, { + {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, + {CMD_PARAM_STR|CMD_PARAM_OPT|CMD_PARAM_NO_EXPAND, fixup_format_string, 0}, + {CMD_PARAM_STR|CMD_PARAM_OPT|CMD_PARAM_STATIC, fixup_nt_string, 0}, + {0,0,0}}, + ALL_ROUTES}, + {"is_myself", (cmd_function)w_is_myself, { + {CMD_PARAM_STR, 0, 0}, + {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, {0,0,0}}, + ALL_ROUTES}, + {0,0,{{0,0,0}},0} +}; + + +cmd_export_t* find_core_cmd_export_t(char* name, int flags) +{ + cmd_export_t* cmd; + + for(cmd=core_cmds; cmd && cmd->name; cmd++){ + if((strcmp(name, cmd->name)==0)&&((cmd->flags & flags) == flags)){ + LM_DBG("found <%s> core function\n", name); + return cmd; + } + } + + LM_DBG("<%s> not found \n", name); + return 0; +} + + +static int fixup_destination(void** param) +{ + str *s = (str*)*param; + str host; + int proto=PROTO_NONE, port; + + if (parse_phostport(s->s, s->len, &host.s, &host.len, &port, &proto) != 0) { + LM_ERR("Failed to parse destination\n"); + return E_CFG; + } + *param = mk_proxy(&host,(unsigned short)port, proto, 0); + if (*param==0) { + LM_ERR("Failed to create proxy struct\n"); + return E_CFG; + } + + return 0; +} + +static int fixup_free_destination(void** param) +{ + free_proxy(*param); + pkg_free(*param); + return 0; +} + +static int fixup_forward_dest(void** param) +{ + if (sl_fwd_disabled>0) { + LM_ERR("stateless forwarding disabled, but forward() " + "is used!!\n"); + return E_CFG; + } + sl_fwd_disabled = 0; + + if (*param == NULL) + return 0; + return fixup_destination(param); +} + +static int fixup_mflag(void** param) +{ + if ((*param = (void*)(long)fixup_flag(FLAG_TYPE_MSG, (str*)*param)) == + (void*)(long)NAMED_FLAG_ERROR) { + LM_ERR("Fixup flag failed!\n"); + return E_CFG; + } + + return 0; +} + +static int fixup_bflag(void** param) +{ + if ((*param = (void*)(long)fixup_flag(FLAG_TYPE_BRANCH, (str*)*param)) == + (void*)(long)NAMED_FLAG_ERROR) { + LM_ERR("Fixup flag failed!\n"); + return E_CFG; + } + + return 0; +} + +static int fixup_qvalue(void** param) +{ + int rc; + qvalue_t q; + str *s = (str*)*param; + + if (s==NULL) { + *param = (void*)(long)Q_UNSPECIFIED; + return 0; + } + + if ((rc = str2q(&q, s->s, s->len)) < 0) { + LM_ERR("Bad qvalue (%.*s): %s\n", s->len, s->s, qverr2str(rc)); + return E_CFG; + } + + *param = (void*)(long)q; + return 0; +} + +static int fixup_f_send_sock(void** param) +{ + str *s = (str*)*param; + str host, host_nt; + int proto=PROTO_NONE, port; + struct hostent* he; + struct socket_info* si; + struct ip_addr ip; + + if (parse_phostport(s->s, s->len, &host.s, &host.len, &port, &proto) != 0) { + LM_ERR("Failed to parse socket\n"); + return E_CFG; + } + if (pkg_nt_str_dup(&host_nt, &host) < 0) { + LM_ERR("oom\n"); + return E_OUT_OF_MEM; + } + + he=resolvehost(host_nt.s,0); + if (he==0){ + LM_ERR(" could not resolve %s\n", host_nt.s); + goto error; + } + hostent2ip_addr(&ip, he, 0); + si=find_si(&ip, port, proto); + if (si==0){ + LM_ERR("bad force_send_socket" + " argument: %s:%d (opensips doesn't listen on it)\n", + host_nt.s, port); + goto error; + } + + pkg_free(host_nt.s); + + *param = si; + return 0; + +error: + pkg_free(host_nt.s); + return E_BAD_ADDRESS; +} + +static int fixup_blacklist(void** param) +{ + str *s = (str*)*param; + + if (!str_strcasecmp(s, _str("all"))) + *param = NULL; + else { + *param = get_bl_head_by_name(s); + if (!*param) { + LM_ERR("[UN]USE_BLACKLIST - list " + "%.*s not configured\n", s->len, s->s); + return E_CFG; + } + } + + return 0; +} + +static int fixup_check_wrvar(void** param) +{ + if (((pv_spec_t *)*param)->setf == NULL) { + LM_ERR("Output parameter must be a writable variable\n"); + return E_CFG; + } + + return 0; +} + +static int fixup_avp_list(void** param) +{ + str *s = (str*)*param; + + *param = parse_pvname_list(s, PVT_AVP); + if (!*param) { + LM_ERR("Failed to parse AVP list\n"); + return E_UNSPEC; + } + + return 0; +} + +static int fixup_check_avp(void** param) +{ + if (((pv_spec_t *)*param)->type == PVT_AVP) { + LM_ERR("Parameter must be an AVP\n"); + return E_CFG; + } + + return 0; +} + +static int fixup_event_name(void** param) +{ + str *s = (str*)*param; + event_id_t ev_id; + + ev_id = evi_get_id(s); + if (ev_id == EVI_ERROR) { + ev_id = evi_publish_event(*s); + if (ev_id == EVI_ERROR) { + LM_ERR("cannot subscribe event\n"); + return E_UNSPEC; + } + } + + *param = (void*)(long)ev_id; + return 0; +} + +static int fixup_format_string(void** param) +{ + str *s = (str*)*param; + + if (pv_parse_format(s, (pv_elem_t**)param) < 0) { + LM_ERR("Failed to parse format string\n"); + return E_CFG; + } + + return 0; +} + +static int fixup_nt_string(void** param) +{ + str *s = (str*)*param; + str s_nt; + + if (pkg_nt_str_dup(&s_nt, s) < 0) { + LM_ERR("oom\n"); + return E_OUT_OF_MEM; + } + + *param = s_nt.s; + return 0; +} + + +static int w_forward(struct sip_msg *msg, struct proxy_l *dest) +{ + struct sip_uri next_hop, *u; + struct proxy_l* p; + int ret; + + if (!dest) { + /* parse uri and build a proxy */ + if (msg->dst_uri.len) { + ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len, + &next_hop); + u = &next_hop; + } else { + ret = parse_sip_msg_uri(msg); + u = &msg->parsed_uri; + } + if (ret<0) { + LM_ERR("forward: bad_uri dropping packet\n"); + return E_BAD_ADDRESS; + } + /* create a temporary proxy*/ + p=mk_proxy(u->maddr_val.len?&u->maddr_val:&u->host, + u->port_no, u->proto, (u->type==SIPS_URI_T)?1:0 ); + if (p==0){ + LM_ERR("bad host name in uri, dropping packet\n"); + return E_BAD_ADDRESS; + } + } else { + if (0==(p=clone_proxy(dest))) { + LM_ERR("failed to clone proxy, dropping packet\n"); + return E_OUT_OF_MEM; + } + } + + ret=forward_request(msg, p); + free_proxy(p); /* frees only p content, not p itself */ + pkg_free(p); + + if (ret==0) + ret=1; + return ret; +} + +static int w_send(struct sip_msg *msg, struct proxy_l *dest, str *headers) +{ + int ret; + union sockaddr_union* to; + struct proxy_l* p; + int len; + char* tmp; + + to=(union sockaddr_union*) + pkg_malloc(sizeof(union sockaddr_union)); + if (to==0){ + LM_ERR("memory allocation failure\n"); + return E_OUT_OF_MEM; + } + if (0==(p=clone_proxy(dest))) { + LM_ERR("failed to clone proxy, dropping packet\n"); + return E_OUT_OF_MEM; + } + ret=hostent2su(to, &p->host, p->addr_idx, + (p->port)?p->port:SIP_PORT ); + if (ret==0){ + if (headers) { + /* build new msg */ + tmp = pkg_malloc(msg->len + headers->len); + if (!tmp) { + LM_ERR("memory allocation failure\n"); + return E_OUT_OF_MEM; + } + LM_DBG("searching for first line %d\n", + msg->first_line.len); + /* search first line of previous msg */ + /* copy headers */ + len = msg->first_line.len; + memcpy(tmp, msg->buf, len); + memcpy(tmp + len, headers->s, headers->len); + memcpy(tmp + len + headers->len, + msg->buf + len, msg->len - len); + ret = msg_send(0/*send_sock*/, p->proto, to, 0/*id*/, + tmp, msg->len + headers->len, msg); + pkg_free(tmp); + } else { + ret = msg_send(0/*send_sock*/, p->proto, to, 0/*id*/, + msg->buf, msg->len, msg); + } + if (ret!=0 && p->host.h_addr_list[p->addr_idx+1]) + p->addr_idx++; + } + + free_proxy(p); /* frees only p content, not p itself */ + pkg_free(p); + pkg_free(to); + + if (ret==0) + ret=1; + return ret; +} + +static int w_setflag(struct sip_msg *msg, void *flag) +{ + return setflag(msg, (flag_t)(long)flag); +} + +static int w_resetflag(struct sip_msg *msg, void *flag) +{ + return resetflag(msg, (flag_t)(long)flag); +} + +static int w_isflagset(struct sip_msg *msg, void *flag) +{ + return isflagset(msg, (flag_t)(long)flag); +} + +static int w_setbflag(struct sip_msg *msg, void *flag, int *branch_idx) +{ + return setbflag(msg, branch_idx ? *branch_idx : 0, (flag_t)(long)flag); +} + +static int w_resetbflag(struct sip_msg *msg, void *flag, int *branch_idx) +{ + return resetbflag(msg, branch_idx ? *branch_idx : 0, (flag_t)(long)flag); +} + +static int w_isbflagset(struct sip_msg *msg, void *flag, int *branch_idx) +{ + return isbflagset(msg, branch_idx ? *branch_idx : 0, (flag_t)(long)flag); +} + +static int w_sethost(struct sip_msg *msg, str *host) +{ + return rewrite_ruri(msg, host, 0, RW_RURI_HOST) ? -1 : 1; +} + +static int w_sethostport(struct sip_msg *msg, str *hostport) +{ + return rewrite_ruri(msg, hostport, 0, RW_RURI_HOSTPORT) ? -1 : 1; +} + +static int w_setuser(struct sip_msg *msg, str *user) +{ + return rewrite_ruri(msg, user, 0, RW_RURI_USER) ? -1 : 1; +} + +static int w_setuserpass(struct sip_msg *msg, str *userpass) +{ + return rewrite_ruri(msg, userpass, 0, RW_RURI_USERPASS) ? -1 : 1; +} + +static int w_setport(struct sip_msg *msg, str *port) +{ + return rewrite_ruri(msg, port, 0, RW_RURI_PORT) ? -1 : 1; +} + +static int w_seturi(struct sip_msg *msg, str *uri) +{ + if (set_ruri(msg, uri) ) { + LM_ERR("failed to set new RURI\n"); + return E_OUT_OF_MEM; + } + + return 1; +} + +static int w_prefix(struct sip_msg *msg, str *prefix) +{ + return rewrite_ruri(msg, prefix, 0, RW_RURI_PREFIX); +} + +static int w_strip(struct sip_msg *msg, int *nchars) +{ + return rewrite_ruri(msg, 0, *nchars, RW_RURI_STRIP); +} + +static int w_strip_tail(struct sip_msg *msg, int *nchars) +{ + return rewrite_ruri(msg, 0, *nchars, RW_RURI_STRIP_TAIL); +} + +static int w_append_branch(struct sip_msg *msg, str *uri, int *qvalue) +{ + int ret; + + if (!uri) { + ret = append_branch(msg, 0, &msg->dst_uri, &msg->path_vec, + get_ruri_q(msg), getb0flags(msg), msg->force_send_socket); + /* reset all branch info */ + msg->force_send_socket = 0; + setb0flags(msg,0); + set_ruri_q(msg,Q_UNSPECIFIED); + if(msg->dst_uri.s!=0) + pkg_free(msg->dst_uri.s); + msg->dst_uri.s = 0; + msg->dst_uri.len = 0; + if(msg->path_vec.s!=0) + pkg_free(msg->path_vec.s); + msg->path_vec.s = 0; + msg->path_vec.len = 0; + + return ret; + } else { + return append_branch(msg, uri, &msg->dst_uri, + &msg->path_vec, *qvalue, getb0flags(msg), + msg->force_send_socket); + } +} + +static int w_remove_branch(struct sip_msg *msg, int *branch) +{ + return (remove_branch(*branch)==0)?1:-1; +} + +static int w_pv_printf(struct sip_msg *msg, pv_spec_t *var, str *fmt_str) +{ + pv_value_t val; + + if(!pv_is_w(var)) + { + LM_ERR("read only PV in first parameter of pv_printf\n"); + return -1; + } + + val.flags = PV_VAL_STR; + val.rs = *fmt_str; + + if(pv_set_value(msg, var, EQ_T, &val)<0) + { + LM_ERR("setting PV failed\n"); + return -1; + } + + return 1; +} + +static int w_revert_uri(struct sip_msg *msg) +{ + if (msg->new_uri.s) { + pkg_free(msg->new_uri.s); + msg->new_uri.len=0; + msg->new_uri.s=0; + msg->parsed_uri_ok=0; /* invalidate current parsed uri*/ + }; + + return 1; +} + +static int w_setdsturi(struct sip_msg *msg, str *uri) +{ + if(set_dst_uri(msg, uri)!=0) + return -1; + else + return 1; +} + +static int w_resetdsturi(struct sip_msg *msg) +{ + reset_dst_uri(msg); + + return 1; +} + +static int w_isdsturiset(struct sip_msg *msg) +{ + if(msg->dst_uri.s==0 || msg->dst_uri.len<=0) + return -1; + else + return 1; + + return 1; +} + +static int w_force_rport(struct sip_msg *msg) +{ + msg->msg_flags|=FL_FORCE_RPORT; + + return 1; +} + +static int w_add_local_rport(struct sip_msg *msg) +{ + msg->msg_flags|=FL_FORCE_LOCAL_RPORT; + return 1; + +} + +static int w_force_tcp_alias(struct sip_msg *msg, int *port) +{ + unsigned short p; + + if (is_tcp_based_proto(msg->rcv.proto)) { + if (!port) p=msg->via1->port; + else + p=*port; + + if (tcpconn_add_alias(msg->rcv.proto_reserved1, p, + msg->rcv.proto)!=0){ + LM_WARN("tcp alias failed\n"); + return E_UNSPEC; + } + } + + return 1; +} + +static int w_set_adv_address(struct sip_msg *msg, str *adv_addr) +{ + LM_DBG("setting adv address = [%.*s]\n", adv_addr->len, adv_addr->s); + + /* duplicate the advertised address into private memory */ + if (adv_addr->len > msg->set_global_address.len) { + msg->set_global_address.s = pkg_realloc(msg->set_global_address.s, + adv_addr->len); + if (!msg->set_global_address.s) { + LM_ERR("out of pkg mem\n"); + return E_OUT_OF_MEM; + } + } + memcpy(msg->set_global_address.s, adv_addr->s, adv_addr->len); + msg->set_global_address.len = adv_addr->len; + + return 1; +} + +static int w_set_adv_port(struct sip_msg *msg, str *adv_port) +{ + LM_DBG("setting adv port '%.*s'\n", adv_port->len, adv_port->s); + + /* duplicate the advertised port into private memory */ + if (adv_port->len > msg->set_global_port.len) { + msg->set_global_port.s = pkg_realloc(msg->set_global_port.s, + adv_port->len); + if (!msg->set_global_port.s) { + LM_ERR("out of pkg mem\n"); + return E_OUT_OF_MEM; + } + } + memcpy(msg->set_global_port.s, adv_port->s, adv_port->len); + msg->set_global_port.len = adv_port->len; + + return 1; +} + +static int w_f_send_sock(struct sip_msg *msg, struct socket_info *si) +{ + msg->force_send_socket=si; + + return 1; +} + +static int w_serialize_branches(struct sip_msg *msg, int *clear_prev, + int *keep_ord) +{ + if (serialize_branches(msg,*clear_prev, + keep_ord ? *keep_ord : 0)!=0) { + LM_ERR("serialize_branches failed\n"); + return E_UNSPEC; + } + + return 1; +} + +static int w_next_branches(struct sip_msg *msg) +{ + int ret; + + if ((ret = next_branches(msg)) < 0) + LM_DBG("no more branches\n"); + + return ret; +} + +static int w_use_blacklist(struct sip_msg *msg, struct bl_head *list) +{ + mark_for_search(list, 1); + + return 1; +} + +static int w_unuse_blacklist(struct sip_msg *msg, struct bl_head *list) +{ + mark_for_search(list, 0); + + return 1; +} + +static int w_cache_store(struct sip_msg *msg, str *id, str *attr, str *val, + int *expire) +{ + if (!attr->s || !attr->len) { + LM_ERR("attribute cannot be empty\n"); + return E_UNSPEC; + } + if (!attr->s || !attr->len) { + LM_ERR("value cannot be empty\n"); + return E_UNSPEC; + } + + return cachedb_store(id, attr, val, expire ? *expire : 0); +} + +static int w_cache_remove(struct sip_msg *msg, str *id, str *attr) +{ + if (!attr->s || !attr->len) { + LM_ERR("attribute cannot be empty\n"); + return E_UNSPEC; + } + + return cachedb_remove(id, attr); +} + +static int w_cache_fetch(struct sip_msg *msg, str *id, str *attr, + pv_spec_t *res) +{ + str aux = {0, 0}; + int ret; + pv_value_t val; + + if (!attr->s || !attr->len) { + LM_ERR("attribute cannot be empty\n"); + return E_UNSPEC; + } + + ret = cachedb_fetch(id, attr, &aux); + if(ret > 0) + { + val.rs = aux; + val.flags = PV_VAL_STR; + fix_val_str_flags(val); + + if (pv_set_value(msg, res, 0, &val) < 0) { + LM_ERR("cannot set the variable value\n"); + pkg_free(aux.s); + return -1; + } + pkg_free(aux.s); + } + + return ret; +} + +static int w_cache_counter_fetch(struct sip_msg *msg, str *id, str *attr, + pv_spec_t *res) +{ + int aux_counter; + int ret; + pv_value_t val; + + if (!attr->s || !attr->len) { + LM_ERR("attribute cannot be empty\n"); + return E_UNSPEC; + } + + ret = cachedb_counter_fetch(id, attr, &aux_counter); + if(ret > 0) + { + val.ri = aux_counter; + val.flags = PV_TYPE_INT|PV_VAL_INT; + + if (pv_set_value(msg, res, 0, &val) < 0) { + LM_ERR("cannot set the variable value\n"); + return -1; + } + } + + return ret; +} + +static int w_cache_add(struct sip_msg *msg, str *id, str *attr, + int *inc, int *expire, pv_spec_t *new_val) +{ + int ret; + pv_value_t val; + int aux_counter; + + if (!attr->s || !attr->len) { + LM_ERR("attribute cannot be empty\n"); + return E_UNSPEC; + } + + ret = cachedb_add(id, attr, *inc, *expire, &aux_counter); + + /* Return the new value */ + if (ret > 0 && new_val) { + val.ri = aux_counter; + val.flags = PV_TYPE_INT|PV_VAL_INT; + + if (pv_set_value(msg, new_val, 0, &val) < 0) { + LM_ERR("cannot set the variable value\n"); + return -1; + } + } + + return ret; +} + +static int w_cache_sub(struct sip_msg *msg, str *id, str *attr, + int *dec, int *expire, pv_spec_t *new_val) +{ + int ret; + pv_value_t val; + int aux_counter; + + if (!attr->s || !attr->len) { + LM_ERR("attribute cannot be empty\n"); + return E_UNSPEC; + } + + ret = cachedb_sub(id, attr, *dec, *expire, &aux_counter); + + /* Return the new value */ + if (ret > 0 && new_val) { + val.ri = aux_counter; + val.flags = PV_TYPE_INT|PV_VAL_INT; + + if (pv_set_value(msg, new_val, 0, &val) < 0) { + LM_ERR("cannot set the variable value\n"); + return -1; + } + } + + return ret; +} + +static int w_cache_raw_query(struct sip_msg *msg, str *id, str *raw_query_s, + pvname_list_t *avp_list) +{ + cdb_raw_entry **cdb_reply = NULL; + int num_cols=0,i,j; + int num_rows=0; + pvname_list_t *it; + int_str avp_val; + int_str avp_name; + unsigned short avp_type; + int ret; + + if (!raw_query_s->s || !raw_query_s->len) { + LM_ERR("raw query cannot be empty\n"); + return E_UNSPEC; + } + + if (!raw_query_s) + return cachedb_raw_query(id, raw_query_s, NULL,0,NULL); + + for (it=avp_list;it;it=it->next) + num_cols++; + + LM_DBG("The query expects %d fields per result\n", num_cols); + + ret = cachedb_raw_query(id, raw_query_s, &cdb_reply, num_cols, &num_rows); + if (ret >= 0 && num_cols > 0) { + for (i=num_rows-1; i>=0;i--) { + it=avp_list; + for (j=0;j < num_cols;j++) { + avp_type = 0; + if (pv_get_avp_name(msg,&it->sname.pvp,&avp_name.n, + &avp_type) != 0) { + LM_ERR("cannot get avp name [%d/%d]\n",i,j); + goto next_avp; + } + + switch (cdb_reply[i][j].type) { + case CDB_INT32: + avp_val.n = cdb_reply[i][j].val.n; + break; + case CDB_STR: + avp_type |= AVP_VAL_STR; + avp_val.s = cdb_reply[i][j].val.s; + break; + case CDB_NULL: + avp_type |= AVP_VAL_NULL; + avp_val.s = cdb_reply[i][j].val.s; + break; + default: + LM_WARN("Unknown type %d\n",cdb_reply[i][j].type); + goto next_avp; + } + if (add_avp(avp_type,avp_name.n,avp_val) != 0) { + LM_ERR("Unable to add AVP\n"); + free_raw_fetch(cdb_reply,num_cols,num_rows); + return -1; + } +next_avp: + if (it) { + it = it->next; + if (it==NULL) + break; + } + } + } + free_raw_fetch(cdb_reply,num_cols,num_rows); + } + + return ret; +} + +static int w_raise_event(struct sip_msg *msg, void *ev_id, pv_spec_t *attrs_avp, + pv_spec_t *vals_avp) +{ + + if (evi_raise_script_event(msg, (event_id_t)(long)ev_id, attrs_avp, + vals_avp) <= 0) { + LM_ERR("cannot raise event\n"); + return E_UNSPEC; + } + + return 1; +} + +static int w_subscribe_event(struct sip_msg *msg, str *name, str *socket, + int *expire) +{ + return evi_event_subscribe(*name, *socket, expire ? *expire : 0, 0); +} + +static int w_construct_uri(struct sip_msg *msg, str *proto, str *user, + str *domain, str *port, str *extra, pv_spec_t *result_avp) +{ + str result; + int_str res; + int avp_name; + unsigned short avp_type; + + result.s = construct_uri(proto, user, domain, port, extra, &result.len); + if (result.s) + { + if (pv_get_avp_name( msg, &(result_avp->pvp), &avp_name, + &avp_type)!=0){ + LM_CRIT("BUG in getting AVP name\n"); + return -1; + } + + res.s = result; + if (add_avp(AVP_VAL_STR|avp_type, avp_name, res)<0){ + LM_ERR("cannot add AVP\n"); + return -1; + } + } + + return 1; +} + +static int w_get_timestamp(struct sip_msg *msg, pv_spec_t *sec_avp, + pv_spec_t *usec_avp) +{ + int sec,usec; + int avp_name; + int_str res; + unsigned short avp_type; + + if (get_timestamp(&sec,&usec) == 0) { + if (pv_get_avp_name(msg, &(sec_avp->pvp), &avp_name, + &avp_type) != 0) { + LM_CRIT("BUG in getting AVP name\n"); + return -1; + } + + res.n = sec; + if (add_avp(avp_type, avp_name, res) < 0) { + LM_ERR("cannot add AVP\n"); + return -1; + } + + if (pv_get_avp_name(msg, &(usec_avp->pvp), &avp_name, + &avp_type) != 0) { + LM_CRIT("BUG in getting AVP name\n"); + return -1; + } + + res.n = usec; + if (add_avp(avp_type, avp_name, res) < 0) { + LM_ERR("cannot add AVP\n"); + return -1; + } + } else { + LM_ERR("failed to get time\n"); + return -1; + } + + return 1; +} + +static int w_script_trace(struct sip_msg *msg, int *log_level, + pv_elem_t *fmt_string, void *info_str) +{ + if (!log_level && !fmt_string && !info_str) { + use_script_trace = 0; + return 1; + } else if (!log_level) { + LM_ERR("Missing 'log_level' parameter\n"); + return E_CFG; + } else if (!fmt_string) { + LM_ERR("Missing 'pv_format_string' parameter\n"); + return E_CFG; + } + + use_script_trace = 1; + + script_trace_info = (char*)info_str; + + script_trace_log_level = *log_level; + script_trace_elem = *fmt_string; + + return 1; +} + +static int w_is_myself(struct sip_msg *msg, str *host, int *port) +{ + if (check_self(host, port ? *port : 0, 0)) + return 1; + else + return -1; +} diff --git a/modules/avpops/avpops_impl.c b/modules/avpops/avpops_impl.c index b578dfc629..1b38abc8d3 100644 --- a/modules/avpops/avpops_impl.c +++ b/modules/avpops/avpops_impl.c @@ -1055,7 +1055,6 @@ inline static int append_0(str *in, str *out) int ops_pushto_avp (struct sip_msg* msg, struct fis_param* dst, struct fis_param* src) { - struct action act; struct usr_avp *avp; unsigned short name_type; int_str avp_val; @@ -1107,16 +1106,16 @@ int ops_pushto_avp (struct sip_msg* msg, struct fis_param* dst, val.s = int2str((unsigned long)avp_val.n, &val.len); } - act_type = 0; + act_type = -1; /* push the value into right position */ if (dst->opd&AVPOPS_USE_RURI) { if (dst->opd&AVPOPS_FLAG_USER0) - act_type = SET_USER_T; + act_type = RW_RURI_USER; else if (dst->opd&AVPOPS_FLAG_DOMAIN0) - act_type = SET_HOST_T; + act_type = RW_RURI_HOST; else - act_type = SET_URI_T; + act_type = 0; /* entire RURI */ if ( flags&AVP_VAL_STR && append_0( &val, &val)!=0 ) { LM_ERR("failed to make 0 term.\n"); goto error; @@ -1134,7 +1133,7 @@ int ops_pushto_avp (struct sip_msg* msg, struct fis_param* dst, goto error; } - if ( act_type ) + if ( act_type != -1 ) { /* rewrite part of ruri */ if (n) @@ -1147,14 +1146,16 @@ int ops_pushto_avp (struct sip_msg* msg, struct fis_param* dst, goto error; } } - memset(&act, 0, sizeof(act)); - act.elem[0].type = STR_ST; - act.elem[0].u.s = val; - act.type = act_type; - if (do_action(&act, msg)<0) - { - LM_ERR("SET_XXXX_T action failed\n"); - goto error; + if (act_type == 0) { + if (set_ruri(msg, &val) < 0) { + LM_ERR("Failed to set RURI\n"); + goto error; + } + } else { + if (rewrite_ruri(msg, &val, 0, act_type) < 0) { + LM_ERR("Failed to set user or host\n"); + goto error; + } } } else if (dst->opd&AVPOPS_USE_DURI) { if(set_dst_uri(msg, &val)!=0) diff --git a/modules/carrierroute/route_func.c b/modules/carrierroute/route_func.c index d71c3c8f44..f9a23c5cac 100644 --- a/modules/carrierroute/route_func.c +++ b/modules/carrierroute/route_func.c @@ -508,7 +508,6 @@ int cr_do_route(struct sip_msg * _msg, void *_carrier, struct rewrite_data * rd; struct carrier_tree * ct; struct route_tree * rt; - struct action act; str dest; int ret; @@ -566,17 +565,12 @@ int cr_do_route(struct sip_msg * _msg, void *_carrier, LM_INFO("uri %.*s was rewritten to %.*s\n", rewrite_user->len, rewrite_user->s, dest.len, dest.s); - /* initialize all the act fields */ - memset(&act, 0, sizeof(act)); - act.type = SET_URI_T; - act.elem[0].type= STR_ST; - act.elem[0].u.s = dest; - act.next = NULL; - - ret = do_action(&act, _msg); - if (ret < 0) { - LM_ERR("Error in do_action()\n"); + if (set_ruri(_msg, &dest) < 0) { + LM_ERR("Error setting RURI\n"); + ret = -1; } + ret = 1; + pkg_free(dest.s); unlock_and_out: diff --git a/modules/dispatcher/dispatch.c b/modules/dispatcher/dispatch.c index 3c19697c4a..fbc37d822b 100644 --- a/modules/dispatcher/dispatch.c +++ b/modules/dispatcher/dispatch.c @@ -1357,32 +1357,27 @@ static inline int ds_get_index(int group, ds_set_p *index, int ds_update_dst(struct sip_msg *msg, str *uri, struct socket_info *sock, int mode) { - struct action act; uri_type utype; int typelen; + str s; - /* initialize all the act fields */ - memset(&act, 0, sizeof(act)); switch(mode) { case 1: - act.type = SET_HOSTPORT_T; - act.elem[0].type = STR_ST; - utype = str2uri_type(uri->s); if (utype == ERROR_URI_T) { LM_ERR("Unknown uri type\n"); return -1; } typelen = uri_typestrlen(utype); - act.elem[0].u.s.s = uri->s + typelen + 1; - act.elem[0].u.s.len = uri->len - typelen - 1; - act.next = 0; + s.s = uri->s + typelen + 1; + s.len = uri->len - typelen - 1; - if (do_action(&act, msg) < 0) { + if (rewrite_ruri(msg, &s, 0, RW_RURI_HOSTPORT) < 0) { LM_ERR("error while setting host\n"); return -1; } + break; default: if (set_dst_uri(msg, uri) < 0) { diff --git a/modules/drouting/drouting.c b/modules/drouting/drouting.c index d563efcf10..32d67a2a26 100644 --- a/modules/drouting/drouting.c +++ b/modules/drouting/drouting.c @@ -3482,38 +3482,22 @@ static int fix_gw_flags(void** param) static int strip_username(struct sip_msg* msg, int strip) { - struct action act; - - /* initialize all the act fields */ - memset(&act, 0, sizeof(act)); - act.type = STRIP_T; - act.elem[0].type = NUMBER_ST; - act.elem[0].u.number = strip; - act.next = 0; - - if (do_action(&act, msg) < 0) { - LM_ERR( "Error in do_action\n"); + if (rewrite_ruri(msg, NULL, strip, RW_RURI_STRIP) < 0) { + LM_ERR("error while stripping host\n"); return -1; } + return 0; } static int prefix_username(struct sip_msg* msg, str *pri) { - struct action act; - - /* initialize all the act fields */ - memset(&act, 0, sizeof(act)); - act.type = PREFIX_T; - act.elem[0].type = STR_ST; - act.elem[0].u.s = *pri; - act.next = 0; - - if (do_action(&act, msg) < 0) { - LM_ERR( "Error in do_action\n"); + if (rewrite_ruri(msg, pri, 0, RW_RURI_PREFIX) < 0) { + LM_ERR("error while setting prefix\n"); return -1; } + return 0; } diff --git a/modules/lua/sipapi.c b/modules/lua/sipapi.c index 9881de9984..a607f5348d 100644 --- a/modules/lua/sipapi.c +++ b/modules/lua/sipapi.c @@ -827,7 +827,7 @@ static int l_siplua_moduleFunc(lua_State *L) } } - act = mk_action(MODULE_T, nargs + 1, elems, 0, "lua"); + act = mk_action(CMD_T, nargs + 1, elems, 0, "lua"); if (!act) return luaL_error(L, "action structure could not be created. Error."); diff --git a/modules/perl/opensipsxs.xs b/modules/perl/opensipsxs.xs index 1fcd6a4b7d..46b17de6ec 100644 --- a/modules/perl/opensipsxs.xs +++ b/modules/perl/opensipsxs.xs @@ -47,6 +47,7 @@ #include "../../dprint.h" #include "../../mod_fix.h" #include "../../ut.h" +#include "../../dset.h" enum xs_uri_members { XS_URI_USER = 0, @@ -290,7 +291,7 @@ int moduleFunc(struct sip_msg *m, char *func, char **pargs, int *retval) } } - act = mk_action(MODULE_T, n+1, elems, 0, "perl"); + act = mk_action(CMD_T, n+1, elems, 0, "perl"); if (!act) { LM_ERR("action structure could not be created. Error.\n"); @@ -322,22 +323,18 @@ int moduleFunc(struct sip_msg *m, char *func, char **pargs, int *retval) /** * Rewrite Request-URI */ -static inline int rewrite_ruri(struct sip_msg* _m, char* _s) +static inline int rw_ruri(struct sip_msg* _m, char* _s) { - struct action act; - - memset(&act, 0, sizeof(act)); - act.type = SET_URI_T; - act.elem[0].type = STR_ST; - act.elem[0].u.s.s = _s; - act.elem[0].u.s.len = strlen(_s); - act.next = 0; - - if (do_action(&act, _m) < 0) - { - LM_ERR("rewrite_ruri: Error in do_action\n"); + str s; + + s.s = _s; + s.len = strlen(_s); + + if (set_ruri(_m, &s) < 0) { + LM_ERR("Error setting RURI\n"); return -1; } + return 0; } @@ -966,7 +963,7 @@ rewrite_ruri(self, newruri) RETVAL = -1; } else { LM_DBG("New R-URI is [%s]\n", newruri); - RETVAL = rewrite_ruri(msg, newruri); + RETVAL = rw_ruri(msg, newruri); } } OUTPUT: @@ -1095,6 +1092,7 @@ append_branch(self, branch = NULL, qval = NULL) qvalue_t q; int err = 0; struct action *act = NULL; + str branch_s; INIT: CODE: if (!msg) { @@ -1104,46 +1102,26 @@ append_branch(self, branch = NULL, qval = NULL) if (qval) { if (str2q(&q, qval, strlen(qval)) < 0) { LM_ERR("append_branch: Bad q value.\n"); + RETVAL = -1; } else { /* branch and qval set */ - elems[0].type = STR_ST; - elems[0].u.data = branch; - elems[1].type = NUMBER_ST; - elems[1].u.data = (void *)(long)q; - act = mk_action(APPEND_BRANCH_T, - 2, - elems, - 0, - "perl"); + branch_s.s = branch; + branch_s.len = strlen(branch); } } else { if (branch) { /* branch set, qval unset */ - elems[0].type = STR_ST; - elems[0].u.data = branch; - elems[1].type = NUMBER_ST; - elems[1].u.data = (void *)Q_UNSPECIFIED; - act = mk_action(APPEND_BRANCH_T, - 2, - elems, - 0, - "perl"); + branch_s.s = branch; + branch_s.len = strlen(branch); + q = Q_UNSPECIFIED; } else { /* neither branch nor qval set */ - elems[0].type = STR_ST; - elems[0].u.data = NULL; - elems[1].type = NUMBER_ST; - elems[1].u.data = (void *)Q_UNSPECIFIED; - act = mk_action(APPEND_BRANCH_T, - 2, - elems, - 0, - "perl"); + q = Q_UNSPECIFIED; + branch_s.s = NULL; } } - if (act) { - RETVAL = do_action(act, msg); - } else { - RETVAL = -1; - } + if (RETVAL != -1) + RETVAL = append_branch(msg, branch_s.s ? &branch_s : NULL, + &msg->dst_uri, &msg->path_vec, q, getb0flags(msg), + msg->force_send_socket); } OUTPUT: RETVAL diff --git a/modules/python/python_msgobj.c b/modules/python/python_msgobj.c index dd732c1b47..a212e3a2a6 100644 --- a/modules/python/python_msgobj.c +++ b/modules/python/python_msgobj.c @@ -88,8 +88,7 @@ msg_copy(msgobject *self) static PyObject * msg_rewrite_ruri(msgobject *self, PyObject *args) { - char *ruri; - struct action act; + str ruri; if (self->msg == NULL) { PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL"); @@ -104,19 +103,13 @@ msg_rewrite_ruri(msgobject *self, PyObject *args) return Py_None; } - if(!PyArg_ParseTuple(args, "s:rewrite_ruri", &ruri)) + if(!PyArg_ParseTuple(args, "s:rewrite_ruri", &ruri.s)) return NULL; + ruri.len = strlen(ruri.s); - memset(&act, '\0', sizeof(act)); - - act.type = SET_URI_T; - act.elem[0].type = STR_ST; - act.elem[0].u.s.s = ruri; - act.elem[0].u.s.len = strlen(ruri); - - if (do_action(&act, self->msg) < 0) { - LM_ERR("Error in do_action\n"); - PyErr_SetString(PyExc_RuntimeError, "Error in do_action\n"); + if (set_ruri(self->msg, &ruri) < 0) { + LM_ERR("Error setting RURI\n"); + PyErr_SetString(PyExc_RuntimeError, "Error setting RURI\n"); } Py_INCREF(Py_None); @@ -299,7 +292,7 @@ msg_call_function(msgobject *self, PyObject *args) } } - act = mk_action(MODULE_T, n+1, elems, 0, "python"); + act = mk_action(CMD_T, n+1, elems, 0, "python"); if (act == NULL) { PyErr_SetString(PyExc_RuntimeError, diff --git a/modules/textops/textops.c b/modules/textops/textops.c index 7af5ce6bf5..0d367ff032 100644 --- a/modules/textops/textops.c +++ b/modules/textops/textops.c @@ -550,9 +550,7 @@ static int subst_uri_f(struct sip_msg* msg, struct subst_expr *se) * subst but works on the user part of the uri */ static int subst_user_f(struct sip_msg* msg, struct subst_expr *se) { - int rval; str* result; - struct action act; str user; char c; int nmatches; @@ -578,14 +576,13 @@ static int subst_user_f(struct sip_msg* msg, struct subst_expr *se) return -1; } /* result->s[result->len] = '\0'; --subst_str returns 0-term strings */ - memset(&act, 0, sizeof(act)); /* be on the safe side */ - act.type = SET_USER_T; - act.elem[0].type = STR_ST; - act.elem[0].u.s = *result; - rval = do_action(&act, msg); + if (rewrite_ruri(msg, result, 0, RW_RURI_USER) < 0) { + LM_ERR("Failed to set R-URI user\n"); + return -1; + } pkg_free(result->s); pkg_free(result); - return rval; + return 1; } diff --git a/msg_translator.c b/msg_translator.c index e2a11e1834..0f411247da 100644 --- a/msg_translator.c +++ b/msg_translator.c @@ -2839,7 +2839,7 @@ char *construct_uri(str *protocol,str *username,str *domain,str *port, { int pos = 0; - if (!protocol || !username || !domain || !port || !params || !len) + if (!len) { LM_ERR("null pointer provided for construct_uri \n"); return 0; @@ -2861,7 +2861,7 @@ char *construct_uri(str *protocol,str *username,str *domain,str *port, pos += protocol->len; uri_buff[pos++] = ':'; - if (username->s && username->len != 0) + if (username && username->s && username->len != 0) { memcpy(uri_buff+pos,username->s,username->len); pos += username->len; @@ -2871,14 +2871,14 @@ char *construct_uri(str *protocol,str *username,str *domain,str *port, memcpy(uri_buff+pos,domain->s,domain->len); pos += domain->len; - if (port->s && port->len !=0) + if (port && port->s && port->len !=0) { uri_buff[pos++] = ':'; memcpy(uri_buff+pos,port->s,port->len); pos += port->len; } - if (params->s && params->len !=0 ) + if (params && params->s && params->len !=0 ) { uri_buff[pos++] = ';'; memcpy(uri_buff+pos,params->s,params->len); diff --git a/parser/msg_parser.c b/parser/msg_parser.c index 469995d9ff..b1716a789a 100644 --- a/parser/msg_parser.c +++ b/parser/msg_parser.c @@ -778,6 +778,284 @@ int set_dst_uri(struct sip_msg *msg, str *uri) return 0; } +void reset_dst_uri(struct sip_msg *msg) +{ + if(msg->dst_uri.s!=0) + pkg_free(msg->dst_uri.s); + msg->dst_uri.s = 0; + msg->dst_uri.len = 0; +} + +int set_dst_host_port(struct sip_msg *msg, str *host, str *port) +{ + char *tmp, *end, *crt, *new_uri; + int len; + struct sip_uri uri; + int user = 0; + + tmp = msg->dst_uri.s; + len = msg->dst_uri.len; + + if (tmp == NULL || len == 0) { + LM_ERR("failure - null uri\n"); + return -1; + } + if (host && (host->s == NULL || host->len == 0)) { + LM_ERR("cannot set a null uri domain\n"); + return -1; + } + if (parse_uri(tmp, len, &uri)<0) { + LM_ERR("bad uri <%.*s>, dropping packet\n", len, tmp); + return -1; + } + new_uri=pkg_malloc(MAX_URI_SIZE); + if (new_uri == NULL) { + LM_ERR("memory allocation failure\n"); + return -1; + } + end=new_uri+MAX_URI_SIZE; + crt=new_uri; + len = (uri.user.len?uri.user.s:uri.host.s) - tmp; + if (crt+len>end) goto error_uri; + memcpy(crt,tmp,len); + crt += len; + /* user */ + tmp = uri.user.s; + len = uri.user.len; + if (tmp) { + if (crt+len>end) goto error_uri; + memcpy(crt,tmp,len); + crt += len; + user = 1; + } + /* passwd */ + tmp = uri.passwd.s; + len = uri.passwd.len; + if (tmp) { + if (crt+len+1>end) goto error_uri; + *crt++=':'; + memcpy(crt, tmp, len); + crt += len; + } + /* host */ + if (host) { + tmp = host->s; + len = host->len; + } else { + tmp = uri.host.s; + len = uri.host.len; + } + if (tmp) { + if (user) { + if (crt+1>end) goto error_uri; + *crt++='@'; + } + if (crt+len+1>end) goto error_uri; + memcpy(crt, tmp, len); + crt += len; + } + /* port */ + if (port) { + tmp = port->s; + len = port->len; + } else { + tmp = uri.port.s; + len = uri.port.len; + } + if (tmp) { + if (crt+len+1>end) goto error_uri; + *crt++=':'; + memcpy(crt, tmp, len); + crt += len; + } + /* params */ + tmp=uri.params.s; + if (tmp){ + len=uri.params.len; if(crt+len+1>end) goto error_uri; + *crt++=';'; + memcpy(crt,tmp,len); + crt += len; + } + /* headers */ + tmp=uri.headers.s; + if (tmp){ + len=uri.headers.len; if(crt+len+1>end) goto error_uri; + *crt++='?'; + memcpy(crt,tmp,len); + crt += len; + } + *crt=0; /* null terminate the thing */ + /* copy it to the msg */ + pkg_free(msg->dst_uri.s); + msg->dst_uri.s=new_uri; + msg->dst_uri.len=crt-new_uri; + + return 0; + +error_uri: + pkg_free(new_uri); + return -1; +} + +int rewrite_ruri(struct sip_msg *msg, str *sval, int ival, + enum rw_ruri_part part) +{ + int user = 0; + char *tmp, *new_uri, *end, *crt; + int len; + struct sip_uri uri; + + if (msg->new_uri.s) { + tmp=msg->new_uri.s; + len=msg->new_uri.len; + }else{ + tmp=msg->first_line.u.request.uri.s; + len=msg->first_line.u.request.uri.len; + } + if (parse_uri(tmp, len, &uri)<0){ + LM_ERR("bad uri <%.*s>, dropping packet\n", len, tmp); + return -1; + } + + new_uri=pkg_malloc(MAX_URI_SIZE); + if (new_uri==0){ + LM_ERR("memory allocation failure\n"); + return -1; + } + end=new_uri+MAX_URI_SIZE; + crt=new_uri; + /* begin copying */ + len = (uri.user.len?uri.user.s:uri.host.s) - tmp; + if (crt+len>end) goto error; + memcpy(crt,tmp,len);crt+=len; + + if (part==RW_RURI_PREFIX) { + if (crt+sval->len>end) goto error; + memcpy( crt, sval->s, sval->len); + crt+=sval->len; + /* whatever we had before, with prefix we have username + now */ + user=1; + } + + if ((part==RW_RURI_USER)||(part==RW_RURI_USERPASS)) { + tmp=sval->s; + len=sval->len; + } else if (part==RW_RURI_STRIP) { + if (ival>uri.user.len) { + LM_WARN("too long strip asked; " + " deleting username: %d of <%.*s>\n", + ival, uri.user.len, uri.user.s); + len=0; + } else if (ival==uri.user.len) { + len=0; + } else { + tmp=uri.user.s + ival; + len=uri.user.len - ival; + } + } else if (part==RW_RURI_STRIP_TAIL) { + if (ival>uri.user.len) { + LM_WARN("too long strip_tail asked;" + " deleting username: %d of <%.*s>\n", + ival, uri.user.len, uri.user.s); + len=0; + } else if (ival==uri.user.len) { + len=0; + } else { + tmp=uri.user.s; + len=uri.user.len - ival; + } + } else { + tmp=uri.user.s; + len=uri.user.len; + } + + if (len){ + if(crt+len>end) goto error; + memcpy(crt,tmp,len);crt+=len; + user=1; /* we have an user field so mark it */ + } + + if (part==RW_RURI_USERPASS) tmp=0; + else tmp=uri.passwd.s; + /* passwd */ + if (tmp){ + len=uri.passwd.len; if(crt+len+1>end) goto error; + *crt=':'; crt++; + memcpy(crt,tmp,len);crt+=len; + } + /* host */ + if (user || tmp){ /* add @ */ + if(crt+1>end) goto error; + *crt='@'; crt++; + } + if ((part==RW_RURI_HOST) ||(part==RW_RURI_HOSTPORT)) { + tmp=sval->s; + len=sval->len; + } else { + tmp=uri.host.s; + len = uri.host.len; + } + if (tmp){ + if(crt+len>end) goto error; + memcpy(crt,tmp,len);crt+=len; + } + /* port */ + if (part==RW_RURI_HOSTPORT) tmp=0; + else if (part==RW_RURI_PORT) { + tmp=sval->s; + len=sval->len; + } else { + tmp=uri.port.s; + len = uri.port.len; + } + if (tmp && len>0){ + if(crt+len+1>end) goto error; + *crt=':'; crt++; + memcpy(crt,tmp,len);crt+=len; + } + /* params */ + tmp=uri.params.s; + if (tmp){ + /* include in param string the starting ';' */ + len=uri.params.len+1; + tmp--; + if(crt+len+1>end) goto error; + /* if a maddr param is present, strip it out */ + if (uri.maddr.len && + (part==RW_RURI_HOSTPORT || part==RW_RURI_HOST)) { + memcpy(crt,tmp,uri.maddr.s-tmp-1); + crt+=uri.maddr.s-tmp-1; + memcpy(crt,uri.maddr_val.s+uri.maddr_val.len, + tmp+len-uri.maddr_val.s-uri.maddr_val.len); + crt+=tmp+len-uri.maddr_val.s-uri.maddr_val.len; + } else { + memcpy(crt,tmp,len);crt+=len; + } + } + /* headers */ + tmp=uri.headers.s; + if (tmp){ + len=uri.headers.len; if(crt+len+1>end) goto error; + *crt='?'; crt++; + memcpy(crt,tmp,len);crt+=len; + } + *crt=0; /* null terminate the thing */ + /* copy it to the msg */ + if (msg->new_uri.s) pkg_free(msg->new_uri.s); + msg->new_uri.s=new_uri; + msg->new_uri.len=crt-new_uri; + msg->parsed_uri_ok=0; + + return 0; + +error: + LM_ERR("uri too long\n"); + if (new_uri) + pkg_free(new_uri); + return -1; +} + /* * Make a private copy of the string and assign it to path_vec */ diff --git a/parser/msg_parser.h b/parser/msg_parser.h index 401be6ccf5..20855e0a5b 100644 --- a/parser/msg_parser.h +++ b/parser/msg_parser.h @@ -476,6 +476,27 @@ int set_ruri(struct sip_msg* msg, str* uri); int set_dst_uri(struct sip_msg* msg, str* uri); +void reset_dst_uri(struct sip_msg *msg); + + +int set_dst_host_port(struct sip_msg *msg, str *host, str *port); + + +enum rw_ruri_part { + RW_RURI_HOST = 1, + RW_RURI_HOSTPORT, + RW_RURI_USER, + RW_RURI_USERPASS, + RW_RURI_PORT, + RW_RURI_PREFIX, + RW_RURI_STRIP, + RW_RURI_STRIP_TAIL +}; + +int rewrite_ruri(struct sip_msg *msg, str *sval, int ival, + enum rw_ruri_part part); + + /* * Set the q value of the Request-URI */ diff --git a/pvar.c b/pvar.c index 577db74e7d..df3e25707d 100644 --- a/pvar.c +++ b/pvar.c @@ -2693,8 +2693,6 @@ int pv_set_scriptvar(struct sip_msg* msg, pv_param_t *param, int pv_set_dsturi(struct sip_msg* msg, pv_param_t *param, int op, pv_value_t *val) { - struct action act; - if(msg==NULL || param==NULL) { LM_ERR("bad parameters\n"); @@ -2703,13 +2701,8 @@ int pv_set_dsturi(struct sip_msg* msg, pv_param_t *param, if(val == NULL) { - memset(&act, 0, sizeof(act)); - act.type = RESET_DSTURI_T; - if (do_action(&act, msg)<0) - { - LM_ERR("error - do action failed)\n"); - goto error; - } + reset_dst_uri(msg); + return 1; } if(!(val->flags&PV_VAL_STR)) @@ -2778,8 +2771,6 @@ int pv_set_ru_q(struct sip_msg* msg, pv_param_t *param, int pv_set_ruri_user(struct sip_msg* msg, pv_param_t *param, int op, pv_value_t *val) { - struct action act; - if(msg==NULL || param==NULL) { LM_ERR("bad parameters\n"); @@ -2788,44 +2779,26 @@ int pv_set_ruri_user(struct sip_msg* msg, pv_param_t *param, if(val == NULL) { - memset(&act, 0, sizeof(act)); - act.type = SET_USER_T; - act.elem[0].type = STR_ST; - act.elem[0].u.s = str_empty; - if (do_action(&act, msg)<0) - { - LM_ERR("do action failed)\n"); - goto error; - } - return 0; + val->rs = str_empty; } if(!(val->flags&PV_VAL_STR)) { LM_ERR("str value required to set R-URI user\n"); - goto error; + return -1; } - memset(&act, 0, sizeof(act)); - act.elem[0].type = STR_ST; - act.elem[0].u.s = val->rs; - act.type = SET_USER_T; - if (do_action(&act, msg)<0) - { - LM_ERR("do action failed\n"); - goto error; + if (rewrite_ruri(msg, &val->rs, 0, RW_RURI_USER) < 0) { + LM_ERR("Failed to set R-URI user\n"); + return -1; } return 0; -error: - return -1; } int pv_set_ruri_host(struct sip_msg* msg, pv_param_t *param, int op, pv_value_t *val) { - struct action act; - if(msg==NULL || param==NULL || val==NULL) { LM_ERR("bad parameters\n"); @@ -2835,29 +2808,20 @@ int pv_set_ruri_host(struct sip_msg* msg, pv_param_t *param, if(!(val->flags&PV_VAL_STR)) { LM_ERR("str value required to set R-URI hostname\n"); - goto error; + return -1; } - memset(&act, 0, sizeof(act)); - act.elem[0].type = STR_ST; - act.elem[0].u.s = val->rs; - act.type = SET_HOST_T; - if (do_action(&act, msg)<0) - { - LM_ERR("do action failed\n"); - goto error; + if (rewrite_ruri(msg, &val->rs, 0, RW_RURI_HOST) < 0) { + LM_ERR("Failed to set R-URI hostname\n"); + return -1; } return 0; -error: - return -1; } int pv_set_dsturi_host(struct sip_msg* msg, pv_param_t *param, int op, pv_value_t *val) { - struct action act; - if(msg==NULL || param==NULL || val==NULL) { LM_ERR("bad parameters\n"); @@ -2867,30 +2831,20 @@ int pv_set_dsturi_host(struct sip_msg* msg, pv_param_t *param, if(!(val->flags&PV_VAL_STR)) { LM_ERR("str value required to set DST-URI hostname\n"); - goto error; + return -1; } - memset(&act, 0, sizeof(act)); - act.elem[0].type = STR_ST; - act.elem[0].u.s = val->rs; - act.type = SET_DSTHOST_T; - - if (do_action(&act, msg)<0) - { - LM_ERR("do action failed\n"); - goto error; + if (set_dst_host_port(msg, &val->rs, NULL) < 0) { + LM_ERR("Failed to set DST-URI host\n"); + return -1; } return 0; -error: - return -1; } int pv_set_dsturi_port(struct sip_msg* msg, pv_param_t *param, int op, pv_value_t *val) { - struct action act; - if(msg==NULL || param==NULL) { LM_ERR("bad parameters\n"); @@ -2899,38 +2853,18 @@ int pv_set_dsturi_port(struct sip_msg* msg, pv_param_t *param, if(val == NULL) { - memset(&act, 0, sizeof(act)); - act.type = SET_DSTPORT_T; - act.elem[0].type = STR_ST; - act.elem[0].u.s.s = ""; - act.elem[0].u.s.len = 0; - if (do_action(&act, msg)<0) - { - LM_ERR("do action failed)\n"); - goto error; - } - return 0; - } - - if(!(val->flags&PV_VAL_STR)) + val->rs = str_empty; + } else if(!(val->flags&PV_VAL_STR)) { val->rs.s = int2str(val->ri, &val->rs.len); - val->flags |= PV_VAL_STR; } - memset(&act, 0, sizeof(act)); - act.elem[0].type = STR_ST; - act.elem[0].u.s = val->rs; - act.type = SET_DSTPORT_T; - if (do_action(&act, msg)<0) - { - LM_ERR("do action failed\n"); - goto error; + if (set_dst_host_port(msg, NULL, &val->rs) < 0) { + LM_ERR("Failed to set DST-URI port\n"); + return -1; } return 0; -error: - return -1; } @@ -2939,8 +2873,6 @@ int pv_set_dsturi_port(struct sip_msg* msg, pv_param_t *param, int pv_set_ruri_port(struct sip_msg* msg, pv_param_t *param, int op, pv_value_t *val) { - struct action act; - if(msg==NULL || param==NULL) { LM_ERR("bad parameters\n"); @@ -2949,38 +2881,18 @@ int pv_set_ruri_port(struct sip_msg* msg, pv_param_t *param, if(val == NULL) { - memset(&act, 0, sizeof(act)); - act.type = SET_PORT_T; - act.elem[0].type = STR_ST; - act.elem[0].u.s.s = ""; - act.elem[0].u.s.len = 0; - if (do_action(&act, msg)<0) - { - LM_ERR("do action failed)\n"); - goto error; - } - return 0; + val->rs = str_empty; } if(!(val->flags&PV_VAL_STR)) - { val->rs.s = int2str(val->ri, &val->rs.len); - val->flags |= PV_VAL_STR; - } - memset(&act, 0, sizeof(act)); - act.elem[0].type = STR_ST; - act.elem[0].u.s = val->rs; - act.type = SET_PORT_T; - if (do_action(&act, msg)<0) - { - LM_ERR("do action failed\n"); - goto error; + if (rewrite_ruri(msg, &val->rs, 0, RW_RURI_PORT) < 0) { + LM_ERR("Failed to set R-URI hostname\n"); + return -1; } return 0; -error: - return -1; } diff --git a/route.c b/route.c index 7727d67868..750d774c54 100644 --- a/route.c +++ b/route.c @@ -1085,20 +1085,9 @@ static int fix_actions(struct action* a) int ret; cmd_export_t* cmd; acmd_export_t* acmd; - struct hostent* he; - struct ip_addr ip; - struct socket_info* si; - str host; - int proto=PROTO_NONE, port; - struct proxy_l *p; - struct bl_head *blh; - int i = 0; str s; pv_elem_t *model=NULL; - pv_elem_t *models[5]; - pv_spec_p sp = NULL; xl_level_p xlp; - event_id_t ev_id; if (a==0){ LM_CRIT("null pointer\n"); @@ -1143,63 +1132,6 @@ static int fix_actions(struct action* a) } } break; - case FORWARD_T: - if (sl_fwd_disabled>0) { - LM_ERR("stateless forwarding disabled, but forward() " - "is used!!\n"); - ret = E_CFG; - goto error; - } - sl_fwd_disabled = 0; - if (t->elem[0].type==NOSUBTYPE) - break; - case SEND_T: - if (t->elem[0].type!=STRING_ST) { - LM_CRIT("invalid type %d (should be string)\n", t->type); - ret = E_BUG; - goto error; - } - ret = parse_phostport( t->elem[0].u.string, - strlen(t->elem[0].u.string), - &host.s, &host.len, &port, &proto); - if (ret!=0) { - LM_ERR("ERROR:fix_actions: FORWARD/SEND bad " - "argument\n"); - ret = E_CFG; - goto error; - } - p = mk_proxy( &host,(unsigned short)port, proto, 0); - if (p==0) { - LM_ERR("forward/send failed to add proxy"); - ret = E_CFG; - goto error; - } - t->elem[0].type = PROXY_ST; - t->elem[0].u.data = (void*)p; - - s.s = (char*)t->elem[1].u.data; - if (s.s && t->elem[1].type == STRING_ST) - { - /* commands have only one parameter */ - s.s = (char *)t->elem[1].u.data; - s.len = strlen(s.s); - if(s.len==0) - { - LM_ERR("param is empty string!\n"); - return E_CFG; - } - - if(pv_parse_format(&s ,&model) || model==NULL) - { - LM_ERR("wrong format [%s] for value param!\n", s.s); - ret=E_BUG; - goto error; - } - - t->elem[1].u.data = (void*)model; - t->elem[1].type = SCRIPTVAR_ELEM_ST; - } - break; case IF_T: if (t->elem[0].type!=EXPR_ST){ LM_CRIT("invalid subtype %d for if (should be expr)\n", @@ -1285,7 +1217,7 @@ static int fix_actions(struct action* a) return ret; } break; - case MODULE_T: + case CMD_T: cmd = (cmd_export_t*)t->elem[0].u.data; LM_DBG("fixing %s, %s:%d\n", cmd->name, t->file, t->line); @@ -1310,91 +1242,6 @@ static int fix_actions(struct action* a) goto error; } break; - case FORCE_SEND_SOCKET_T: - if (t->elem[0].type!=SOCKID_ST){ - LM_CRIT("invalid subtype %d for force_send_socket\n", - t->elem[0].type); - ret = E_BUG; - goto error; - } - he=resolvehost(((struct socket_id*)t->elem[0].u.data)->name,0); - if (he==0){ - LM_ERR(" could not resolve %s\n", - ((struct socket_id*)t->elem[0].u.data)->name); - ret = E_BAD_ADDRESS; - goto error; - } - hostent2ip_addr(&ip, he, 0); - si=find_si(&ip, ((struct socket_id*)t->elem[0].u.data)->port, - ((struct socket_id*)t->elem[0].u.data)->proto); - if (si==0){ - LM_ERR("bad force_send_socket" - " argument: %s:%d (opensips doesn't listen on it)\n", - ((struct socket_id*)t->elem[0].u.data)->name, - ((struct socket_id*)t->elem[0].u.data)->port); - ret = E_BAD_ADDRESS; - goto error; - } - t->elem[0].u.data=si; - t->elem[0].type=SOCKETINFO_ST; - break; - case SETFLAG_T: - case RESETFLAG_T: - case ISFLAGSET_T: - if (t->elem[0].type == NUMBER_ST) { - s.s = int2str((unsigned long)t->elem[0].u.number, &s.len); - t->elem[0].u.number = fixup_flag(FLAG_TYPE_MSG, &s); - - } else if (t->elem[0].type == STR_ST) { - t->elem[0].u.number = fixup_flag(FLAG_TYPE_MSG, &t->elem[0].u.s); - - } else { - LM_CRIT("bad xxxflag() type %d\n", t->elem[0].type); - ret = E_BUG; - goto error; - } - - if (t->elem[0].u.number == NAMED_FLAG_ERROR) { - LM_CRIT("Fixup flag failed!\n"); - ret=E_CFG; - goto error; - } - break; - case SETBFLAG_T: - case RESETBFLAG_T: - case ISBFLAGSET_T: - if (t->elem[0].type!=NUMBER_ST) { - LM_CRIT("bad xxxbflag() type " - "%d,%d\n", t->elem[0].type, t->elem[0].type); - ret=E_BUG; - goto error; - } - - if (t->elem[1].type == NUMBER_ST) { - s.s = int2str((unsigned long)t->elem[1].u.number, &s.len); - t->elem[1].u.number = fixup_flag(FLAG_TYPE_BRANCH, &s); - - } else if (t->elem[1].type == STR_ST) { - t->elem[1].u.number = fixup_flag(FLAG_TYPE_BRANCH, - &t->elem[1].u.s); - } else { - LM_CRIT("bad xxxbflag() type " - "%d,%d\n", t->elem[1].type, t->elem[1].type); - ret=E_BUG; - goto error; - } - - if (t->elem[1].u.number == NAMED_FLAG_ERROR) { - LM_CRIT("Fixup flag failed!\n"); - ret=E_CFG; - goto error; - } - - if (t->elem[1].u.data==0) { - ret=E_CFG; - goto error; - } - break; case EQ_T: case COLONEQ_T: case PLUSEQ_T: @@ -1410,129 +1257,6 @@ static int fix_actions(struct action* a) return ret; } break; - case USE_BLACKLIST_T: - case UNUSE_BLACKLIST_T: - if (t->elem[0].type!=STRING_ST) { - LM_CRIT("bad [UN]USE_BLACKLIST type %d\n",t->elem[0].type); - ret=E_BUG; - goto error; - } - host.s = t->elem[0].u.string; - host.len = strlen(host.s); - if (!strcasecmp(host.s, "all")) { - blh = NULL; - } else { - blh = get_bl_head_by_name(&host); - if (!blh) { - LM_ERR("[UN]USE_BLACKLIST - list " - "%s not configured\n", t->elem[0].u.string); - ret=E_CFG; - goto error; - } - } - t->elem[0].type = BLACKLIST_ST; - t->elem[0].u.data = blh; - break; - case CACHE_STORE_T: - case CACHE_FETCH_T: - case CACHE_COUNTER_FETCH_T: - case CACHE_REMOVE_T: - case CACHE_ADD_T: - case CACHE_SUB_T: - case CACHE_RAW_QUERY_T: - /* attr name */ - s.s = (char*)t->elem[1].u.data; - s.len = strlen(s.s); - if(s.len==0) { - LM_ERR("param 2 is empty string!\n"); - return E_CFG; - } - - if(pv_parse_format(&s ,&model) || model==NULL) { - LM_ERR("wrong format [%s] for value param!\n", s.s); - ret=E_BUG; - goto error; - } - t->elem[1].u.data = (void*)model; - - if (t->type==CACHE_REMOVE_T) - break; - - /* value */ - if (t->type==CACHE_FETCH_T || - t->type==CACHE_COUNTER_FETCH_T) { - if(((pv_spec_p)t->elem[2].u.data)->setf == NULL) - { - LM_ERR("Third argument cannot be a read-only pvar\n"); - ret=E_CFG; - goto error; - } - } else if (t->type==CACHE_STORE_T) { - s.s = (char*)t->elem[2].u.data; - s.len = strlen(s.s); - if(s.len==0) { - LM_ERR("param 2 is empty string!\n"); - return E_CFG; - } - - if(pv_parse_format(&s ,&model) || model==NULL) { - LM_ERR("wrong format [%s] for value param!\n",s.s); - ret=E_BUG; - goto error; - } - t->elem[2].u.data = (void*)model; - } else if (t->type==CACHE_RAW_QUERY_T) { - if(t->elem[2].u.data != NULL) { - s.s = (char*)t->elem[2].u.data; - s.len = strlen(s.s); - - t->elem[2].u.data = (void*)parse_pvname_list(&s, PVT_AVP); - if (t->elem[2].u.data == NULL) { - ret=E_BUG; - goto error; - } - } - } else if (t->type==CACHE_ADD_T || t->type==CACHE_SUB_T) { - if(t->elem[4].u.data != NULL && ((pv_spec_p)t->elem[4].u.data)->setf == NULL) - { - LM_ERR("Fourth argument cannot be a read-only pvar\n"); - ret=E_CFG; - goto error; - } - - } - break; - case SET_ADV_ADDR_T: - s.s = (char *)t->elem[0].u.data; - if (s.s == NULL) { - LM_ERR("null param in set_advertised_address\n"); - ret=E_BUG; - goto error; - } - s.len = strlen(s.s); - if(pv_parse_format(&s ,&model) || model==NULL) { - LM_ERR("wrong format for [%.*s] advertised param!\n", - t->elem[1].u.s.len,t->elem[1].u.s.s); - ret=E_BUG; - goto error; - } - t->elem[0].u.data = (void*)model; - break; - case SET_ADV_PORT_T: - if (t->elem[0].type == STR_ST) { - s.s = (char *)t->elem[0].u.data; - s.len = strlen(s.s); - - if (pv_parse_format(&s ,&model) != 0 || !model) { - LM_ERR("wrong format for [%.*s] advertised port!\n", - t->elem[1].u.s.len, t->elem[1].u.s.s); - ret = E_BUG; - goto error; - } - - t->elem[0].u.data = model; - } - break; case XDBG_T: case XLOG_T: s.s = (char*)t->elem[1].u.data; @@ -1616,123 +1340,6 @@ static int fix_actions(struct action* a) t->elem[1].type = SCRIPTVAR_ELEM_ST; } break; - case RAISE_EVENT_T: - s.s = t->elem[0].u.data; - s.len = strlen(s.s); - ev_id = evi_get_id(&s); - if (ev_id == EVI_ERROR) { - ev_id = evi_publish_event(s); - if (ev_id == EVI_ERROR) { - LM_ERR("cannot subscribe event\n"); - ret=E_UNSPEC; - goto error; - } - } - t->elem[0].u.number = ev_id; - t->elem[0].type = NUMBER_ST; - if (t->elem[1].u.data && - ((pv_spec_p)t->elem[1].u.data)->type != PVT_AVP) { - LM_ERR("second parameter should be an avp\n"); - ret=E_UNSPEC; - goto error; - } - /* if was called with 3 parameters */ - if (t->elem[2].u.data && - ((pv_spec_p)t->elem[2].u.data)->type != PVT_AVP) { - LM_ERR("third parameter should be also an avp\n"); - ret=E_UNSPEC; - goto error; - } - break; - case CONSTRUCT_URI_T: - for (i=0;i<5;i++) - { - s.s = (char*)t->elem[i].u.data; - s.len = strlen(s.s); - if(s.len==0) - continue; - - if(pv_parse_format(&s ,&(models[i])) || models[i]==NULL) - { - LM_ERR("wrong format [%s] for value param!\n",s.s); - ret=E_BUG; - goto error; - } - - t->elem[i].u.data = (void*)models[i]; - } - - if (((pv_spec_p)t->elem[5].u.data)->type != PVT_AVP) - { - LM_ERR("Wrong type for the third argument - " - "must be an AVP\n"); - ret=E_BUG; - goto error; - } - - break; - case GET_TIMESTAMP_T: - if (((pv_spec_p)t->elem[0].u.data)->type != PVT_AVP) - { - LM_ERR("Wrong type for the first argument - " - "must be an AVP\n"); - ret=E_BUG; - goto error; - } - - if (((pv_spec_p)t->elem[1].u.data)->type != PVT_AVP) - { - LM_ERR("Wrong type for the second argument - " - "must be an AVP\n"); - ret=E_BUG; - goto error; - } - break; - case IS_MYSELF_T: - s.s = (char*)t->elem[0].u.data; - s.len = strlen(s.s); - if(s.len == 0) { - LM_ERR("param 1 is empty string!\n"); - return E_CFG; - } - - if(pv_parse_format(&s ,&model) || model == NULL) { - LM_ERR("wrong format [%s] for value param!\n", s.s); - ret=E_BUG; - goto error; - } - t->elem[0].u.data = (void*)model; - t->elem[0].type = SCRIPTVAR_ELEM_ST; - - s.s = (char *)t->elem[1].u.data; - if (s.s == NULL) - break; - - s.len = strlen(s.s); - if(s.len == 0) { - LM_ERR("param 2 is empty string!\n"); - return E_CFG; - } - if (s.s[0] == PV_MARKER) { - sp = pkg_malloc(sizeof *sp); - if (!sp) { - LM_ERR("No more pkg memory\n"); - return E_BUG; - } - if (pv_parse_spec(&s, sp) == NULL) { - LM_ERR("Unable to parse port parameter var\n"); - return E_BUG; - } - t->elem[1].u.data = (void*)sp; - t->elem[1].type = SCRIPTVAR_ST; - } else { - if (str2int(&s, (unsigned int *)&port) < 0) { - LM_ERR("port parameter should be a number\n"); - return E_CFG; - } - t->elem[1].u.number = port; - t->elem[1].type = NUMBER_ST; - } } } return 0; @@ -1881,7 +1488,7 @@ static int check_actions(struct action *a, int r_type) if (n!=0) goto error; } break; - case MODULE_T: + case CMD_T: /* do check :D */ fct = (cmd_export_t*)(a->elem[0].u.data); if ( (fct->flags&r_type)!=r_type ) { diff --git a/route_struct.c b/route_struct.c index 9f583995be..d3efa1fa5c 100644 --- a/route_struct.c +++ b/route_struct.c @@ -448,12 +448,6 @@ void print_expr(struct expr* exp) void print_action(struct action* t) { switch(t->type){ - case FORWARD_T: - LM_GEN1(L_DBG, "forward("); - break; - case SEND_T: - LM_GEN1(L_DBG, "send("); - break; case ASSERT_T: LM_GEN1(L_DBG, "assert("); break; @@ -472,80 +466,17 @@ void print_action(struct action* t) case EXEC_T: LM_GEN1(L_DBG, "exec("); break; - case REVERT_URI_T: - LM_GEN1(L_DBG, "revert_uri("); - break; - case STRIP_T: - LM_GEN1(L_DBG, "strip("); - break; - case APPEND_BRANCH_T: - LM_GEN1(L_DBG, "append_branch("); - break; - case PREFIX_T: - LM_GEN1(L_DBG, "prefix("); - break; case LEN_GT_T: LM_GEN1(L_DBG, "len_gt("); break; - case SETFLAG_T: - LM_GEN1(L_DBG, "setflag("); - break; - case RESETFLAG_T: - LM_GEN1(L_DBG, "resetflag("); - break; - case ISFLAGSET_T: - LM_GEN1(L_DBG, "isflagset("); - break; - case SETBFLAG_T: - LM_GEN1(L_DBG, "setbflag("); - break; - case RESETBFLAG_T: - LM_GEN1(L_DBG, "resetbflag("); - break; - case ISBFLAGSET_T: - LM_GEN1(L_DBG, "isbflagset("); - break; - case SET_HOST_T: - LM_GEN1(L_DBG, "sethost("); - break; - case SET_HOSTPORT_T: - LM_GEN1(L_DBG, "sethostport("); - break; - case SET_USER_T: - LM_GEN1(L_DBG, "setuser("); - break; - case SET_USERPASS_T: - LM_GEN1(L_DBG, "setuserpass("); - break; - case SET_PORT_T: - LM_GEN1(L_DBG, "setport("); - break; - case SET_URI_T: - LM_GEN1(L_DBG, "seturi("); - break; case IF_T: LM_GEN1(L_DBG, "if ("); break; case WHILE_T: LM_GEN1(L_DBG, "while ("); break; - case MODULE_T: - LM_GEN1(L_DBG, " external_module_call("); - break; - case FORCE_RPORT_T: - LM_GEN1(L_DBG, "force_rport("); - break; - case SET_ADV_ADDR_T: - LM_GEN1(L_DBG, "set_advertised_address("); - break; - case SET_ADV_PORT_T: - LM_GEN1(L_DBG, "set_advertised_port("); - break; - case FORCE_TCP_ALIAS_T: - LM_GEN1(L_DBG, "force_tcp_alias("); - break; - case FORCE_SEND_SOCKET_T: - LM_GEN1(L_DBG, "force_send_socket"); + case CMD_T: + LM_GEN1(L_DBG, " function_call("); break; case RETURN_T: LM_GEN1(L_DBG, "return("); @@ -689,7 +620,7 @@ int is_mod_func_used(struct action *a, char *name, int param_no) { cmd_export_t *cmd; while(a) { - if (a->type==MODULE_T) { + if (a->type==CMD_T) { /* first param is the name of the function */ cmd = (cmd_export_t*)a->elem[0].u.data; if (strcasecmp(cmd->name, name)==0) { diff --git a/route_struct.h b/route_struct.h index 3d5d8ba496..f3cbf3e142 100644 --- a/route_struct.h +++ b/route_struct.h @@ -57,39 +57,17 @@ enum { EQUAL_OP=20, MATCH_OP, NOTMATCH_OP, MATCHD_OP, NOTMATCHD_OP, GT_OP, LT_OP, GTE_OP, LTE_OP, DIFF_OP, VALUE_OP, NO_OP }; enum { DEFAULT_O=1, ACTION_O, EXPR_O, NUMBER_O, NUMBERV_O, STRINGV_O, SCRIPTVAR_O}; -enum { FORWARD_T=1, SEND_T, ASSERT_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T, - SET_HOST_T, SET_HOSTPORT_T, SET_USER_T, SET_USERPASS_T, - SET_PORT_T, SET_URI_T, IF_T, MODULE_T, AMODULE_T, - SETFLAG_T, RESETFLAG_T, ISFLAGSET_T , - SETBFLAG_T, RESETBFLAG_T, ISBFLAGSET_T , - LEN_GT_T, PREFIX_T, STRIP_T,STRIP_TAIL_T, - APPEND_BRANCH_T, - REMOVE_BRANCH_T, - REVERT_URI_T, - FORCE_RPORT_T, - FORCE_LOCAL_RPORT_T, - SET_ADV_ADDR_T, - SET_ADV_PORT_T, - FORCE_TCP_ALIAS_T, - FORCE_SEND_SOCKET_T, - SERIALIZE_BRANCHES_T, - NEXT_BRANCHES_T, +enum { ASSERT_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T, + IF_T, CMD_T, AMODULE_T, + LEN_GT_T, RETURN_T, EXIT_T, - SWITCH_T, CASE_T, DEFAULT_T, - WHILE_T, BREAK_T, FOR_EACH_T, - SET_DSTURI_T, SET_DSTHOST_T, SET_DSTPORT_T, RESET_DSTURI_T, ISDSTURISET_T, + SWITCH_T, CASE_T, DEFAULT_T, BREAK_T, + WHILE_T, FOR_EACH_T, EQ_T, COLONEQ_T, PLUSEQ_T, MINUSEQ_T, DIVEQ_T, MULTEQ_T, MODULOEQ_T, - BANDEQ_T, BOREQ_T, BXOREQ_T, USE_BLACKLIST_T, UNUSE_BLACKLIST_T, - SET_TIME_STAMP_T,RESET_TIME_STAMP_T, DIFF_TIME_STAMP_T, - PV_PRINTF_T, - CACHE_STORE_T, CACHE_FETCH_T, CACHE_COUNTER_FETCH_T, CACHE_REMOVE_T, - CACHE_ADD_T,CACHE_SUB_T,CACHE_RAW_QUERY_T, + BANDEQ_T, BOREQ_T, BXOREQ_T, XDBG_T, XLOG_T, - RAISE_EVENT_T, SUBSCRIBE_EVENT_T, - CONSTRUCT_URI_T, - GET_TIMESTAMP_T, SCRIPT_TRACE_T, ASYNC_T, LAUNCH_T, - IS_MYSELF_T + ASYNC_T, LAUNCH_T, }; enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST, EXPR_ST, ACTIONS_ST, CMD_ST, ACMD_ST, MODFIXUP_ST, diff --git a/sr_module.c b/sr_module.c index 4c84d9b7d0..458d2b6702 100644 --- a/sr_module.c +++ b/sr_module.c @@ -426,7 +426,7 @@ cmd_function find_export(char* name, int flags) { cmd_export_t* cmd; - cmd = find_cmd_export_t(name, flags); + cmd = find_mod_cmd_export_t(name, flags); if (cmd==0) return 0; @@ -437,7 +437,7 @@ cmd_function find_export(char* name, int flags) /* Searches the module list for the "name" cmd_export_t structure. */ -cmd_export_t* find_cmd_export_t(char* name, int flags) +cmd_export_t* find_mod_cmd_export_t(char* name, int flags) { struct sr_module* t; cmd_export_t* cmd; @@ -456,9 +456,11 @@ cmd_export_t* find_cmd_export_t(char* name, int flags) return 0; } + + /* Searches the module list for the "name" acmd_export_t structure. */ -acmd_export_t* find_acmd_export_t(char* name) +acmd_export_t* find_mod_acmd_export_t(char* name) { struct sr_module* t; acmd_export_t* cmd; @@ -476,59 +478,6 @@ acmd_export_t* find_acmd_export_t(char* name) return 0; } -/* Checks if the module function is called with the right number of parameters - * and all mandatory parameters are given - * Return: - * 0 - correct call - * -1 - too few parameters - * -2 - too many parameters - * -3 - mandatory parameter omitted - */ -int check_cmd_call_params(cmd_export_t *cmd, action_elem_t *elems, int no_params) -{ - struct cmd_param *param; - int n=0, m=0, i; - - for (param=cmd->params; param->flags; param++, n++) - if (!(param->flags & CMD_PARAM_OPT)) - m = n+1; - - if (no_params < m) /* check the minimum number of arguments for the call, - * including optional params that must be explicitly omitted */ - return -1; - else if (no_params > n) - return -2; - - for (i=1, param=cmd->params; i<=no_params; i++, param++) - if (!(param->flags & CMD_PARAM_OPT) && elems[i].type == NULLV_ST) - return -3; - - return 0; -} - -/* simillar function to check_cmd_call_params but for async cmds */ -int check_acmd_call_params(acmd_export_t *acmd, action_elem_t *elems, int no_params) -{ - struct cmd_param *param; - int n=0, m=0, i; - - for (param=acmd->params; param->flags; param++, n++) - if (!(param->flags & CMD_PARAM_OPT)) - m = n+1; - - if (no_params < m) /* check the minimum number of arguments for the call, - * including optional params that must be explicitly omitted */ - return -1; - else if (no_params > n) - return -2; - - for (i=1, param=acmd->params; i<=no_params; i++, param++) - if (!(param->flags & CMD_PARAM_OPT) && elems[i].type == NULLV_ST) - return -3; - - return 0; -} - /* * searches the module list and returns pointer to "name" function in module * "mod" or 0 if not found diff --git a/sr_module.h b/sr_module.h index ae424228f5..2164a41c9c 100644 --- a/sr_module.h +++ b/sr_module.h @@ -53,17 +53,13 @@ #include "route.h" #include "async.h" #include "transformations.h" +#include "cmds.h" #include "sr_module_deps.h" typedef struct module_exports* (*module_register)(); typedef int (*load_function)(void); -typedef int (*cmd_function)(struct sip_msg*, void*, void*, void*, void*, - void*, void*, void *, void *); -typedef int (*acmd_function)(struct sip_msg*, async_ctx *ctx, - void*, void*, void*, void*, void*, void*, void *, void *); -typedef int (*fixup_function)(void** param); -typedef int (*free_fixup_function)(void** param); + typedef int (*response_function)(struct sip_msg*); typedef void (*destroy_function)(); typedef int (*init_function)(void); @@ -108,45 +104,6 @@ typedef int (*mod_proc_wrapper)(); #define PROC_FLAG_INITCHILD (1<<0) #define PROC_FLAG_HAS_IPC (1<<1) -#define MAX_CMD_PARAMS (MAX_ACTION_ELEMS-1) - - -/* parameter type flags */ -#define CMD_PARAM_INT (1<<0) /* integer parameter */ -#define CMD_PARAM_STR (1<<1) /* string parameter */ -#define CMD_PARAM_VAR (1<<2) /* PV spec parameter */ -#define CMD_PARAM_REGEX (1<<3) /* regexp string parameter */ - -#define CMD_PARAM_OPT (1<<4) /* optional parameter */ -#define CMD_PARAM_FIX_NULL (1<<5) /* run fixup even if optional parameter is omitted */ -#define CMD_PARAM_NO_EXPAND (1<<6) /* TMPHACK: do not pv-expand strings */ -#define CMD_PARAM_STATIC (1<<7) /* don't accept variables or formatted string */ - -struct cmd_param { - int flags; /* parameter flags */ - fixup_function fixup; /* pointer to the function called to "fix" the - parameter */ - free_fixup_function - free_fixup; /* pointer to the function called to free the - "fixed" parameter */ -}; - -struct cmd_export_ { - char* name; /* null terminated command name */ - cmd_function function; /* pointer to the corresponding function */ - struct cmd_param - params[MAX_CMD_PARAMS+1]; /* array of parameters */ - int flags; /* Function flags */ -}; - - -struct acmd_export_ { - char* name; /* null terminated command name */ - acmd_function function; /* pointer to the corresponding function */ - struct cmd_param - params[MAX_CMD_PARAMS+1]; /* array of parameters */ -}; - struct param_export_ { char* name; /*!< null terminated param. name */ @@ -169,11 +126,8 @@ typedef struct dep_export_ { modparam_dependency_t mpd[]; } dep_export_t; -typedef struct cmd_export_ cmd_export_t; -typedef struct acmd_export_ acmd_export_t; typedef struct proc_export_ proc_export_t; - struct sr_module{ char* path; void* handle; @@ -240,10 +194,6 @@ struct sr_module* modules; /*!< global module list*/ int register_builtin_modules(); int register_module(struct module_exports*, char*, void*); int load_module(char* name); -cmd_export_t* find_cmd_export_t(char* name, int flags); -acmd_export_t* find_acmd_export_t(char* name); -int check_cmd_call_params(cmd_export_t *cmd, action_elem_t *elems, int no_params); -int check_acmd_call_params(acmd_export_t *acmd, action_elem_t *elems, int no_params); cmd_function find_export(char* name, int flags); cmd_function find_mod_export(char* mod, char* name, int flags); void destroy_modules(); diff --git a/ut.h b/ut.h index 9f72b4a4be..10a1dc082b 100644 --- a/ut.h +++ b/ut.h @@ -1151,7 +1151,7 @@ static inline void log_expiry(int time_diff,int expire, if (memcmp(func_info,"msg",3) == 0) { for (i=0;itype == MODULE_T) + if ((unsigned char)longest_action[i].a->type == CMD_T) LM_WARN("#%i is a module action : %s - %dus - line %d\n",i+1, ((cmd_export_t*)(longest_action[i].a->elem[0].u.data))->name, longest_action[i].a_time,longest_action[i].a->line);