/* * Parse and set tag AVP specs */ int init_tag_avp(str *tag_avp_param) { pv_spec_t avp_spec; unsigned short avp_flags; if (tag_avp_param->s && tag_avp_param->len > 0) { if (pv_parse_spec(tag_avp_param, &avp_spec)==0 || avp_spec.type != PVT_AVP) { LM_ERR("malformed or non " "AVP %.*s peer_tag_avp definition\n", tag_avp_param->len, tag_avp_param->s); return -1; } if(pv_get_avp_name(0, &avp_spec.pvp, &tag_avp, &avp_flags)!=0) { LM_ERR("[%.*s]- invalid " "peer_tag_avp AVP definition\n", tag_avp_param->len, tag_avp_param->s); return -1; } tag_avp_type = avp_flags; } else { tag_avp.n = 0; } return 0; }
int fix_parameters() { str s; pv_spec_t avp_spec; if (rcv_avp_param && *rcv_avp_param) { s.s = rcv_avp_param; s.len = strlen(s.s); if (pv_parse_spec(&s, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %s AVP definition\n", rcv_avp_param); return -1; } if(pv_get_avp_name(0, &avp_spec.pvp, &rcv_avp_name, &rcv_avp_type)!=0) { LM_ERR("[%s]- invalid AVP definition\n", rcv_avp_param); return -1; } } else { rcv_avp_name.n = 0; rcv_avp_type = 0; } return 1; }
int exec_avp(struct sip_msg *msg, char *cmd, pvname_list_p avpl) { int_str avp_val; int_str avp_name; unsigned short avp_type; FILE *pipe; int ret; char res_line[MAX_URI_SIZE + 1]; str res; int exit_status; int i; pvname_list_t *crt; /* pessimist: assume error by default */ ret = -1; pipe = popen(cmd, "r"); if(pipe == NULL) { LM_ERR("cannot open pipe: %s\n", cmd); ser_error = E_EXEC; return ret; } /* read now line by line */ i = 0; crt = avpl; while(fgets(res_line, MAX_URI_SIZE, pipe) != NULL) { res.s = res_line; res.len = strlen(res.s); /* trim from right */ while(res.len && (res.s[res.len - 1] == '\r' || res.s[res.len - 1] == '\n' || res.s[res.len - 1] == '\t' || res.s[res.len - 1] == ' ')) { res.len--; } /* skip empty line */ if(res.len == 0) continue; /* ZT */ res.s[res.len] = 0; avp_type = 0; if(crt == NULL) { avp_name.n = i + 1; } else { if(pv_get_avp_name(msg, &(crt->sname.pvp), &avp_name, &avp_type) != 0) { LM_ERR("can't get item name [%d]\n", i); goto error; } } avp_type |= AVP_VAL_STR; avp_val.s = res; if(add_avp(avp_type, avp_name, avp_val) != 0) { LM_ERR("unable to add avp\n"); goto error; } if(crt) crt = crt->next; i++; } if(i == 0) LM_DBG("no result from %s\n", cmd); /* success */ ret = 1; error: if(ferror(pipe)) { LM_ERR("pipe: %d/%s\n", errno, strerror(errno)); ser_error = E_EXEC; ret = -1; } exit_status = pclose(pipe); if(WIFEXITED(exit_status)) { /* exited properly .... */ /* return false if script exited with non-zero status */ if(WEXITSTATUS(exit_status) != 0) ret = -1; } else { /* exited erroneously */ LM_ERR("cmd %s failed. exit_status=%d, errno=%d: %s\n", cmd, exit_status, errno, strerror(errno)); ret = -1; } return ret; }
/** * init module function */ static int mod_init(void) { bind_pua_t bind_pua; str s; pv_spec_t avp_spec; bind_pua= (bind_pua_t)find_export("bind_pua", 1,0); if (!bind_pua) { LM_ERR("Can't bind pua\n"); return -1; } if (bind_pua(&pua) < 0) { LM_ERR("Can't bind pua\n"); return -1; } if(pua.send_publish == NULL) { LM_ERR("Could not import send_publish\n"); return -1; } pua_send_publish= pua.send_publish; /* bind to the dialog API */ if (load_dlg_api(&dlg_api)!=0) { LM_ERR("failed to find dialog API - is dialog module loaded?\n"); return -1; } /* register dialog creation callback */ if (dlg_api.register_dlgcb(NULL, DLGCB_CREATED, __dialog_created, NULL, NULL) != 0) { LM_ERR("cannot register callback for dialog creation\n"); return -1; } if(use_pubruri_avps) { if(!(pubruri_caller_avp && *pubruri_caller_avp) && (pubruri_callee_avp && *pubruri_callee_avp)) { LM_ERR("pubruri_caller_avp and pubruri_callee_avp must be set, if use_pubruri_avps is enabled\n"); return -1; } s.s = pubruri_caller_avp; s.len = strlen(s.s); if (pv_parse_spec(&s, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %s AVP definition\n", pubruri_caller_avp); return -1; } if(pv_get_avp_name(0, &avp_spec.pvp, &pubruri_caller_avp_name, &pubruri_caller_avp_type)!=0) { LM_ERR("[%s]- invalid AVP definition\n", pubruri_caller_avp); return -1; } s.s = pubruri_callee_avp; s.len = strlen(s.s); if (pv_parse_spec(&s, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %s AVP definition\n", pubruri_callee_avp); return -1; } if(pv_get_avp_name(0, &avp_spec.pvp, &pubruri_callee_avp_name, &pubruri_callee_avp_type)!=0) { LM_ERR("[%s]- invalid AVP definition\n", pubruri_callee_avp); return -1; } } return 0; }
/*! \brief * Initialize parent */ static int mod_init(void) { pv_spec_t avp_spec; str s; bind_usrloc_t bind_usrloc; LM_INFO("initializing...\n"); /* load SIGNALING API */ if(load_sig_api(&sigb)< 0) { LM_ERR("can't load signaling functions\n"); return -1; } /* load TM API */ memset(&tmb, 0, sizeof(struct tm_binds)); load_tm_api(&tmb); realm_prefix.s = realm_pref; realm_prefix.len = strlen(realm_pref); rcv_param.len = strlen(rcv_param.s); if (rcv_avp_param && *rcv_avp_param) { s.s = rcv_avp_param; s.len = strlen(s.s); if (pv_parse_spec(&s, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %s AVP definition\n", rcv_avp_param); return -1; } if(pv_get_avp_name(0, &avp_spec.pvp, &rcv_avp_name, &rcv_avp_type)!=0) { LM_ERR("[%s]- invalid AVP definition\n", rcv_avp_param); return -1; } } else { rcv_avp_name = -1; rcv_avp_type = 0; } if (mct_avp_param && *mct_avp_param) { s.s = mct_avp_param; s.len = strlen(s.s); if (pv_parse_spec(&s, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %s AVP definition\n", mct_avp_param); return -1; } if(pv_get_avp_name(0, &avp_spec.pvp, &mct_avp_name, &mct_avp_type)!=0) { LM_ERR("[%s]- invalid AVP definition\n", mct_avp_param); return -1; } } else { mct_avp_name = -1; mct_avp_type = 0; } if (attr_avp_param && *attr_avp_param) { s.s = attr_avp_param; s.len = strlen(s.s); if (pv_parse_spec(&s, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %s AVP definition\n", attr_avp_param); return -1; } if(pv_get_avp_name(0, &avp_spec.pvp, &attr_avp_name, &attr_avp_type)!=0) { LM_ERR("[%s]- invalid AVP definition\n", attr_avp_param); return -1; } } else { attr_avp_name = -1; attr_avp_type = 0; } bind_usrloc = (bind_usrloc_t)find_export("ul_bind_usrloc", 1, 0); if (!bind_usrloc) { LM_ERR("can't bind usrloc\n"); return -1; } /* Normalize default_q parameter */ if (default_q != Q_UNSPECIFIED) { if (default_q > MAX_Q) { LM_DBG("default_q = %d, lowering to MAX_Q: %d\n", default_q, MAX_Q); default_q = MAX_Q; } else if (default_q < MIN_Q) { LM_DBG("default_q = %d, raising to MIN_Q: %d\n", default_q, MIN_Q); default_q = MIN_Q; } } if (bind_usrloc(&ul) < 0) { return -1; } /* * Import use_domain parameter from usrloc */ reg_use_domain = ul.use_domain; if (sock_hdr_name.s) sock_hdr_name.len = strlen(sock_hdr_name.s); if (gruu_secret.s) gruu_secret.len = strlen(gruu_secret.s); /* fix the flags */ fix_flag_name(tcp_persistent_flag_s, tcp_persistent_flag); tcp_persistent_flag = get_flag_id_by_name(FLAG_TYPE_MSG, tcp_persistent_flag_s); tcp_persistent_flag = (tcp_persistent_flag!=-1)?(1<<tcp_persistent_flag):0; return 0; }
/* * Initialize parameters containing the ID of * AVPs with various timers */ int init_avp_params(char *fr_timer_param, char *fr_inv_timer_param) { pv_spec_t avp_spec; unsigned short avp_type; if (fr_timer_param && *fr_timer_param) { fr_timer_str.s = fr_timer_param; fr_timer_str.len = strlen(fr_timer_str.s); LM_WARN("using AVP for TM fr_timer is deprecated," " use t_set_fr(...) instead\n"); if(fr_timer_str.s[0]==PV_MARKER) { if (pv_parse_spec(&fr_timer_str, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %s AVP definition\n", fr_timer_param); return -1; } if(pv_get_avp_name(0, &avp_spec.pvp, &fr_timer_avp, &avp_type)!=0) { LM_ERR("[%s]- invalid AVP definition\n", fr_timer_param); return -1; } fr_timer_avp_type = avp_type; } else { if (parse_avp_spec( &fr_timer_str, &fr_timer_avp_type, &fr_timer_avp, &fr_timer_index)<0) { LOG(L_CRIT,"ERROR:tm:init_avp_params: invalid fr_timer " "AVP specs \"%s\"\n", fr_timer_param); return -1; } /* ser flavour uses the To track of AVPs */ fr_timer_avp_type |= AVP_TRACK_TO; } } if (fr_inv_timer_param && *fr_inv_timer_param) { fr_inv_timer_str.s = fr_inv_timer_param; fr_inv_timer_str.len = strlen(fr_inv_timer_str.s); LM_WARN("using AVP for TM fr_inv_timer is deprecated," " use t_set_fr(...) instead\n"); if(fr_inv_timer_str.s[0]==PV_MARKER) { if (pv_parse_spec(&fr_inv_timer_str, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %s AVP definition\n", fr_inv_timer_param); return -1; } if(pv_get_avp_name(0, &avp_spec.pvp, &fr_inv_timer_avp, &avp_type)!=0) { LM_ERR("[%s]- invalid AVP definition\n", fr_inv_timer_param); return -1; } fr_inv_timer_avp_type = avp_type; } else { if (parse_avp_spec( &fr_inv_timer_str, &fr_inv_timer_avp_type, &fr_inv_timer_avp, &fr_inv_timer_index)<0) { LOG(L_CRIT,"ERROR:tm:init_avp_params: invalid fr_inv_timer " "AVP specs \"%s\"\n", fr_inv_timer_param); return -1; } /* ser flavour uses the To track of AVPs */ fr_inv_timer_avp_type |= AVP_TRACK_TO; } } return 0; }
/* ret= 0! if action -> end of list(e.g DROP), > 0 to continue processing next actions and <0 on error */ 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 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; action_elem_t *route_params_bak; int route_params_number_bak; /* reset the value of error to E_UNSPEC so avoid unknowledgable functions to return with error (status<0) and not setting it leaving there previous error; cache the previous value though for functions which want to process it */ prev_ser_error=ser_error; ser_error=E_UNSPEC; start_expire_timer(start,execmsgthreshold); ret=E_BUG; switch ((unsigned char)a->type){ case DROP_T: script_trace("core", "drop", msg, a->line) ; action_flags |= ACT_FL_DROP; case EXIT_T: script_trace("core", "exit", msg, a->line) ; ret=0; action_flags |= ACT_FL_EXIT; break; case RETURN_T: script_trace("core", "return", msg, 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)) { ret=-1; } else { if(!(val.flags&PV_VAL_INT)) ret = 1; else ret = val.ri; } pv_value_destroy(&val); } else { ret=a->elem[0].u.number; } action_flags |= ACT_FL_RETURN; break; case FORWARD_T: script_trace("core", "forward", msg, 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)) { ret=forward_request(msg,(struct proxy_l*)a->elem[0].u.data); 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->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; } p=(struct proxy_l*)a->elem[0].u.data; 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\n"); 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); pkg_free(tmp); } else { ret = msg_send(0/*send_sock*/, p->proto, to, 0/*id*/, msg->buf, msg->len); } if (ret!=0 && p->host.h_addr_list[p->addr_idx+1]) p->addr_idx++; } pkg_free(to); if (ret==0) ret=1; break; case LOG_T: script_trace("core", "log", msg, a->line) ; if ((a->elem[0].type!=NUMBER_ST)|(a->elem[1].type!=STRING_ST)){ LM_ALERT("BUG in log() types %d, %d\n", a->elem[0].type, a->elem[1].type); ret=E_BUG; break; } 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->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(), getb0flags(), msg->force_send_socket); /* reset all branch info */ msg->force_send_socket = 0; setb0flags(0); set_ruri_q(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->force_send_socket); } break; case REMOVE_BRANCH_T: script_trace("core", "remove_branch", msg, 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->line) ; if (a->elem[0].type!=NUMBER_ST) { LM_ALERT("BUG in len_gt type %d\n", a->elem[0].type ); ret=E_BUG; break; } ret = (msg->len >= (unsigned int)a->elem[0].u.number) ? 1 : -1; break; case SET_DEBUG_T: script_trace("core", "set_debug", msg, a->line) ; if (a->elem[0].type==NUMBER_ST) set_proc_debug_level(a->elem[0].u.number); else reset_proc_debug_level(); ret = 1; break; case SETFLAG_T: script_trace("core", "setflag", msg, a->line) ; ret = setflag( msg, a->elem[0].u.number ); break; case RESETFLAG_T: script_trace("core", "resetflag", msg, a->line) ; ret = resetflag( msg, a->elem[0].u.number ); break; case ISFLAGSET_T: script_trace("core", "isflagset", msg, a->line) ; ret = isflagset( msg, a->elem[0].u.number ); break; case SETSFLAG_T: script_trace("core", "setsflag", msg, a->line) ; ret = setsflag( a->elem[0].u.number ); break; case RESETSFLAG_T: script_trace("core", "resetsflag", msg, a->line) ; ret = resetsflag( a->elem[0].u.number ); break; case ISSFLAGSET_T: script_trace("core", "issflagset", msg, a->line) ; ret = issflagset( a->elem[0].u.number ); break; case SETBFLAG_T: script_trace("core", "setbflag", msg, a->line) ; ret = setbflag( a->elem[0].u.number, a->elem[1].u.number ); break; case RESETBFLAG_T: script_trace("core", "resetbflag", msg, a->line) ; ret = resetbflag( a->elem[0].u.number, a->elem[1].u.number ); break; case ISBFLAGSET_T: script_trace("core", "isbflagset", msg, a->line) ; ret = isbflagset( a->elem[0].u.number, a->elem[1].u.number ); break; case ERROR_T: script_trace("core", "error", msg, a->line) ; if ((a->elem[0].type!=STRING_ST)|(a->elem[1].type!=STRING_ST)){ LM_ALERT("BUG in error() types %d, %d\n", a->elem[0].type, a->elem[1].type); ret=E_BUG; break; } LM_ERR("error(\"%s\", \"%s\") not implemented yet\n", a->elem[0].u.string, a->elem[1].u.string); ret=1; break; case ROUTE_T: script_trace("route", rlist[a->elem[0].u.number].name, msg, a->line) ; if (a->elem[0].type!=NUMBER_ST){ LM_ALERT("BUG in route() type %d\n", a->elem[0].type); ret=E_BUG; break; } if ((a->elem[0].u.number>RT_NO)||(a->elem[0].u.number<0)){ LM_ALERT("BUG - invalid routing table number in" "route(%lu)\n", a->elem[0].u.number); ret=E_CFG; break; } /* check if the route has parameters */ if (a->elem[1].type != 0) { if (a->elem[1].type != NUMBER_ST || a->elem[2].type != SCRIPTVAR_ELEM_ST) { LM_ALERT("BUG in route() type %d/%d\n", a->elem[1].type, a->elem[2].type); ret=E_BUG; break; } route_params_bak = route_params; route_params = (action_elem_t *)a->elem[2].u.data; route_params_number_bak = route_params_number; route_params_number = a->elem[1].u.number; return_code=run_actions(rlist[a->elem[0].u.number].a, msg); route_params = route_params_bak; route_params_number = route_params_number_bak; } else { return_code=run_actions(rlist[a->elem[0].u.number].a, msg); } ret=return_code; break; case REVERT_URI_T: script_trace("core", "revert_uri", msg, 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->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->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->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 (user || 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->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->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->line) ; /* if null expr => ignore if? */ if ((a->elem[0].type==EXPR_ST)&&a->elem[0].u.data){ v=eval_expr((struct expr*)a->elem[0].u.data, msg, 0); /* set return code to expr value */ if (v<0 || (action_flags&ACT_FL_RETURN) || (action_flags&ACT_FL_EXIT) ){ if (v==EXPR_DROP || (action_flags&ACT_FL_RETURN) || (action_flags&ACT_FL_EXIT) ){ /* hack to quit on DROP*/ ret=0; return_code = 0; break; }else{ LM_WARN("error in expression (l=%d)\n", a->line); } } ret=1; /*default is continue */ if (v>0) { if ((a->elem[1].type==ACTIONS_ST)&&a->elem[1].u.data){ ret=run_action_list( (struct action*)a->elem[1].u.data,msg ); return_code = ret; } else return_code = v; }else{ if ((a->elem[2].type==ACTIONS_ST)&&a->elem[2].u.data){ ret=run_action_list( (struct action*)a->elem[2].u.data,msg); return_code = ret; } else return_code = v; } } break; case WHILE_T: script_trace("core", "while", msg, a->line) ; /* if null expr => ignore if? */ if ((a->elem[0].type==EXPR_ST)&&a->elem[0].u.data){ len = 0; while(1) { if(len++ >= max_while_loops) { LM_INFO("max while loops are encountered\n"); break; } v=eval_expr((struct expr*)a->elem[0].u.data, msg, 0); /* set return code to expr value */ if (v<0 || (action_flags&ACT_FL_RETURN) || (action_flags&ACT_FL_EXIT) ){ if (v==EXPR_DROP || (action_flags&ACT_FL_RETURN) || (action_flags&ACT_FL_EXIT) ){ ret=0; return_code = 0; break; }else{ LM_WARN("error in expression (l=%d)\n", a->line); } } ret=1; /*default is continue */ if (v>0) { if ((a->elem[1].type==ACTIONS_ST) &&a->elem[1].u.data){ ret=run_action_list( (struct action*)a->elem[1].u.data,msg ); /* check if return was done */ if ((action_flags&ACT_FL_RETURN) || (action_flags&ACT_FL_EXIT) ){ break; } return_code = ret; } else { /* we should not get here */ return_code = v; break; } } else { /* condition was false */ return_code = v; break; } } } break; case CACHE_STORE_T: script_trace("core", "cache_store", msg, 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->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->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; 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->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; } int aux_counter; /* 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"); pkg_free(aux.s); return -1; } } break; case CACHE_ADD_T: script_trace("core", "cache_add", msg, 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; /* TODO - return the new value to script ? */ ret = cachedb_add(&a->elem[0].u.s, &name_s, increment,expires,NULL); break; case CACHE_SUB_T: script_trace("core", "cache_sub", msg, 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; /* TODO - return new value to script ? */ ret = cachedb_sub(&a->elem[0].u.s, &name_s, decrement,expires,NULL); 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; int val_number=0,i,j; int key_number=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) val_number++; LM_DBG("The query expects %d results back\n",val_number); ret = cachedb_raw_query( &a->elem[0].u.s, &name_s, &cdb_reply,val_number,&key_number); if (ret >= 0 && val_number > 0) { for (i=key_number-1; i>=0;i--) { it=cdb_res; for (j=0;j < val_number;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_INT: 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; 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,val_number,key_number); return -1; } next_avp: if (it) { it = it->next; if (it==NULL); break; } } } free_raw_fetch(cdb_reply,val_number,key_number); } } 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->line) ; if (a->elem[0].type == SCRIPTVAR_ELEM_ST) { if (xdbg(msg, a->elem[0].u.data, val.rs.s) < 0) { LM_ALERT("Cannot print message"); break; } } else { LM_ALERT("BUG in xdbg() type %d\n", a->elem[0].type); ret=E_BUG; } break; case XLOG_T: script_trace("core", "xlog", msg, a->line) ; if (a->elem[1].u.data != NULL) { if (a->elem[1].type != SCRIPTVAR_ELEM_ST) { LM_ALERT("BUG in xlog() type %d\n", a->elem[1].type); ret=E_BUG; break; } if (a->elem[0].type != STR_ST) { LM_ALERT("BUG in xlog() type %d\n", a->elem[0].type); ret=E_BUG; break; } if (xlog_2(msg,a->elem[0].u.data, a->elem[1].u.data) < 0) { LM_ALERT("Cannot print xlog debug message"); break; } } else { if (a->elem[0].type != SCRIPTVAR_ELEM_ST) { LM_ALERT("BUG in xlog() type %d\n", a->elem[0].type); ret=E_BUG; break; } if (xlog_1(msg,a->elem[0].u.data, val.rs.s) < 0) { LM_ALERT("Cannot print xlog debug message"); break; } } break; case RAISE_EVENT_T: script_trace("core", "raise_event", msg, 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->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->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->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->line) ; if (a->elem[0].type!=SCRIPTVAR_ST){ LM_ALERT("BUG in switch() type %d\n", a->elem[0].type); ret=E_BUG; break; } spec = (pv_spec_t*)a->elem[0].u.data; if(pv_get_spec_value(msg, spec, &val)!=0) { LM_ALERT("BUG - no value in switch()\n"); ret=E_BUG; break; } /* get the value of pvar */ if(a->elem[1].type!=ACTIONS_ST) { LM_ALERT("BUG in switch() actions\n"); ret=E_BUG; break; } return_code=1; adefault = NULL; aitem = (struct action*)a->elem[1].u.data; cmatch=0; while(aitem) { if((unsigned char)aitem->type==DEFAULT_T) adefault=aitem; if(cmatch==0) { if(aitem->elem[0].type==STR_ST) { if(val.flags&PV_VAL_STR && val.rs.len==aitem->elem[0].u.s.len && strncasecmp(val.rs.s, aitem->elem[0].u.s.s, val.rs.len)==0) cmatch = 1; } else { /* number */ if(val.flags&PV_VAL_INT && val.ri==aitem->elem[0].u.number) cmatch = 1; } } if(cmatch==1) { if(aitem->elem[1].u.data) { return_code=run_action_list( (struct action*)aitem->elem[1].u.data, msg); if ((action_flags&ACT_FL_RETURN) || (action_flags&ACT_FL_EXIT)) break; } if(aitem->elem[2].u.number==1) break; } aitem = aitem->next; } if((cmatch==0) && (adefault!=NULL)) { LM_DBG("switch: running default statement\n"); if(adefault->elem[0].u.data) return_code=run_action_list( (struct action*)adefault->elem[0].u.data, msg); } ret=return_code; break; case MODULE_T: script_trace("module", ((cmd_export_t*)(a->elem[0].u.data))->name, msg, a->line) ; if ( (a->elem[0].type==CMD_ST) && a->elem[0].u.data ) { ret=((cmd_export_t*)(a->elem[0].u.data))->function(msg, (char*)a->elem[1].u.data, (char*)a->elem[2].u.data, (char*)a->elem[3].u.data, (char*)a->elem[4].u.data, (char*)a->elem[5].u.data, (char*)a->elem[6].u.data); }else{ LM_ALERT("BUG in module call\n"); } break; case FORCE_RPORT_T: script_trace("core", "force_rport", msg, 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->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->line) ; if (a->elem[0].type!=STR_ST){ LM_ALERT("BUG in set_advertised_address() " "type %d\n", a->elem[0].type); ret=E_BUG; break; } str adv_addr; pve = (pv_elem_t *)a->elem[0].u.data; if ( pv_printf_s(msg, pve, &adv_addr)!=0 || adv_addr.len == 0 || adv_addr.s == NULL) { LM_WARN("cannot get string for value\n"); ret=E_BUG; break; } LM_DBG("adv address = [%.*s]\n",adv_addr.len,adv_addr.s); msg->set_global_address=adv_addr; ret=1; /* continue processing */ break; case SET_ADV_PORT_T: script_trace("core", "set_adv_port", msg, a->line) ; if (a->elem[0].type!=STR_ST){ LM_ALERT("BUG in set_advertised_port() " "type %d\n", a->elem[0].type); ret=E_BUG; break; } msg->set_global_port=*((str*)a->elem[0].u.data); ret=1; /* continue processing */ break; #ifdef USE_TCP case FORCE_TCP_ALIAS_T: script_trace("core", "force_tcp_alias", msg, a->line) ; if ( msg->rcv.proto==PROTO_TCP #ifdef USE_TLS || msg->rcv.proto==PROTO_TLS #endif ){ 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_ERR("tcp alias failed\n"); ret=E_UNSPEC; break; } } #endif ret=1; /* continue processing */ break; case FORCE_SEND_SOCKET_T: script_trace("core", "force_send_socket", msg, 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->line) ; if (a->elem[0].type!=NUMBER_ST){ LM_ALERT("BUG in serialize_branches argument" " type: %d\n", a->elem[0].type); ret=E_BUG; break; } if (serialize_branches(msg,(int)a->elem[0].u.number)!=0) { LM_ERR("serialize_branches failed\n"); ret=E_UNSPEC; break; } ret=1; /* continue processing */ break; case NEXT_BRANCHES_T: script_trace("core", "next_branches", msg, a->line) ; if ((ret=next_branches(msg))<0) { LM_ERR("next_branches failed\n"); ret=E_UNSPEC; break; } /* continue processing */ break; case EQ_T: case COLONEQ_T: case PLUSEQ_T: case MINUSEQ_T: case DIVEQ_T: case MULTEQ_T: case MODULOEQ_T: case BANDEQ_T: case BOREQ_T: case BXOREQ_T: ret = do_assign(msg, a); break; case USE_BLACKLIST_T: script_trace("core", "use_blacklist", msg, 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->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->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->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; default: LM_ALERT("BUG - unknown type %d\n", a->type); goto error; } if((unsigned char)a->type!=IF_T && (unsigned char)a->type!=ROUTE_T) return_code = ret; /*skip:*/ update_longest_action(); return ret; error: LM_ERR("error at line: %d\n", a->line); update_longest_action(); return ret; error_uri: LM_ERR("set*: uri too long\n"); if (new_uri) pkg_free(new_uri); update_longest_action(); return E_UNSPEC; error_fwd_uri: update_longest_action(); return ret; }
static int mod_init(void) { pv_spec_t avp_spec; int *param; modparam_t type; // initialize the canonical_uri_avp structure if (canonical_uri_avp.spec.s==NULL || canonical_uri_avp.spec.len<=0) { LOG(L_ERR, "missing/empty canonical_uri_avp parameter. using default.\n"); canonical_uri_avp.spec.s = CANONICAL_URI_AVP_SPEC; } if (pv_parse_spec(&(canonical_uri_avp.spec), &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LOG(L_CRIT, "invalid AVP specification for canonical_uri_avp: `%s'\n", canonical_uri_avp.spec.s); return -1; } if (pv_get_avp_name(0, &(avp_spec.pvp), &(canonical_uri_avp.name), &(canonical_uri_avp.type))!=0) { LOG(L_CRIT, "invalid AVP specification for canonical_uri_avp: `%s'\n", canonical_uri_avp.spec.s); return -1; } // initialize the signaling_ip_avp structure if (signaling_ip_avp.spec.s==NULL || signaling_ip_avp.spec.len<=0) { LOG(L_ERR, "missing/empty signaling_ip_avp parameter. using default.\n"); signaling_ip_avp.spec.s = SIGNALING_IP_AVP_SPEC; } if (pv_parse_spec(&(signaling_ip_avp.spec), &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LOG(L_CRIT, "invalid AVP specification for signaling_ip_avp: `%s'\n", signaling_ip_avp.spec.s); return -1; } if (pv_get_avp_name(0, &(avp_spec.pvp), &(signaling_ip_avp.name), &(signaling_ip_avp.type))!=0) { LOG(L_CRIT, "invalid AVP specification for signaling_ip_avp: `%s'\n", signaling_ip_avp.spec.s); return -1; } // initialize the sip_application_avp structure if (sip_application_avp.spec.s==NULL || sip_application_avp.spec.len<=0) { LOG(L_ERR, "missing/empty sip_application_avp parameter. using default.\n"); sip_application_avp.spec.s = SIP_APPLICATION_AVP_SPEC; } if (pv_parse_spec(&(sip_application_avp.spec), &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LOG(L_CRIT, "invalid AVP specification for sip_application_avp: `%s'\n", sip_application_avp.spec.s); return -1; } if (pv_get_avp_name(0, &(avp_spec.pvp), &(sip_application_avp.name), &(sip_application_avp.type))!=0) { LOG(L_CRIT, "invalid AVP specification for sip_application_avp: `%s'\n", sip_application_avp.spec.s); return -1; } // bind to the dialog API if (load_dlg_api(&dlg_api)!=0) { LOG(L_CRIT, "cannot load the dialog module API\n"); return -1; } // load dlg_flag and default_timeout parameters from the dialog module param = find_param_export(find_module_by_name("dialog"), "dlg_flag", INT_PARAM, &type); if (!param) { LOG(L_CRIT, "cannot find dlg_flag parameter in the dialog module\n"); return -1; } if (type != INT_PARAM) { LOG(L_CRIT, "dlg_flag parameter found but with wrong type: %d\n", type); return -1; } dialog_flag = *param; // register dialog creation callback if (dlg_api.register_dlgcb(NULL, DLGCB_CREATED, __dialog_created, NULL, NULL) != 0) { LOG(L_CRIT, "cannot register callback for dialog creation\n"); return -1; } // register dialog loading callback if (dlg_api.register_dlgcb(NULL, DLGCB_LOADED, __dialog_loaded, NULL, NULL) != 0) { LOG(L_ERR, "cannot register callback for dialogs loaded from the database\n"); } // register a pre-script callback to automatically enable dialog tracing if (register_script_cb(postprocess_request, POST_SCRIPT_CB|REQUEST_CB, 0) != 0) { LOG(L_CRIT, "ERROR:call_control:mod_init: could not register request postprocessing callback\n"); return -1; } return 0; }
static int mod_init(void) { pv_spec_t avp_spec; if (restore_mode_str && *restore_mode_str) { if (strcasecmp(restore_mode_str,"none")==0) { restore_mode = UAC_NO_RESTORE; } else if (strcasecmp(restore_mode_str,"manual")==0) { restore_mode = UAC_MANUAL_RESTORE; } else if (strcasecmp(restore_mode_str,"auto")==0) { restore_mode = UAC_AUTO_RESTORE; } else { LM_ERR("unsupported value '%s' for restore_mode\n", restore_mode_str); goto error; } } if ( (rr_from_param.len==0 || rr_to_param.len==0) && restore_mode!=UAC_NO_RESTORE) { LM_ERR("rr_store_param cannot be empty if FROM is restoreable\n"); goto error; } /* parse the auth AVP spesc, if any */ if ( auth_username_avp || auth_password_avp || auth_realm_avp) { if (!auth_username_avp || !auth_password_avp || !auth_realm_avp) { LM_ERR("partial definition of auth AVP!"); goto error; } if ( parse_auth_avp(auth_realm_avp, &auth_realm_spec, "realm")<0 || parse_auth_avp(auth_username_avp, &auth_username_spec, "username")<0 || parse_auth_avp(auth_password_avp, &auth_password_spec, "password")<0 ) { goto error; } } else { memset( &auth_realm_spec, 0, sizeof(pv_spec_t)); memset( &auth_password_spec, 0, sizeof(pv_spec_t)); memset( &auth_username_spec, 0, sizeof(pv_spec_t)); } /* load the TM API - FIXME it should be loaded only * if NO_RESTORE and AUTH */ if (load_tm_api(&uac_tmb)!=0) { LM_ERR("can't load TM API\n"); goto error; } if (restore_mode!=UAC_NO_RESTORE) { /* load the RR API */ if (load_rr_api(&uac_rrb)!=0) { LM_ERR("can't load RR API\n"); goto error; } if(restore_from_avp.s) { if (pv_parse_spec(&restore_from_avp, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", restore_from_avp.len, restore_from_avp.s); return -1; } if(pv_get_avp_name(0, &avp_spec.pvp, &restore_from_avp_name, &restore_from_avp_type)!=0) { LM_ERR("[%.*s]- invalid AVP definition\n", restore_from_avp.len, restore_from_avp.s); return -1; } restore_from_avp_type |= AVP_VAL_STR; } if(restore_to_avp.s) { if (pv_parse_spec(&restore_to_avp, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", restore_to_avp.len, restore_to_avp.s); return -1; } if(pv_get_avp_name(0, &avp_spec.pvp, &restore_to_avp_name, &restore_to_avp_type)!=0) { LM_ERR("[%.*s]- invalid AVP definition\n", restore_to_avp.len, restore_to_avp.s); return -1; } restore_to_avp_type |= AVP_VAL_STR; } if (restore_mode==UAC_AUTO_RESTORE) { /* we need the append_fromtag on in RR */ memset(&dlg_api, 0, sizeof(struct dlg_binds)); if (uac_restore_dlg==0 || load_dlg_api(&dlg_api)!=0) { if (!uac_rrb.append_fromtag) { LM_ERR("'append_fromtag' RR param is not enabled!" " - required by AUTO restore mode\n"); goto error; } if (uac_restore_dlg!=0) LM_DBG("failed to find dialog API - is dialog module loaded?\n"); } /* get all requests doing loose route */ if (uac_rrb.register_rrcb( rr_checker, 0)!=0) { LM_ERR("failed to install RR callback\n"); goto error; } } } if(reg_db_url.s && reg_db_url.len>=0) { if(!reg_contact_addr.s || reg_contact_addr.len<=0) { LM_ERR("contact address parameter not set\n"); goto error; } if(reg_htable_size>14) reg_htable_size = 14; if(reg_htable_size<2) reg_htable_size = 2; reg_htable_size = 1<<reg_htable_size; if(uac_reg_init_rpc()!=0) { LM_ERR("failed to register RPC commands\n"); goto error; } if(uac_reg_init_ht(reg_htable_size)<0) { LM_ERR("failed to init reg htable\n"); goto error; } register_procs(1); /* add child to update local config framework structures */ cfg_register_child(1); } init_from_replacer(); uac_req_init(); return 0; error: return -1; }
static int mod_init(void) { pv_spec_t avp_spec; str s; LM_INFO("initializing...\n"); if(siptrace_table==0 || strlen(siptrace_table)<=0) { LM_ERR("invalid table name\n"); return -1; } if (flag_idx2mask(&trace_flag)<0) return -1; /* Find a database module */ if (bind_dbmod(db_url, &db_funcs)) { LM_ERR("unable to bind database module\n"); return -1; } if (!DB_CAPABILITY(db_funcs, DB_CAP_INSERT)) { LM_ERR("database modules does not provide all functions needed by module\n"); return -1; } trace_on_flag = (int*)shm_malloc(sizeof(int)); if(trace_on_flag==NULL) { LM_ERR("no more shm memory left\n"); return -1; } *trace_on_flag = trace_on; /* register callbacks to TM */ if (load_tm_api(&tmb)!=0) { LM_ERR("can't load tm api\n"); return -1; } if(tmb.register_tmcb( 0, 0, TMCB_REQUEST_IN, trace_onreq_in, 0) <=0) { LM_ERR("can't register trace_onreq_in\n"); return -1; } /* register sl callback */ register_slcb_f = (register_slcb_t)find_export("register_slcb", 0, 0); if(register_slcb_f==NULL) { LM_ERR("can't load sl api\n"); return -1; } if(register_slcb_f(SLCB_REPLY_OUT,trace_sl_onreply_out, NULL)!=0) { LM_ERR("can't register trace_sl_onreply_out\n"); return -1; } if(register_slcb_f(SLCB_ACK_IN,trace_sl_ack_in, NULL)!=0) { LM_ERR("can't register trace_sl_ack_in\n"); return -1; } if(dup_uri_str.s!=0) { dup_uri_str.len = strlen(dup_uri_str.s); dup_uri = (struct sip_uri *)pkg_malloc(sizeof(struct sip_uri)); if(dup_uri==0) { LM_ERR("no more pkg memory left\n"); return -1; } memset(dup_uri, 0, sizeof(struct sip_uri)); if(parse_uri(dup_uri_str.s, dup_uri_str.len, dup_uri)<0) { LM_ERR("bad dup uri\n"); return -1; } } if(traced_user_avp_str && *traced_user_avp_str) { s.s = traced_user_avp_str; s.len = strlen(s.s); if (pv_parse_spec(&s, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %s AVP definition\n", traced_user_avp_str); return -1; } if(pv_get_avp_name(0, &avp_spec.pvp, &traced_user_avp, &traced_user_avp_type)!=0) { LM_ERR("[%s] - invalid AVP definition\n", traced_user_avp_str); return -1; } } else { traced_user_avp.n = 0; traced_user_avp_type = 0; } if(trace_table_avp_str && *trace_table_avp_str) { s.s = trace_table_avp_str; s.len = strlen(s.s); if (pv_parse_spec(&s, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %s AVP definition\n", trace_table_avp_str); return -1; } if(pv_get_avp_name(0, &avp_spec.pvp, &trace_table_avp, &trace_table_avp_type)!=0) { LM_ERR("[%s] - invalid AVP definition\n", trace_table_avp_str); return -1; } } else { trace_table_avp.n = 0; trace_table_avp_type = 0; } return 0; }
/** Module init function */ static int mod_init(void) { char* p = NULL; char* flags = NULL; int regexp_flags = 0; int i = 0, j; pv_spec_t avp_spec; LM_DBG("start\n"); /* load b2b_entities api */ if(load_b2b_api(&b2b_api)< 0) { LM_ERR("Failed to load b2b api\n"); return -1; } if(b2bl_hsize< 1 || b2bl_hsize> 20) { LM_ERR("Wrong hash size. Needs to be greater than 1" " and smaller than 20. Be aware that you should set the log 2" " value of the real size\n"); return -1; } b2bl_hsize = 1<<b2bl_hsize; if(server_address.s == NULL) { if(extern_scenarios) { LM_ERR("'server_address' parameter not set. This parameter is" " compulsory if you want to use extern scenarios. It must" " be set to the IP address of the machine\n"); return -1; } } else server_address.len = strlen(server_address.s); if(init_b2bl_htable() < 0) { LM_ERR("Failed to initialize b2b logic hash table\n"); return -1; } if(b2b_clean_period < 0) { LM_ERR("Wrong parameter - b2b_clean_period [%d]\n", b2b_clean_period); return -1; } if(b2b_update_period < 0) { LM_ERR("Wrong parameter - b2b_update_period [%d]\n", b2b_update_period); return -1; } if(b2bl_db_mode && db_url.s) { db_url.len = strlen(db_url.s); b2bl_dbtable.len = strlen(b2bl_dbtable.s); /* binding to database module */ if (db_bind_mod(&db_url, &b2bl_dbf)) { LM_ERR("Database module not found\n"); return -1; } if (!DB_CAPABILITY(b2bl_dbf, DB_CAP_ALL)) { LM_ERR("Database module does not implement all functions" " needed by b2b_entities module\n"); return -1; } b2bl_db = b2bl_dbf.init(&db_url); if(!b2bl_db) { LM_ERR("connecting to database failed\n"); return -1; } /*verify table versions */ if(db_check_table_version(&b2bl_dbf, b2bl_db, &b2bl_dbtable, TABLE_VERSION) < 0) { LM_ERR("error during table version check\n"); return -1; } b2bl_db_init(); /* reload data */ if(b2b_logic_restore() < 0) { LM_ERR("Failed to restore data from database\n"); return -1; } if(b2bl_db) b2bl_dbf.close(b2bl_db); b2bl_db = NULL; } else b2bl_db_mode = 0; if (b2bl_key_avp_param.s) b2bl_key_avp_param.len = strlen(b2bl_key_avp_param.s); if (b2bl_key_avp_param.s && b2bl_key_avp_param.len > 0) { if (pv_parse_spec(&b2bl_key_avp_param, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", b2bl_key_avp_param.len, b2bl_key_avp_param.s); return -1; } if (pv_get_avp_name(0, &(avp_spec.pvp), &b2bl_key_avp_name, &b2bl_key_avp_type)!=0){ LM_ERR("[%.*s]- invalid AVP definition\n", b2bl_key_avp_param.len, b2bl_key_avp_param.s); return -1; } } else { b2bl_key_avp_name = -1; b2bl_key_avp_type = 0; } if(b2bl_from_spec_param.s) { b2bl_from_spec_param.len = strlen(b2bl_from_spec_param.s); if(pv_parse_spec(&b2bl_from_spec_param, &b2bl_from_spec)==NULL) { LM_ERR("failed to parse b2bl_from spec\n"); return E_CFG; } switch(b2bl_from_spec.type) { case PVT_NONE: case PVT_EMPTY: case PVT_NULL: case PVT_MARKER: case PVT_COLOR: LM_ERR("invalid b2bl_from spec\n"); return -1; default: ; } } /* parse extra headers */ if(custom_headers.s) custom_headers.len = strlen(custom_headers.s); memset(custom_headers_lst, 0, HDR_LST_LEN*sizeof(str)); custom_headers_lst[i].s = custom_headers.s; if(custom_headers.s) { p = strchr(custom_headers.s, ';'); while(p) { custom_headers_lst[i].len = p - custom_headers_lst[i].s; /* check if this is among the default headers */ for(j = 0; j< HDR_DEFAULT_LEN; j++) { if(custom_headers_lst[i].len == default_headers[j].len && strncmp(custom_headers_lst[i].s, default_headers[j].s, default_headers[j].len)== 0) goto next_hdr; } /* check if defined twice */ for(j = 0; j< i; j++) { if(custom_headers_lst[i].len == custom_headers_lst[j].len && strncmp(custom_headers_lst[i].s, custom_headers_lst[j].s, custom_headers_lst[j].len)== 0) goto next_hdr; } i++; if(i == HDR_LST_LEN) { LM_ERR("Too many extra headers defined." " The maximum value is %d\n.", HDR_LST_LEN); return -1; } next_hdr: p++; if(p-custom_headers.s >= custom_headers.len) break; custom_headers_lst[i].s = p; p = strchr(p, ';'); } } if(p == NULL) { custom_headers_lst[i].len = custom_headers.s + custom_headers.len - custom_headers_lst[i].s; if(custom_headers_lst[i].len == 0) i--; } custom_headers_lst_len = i +1; if(custom_headers_regexp.s) { custom_headers_regexp.len = strlen(custom_headers_regexp.s); if ((custom_headers_re=pkg_malloc(sizeof(regex_t)))==0) { LM_ERR("no more pkg memory\n"); return -1; } if (*custom_headers_regexp.s == '/') { flags = (char *)memchr(custom_headers_regexp.s+1, '/', custom_headers_regexp.len-1); if (flags) { custom_headers_regexp.s++; custom_headers_regexp.len = flags - custom_headers_regexp.s; custom_headers_regexp.s[custom_headers_regexp.len] = '\0'; flags++; while(*flags != '\0') { switch (*flags) { case 'i': regexp_flags |= REG_ICASE; break; case 'e': regexp_flags |= REG_EXTENDED; break; default: LM_ERR("Unknown option '%c'\n", *flags); } flags++; } } else { LM_ERR("Second '/' missing from regexp\n"); return -1; } } if (regcomp(custom_headers_re, custom_headers_regexp.s, regexp_flags) != 0) { pkg_free(custom_headers_re); LM_ERR("bad regexp '%.*s'\n", custom_headers_regexp.len, custom_headers_regexp.s); return -1; } } if(init_callid_hdr.s) init_callid_hdr.len = strlen(init_callid_hdr.s); register_timer("b2bl-clean", b2bl_clean, 0, b2b_clean_period, TIMER_FLAG_DELAY_ON_DELAY); if(b2bl_db_mode == WRITE_BACK) register_timer("b2bl-dbupdate", b2bl_db_timer_update, 0, b2b_update_period, TIMER_FLAG_SKIP_ON_DELAY); return 0; }
int exec_avp(struct sip_msg *msg, char *cmd, pvname_list_p avpl) { int_str avp_val; int_str avp_name; unsigned short avp_type; FILE *pipe; int ret; char res_line[MAX_URI_SIZE+1]; str res; int exit_status; int i; pvname_list_t* crt; pid_t pid; /* pessimist: assume error by default */ ret=-1; pid = __popen3(cmd, NULL, &pipe, NULL); if (pid < 0) { LM_ERR("failed to run command: %s\n", cmd); ser_error=E_EXEC; return ret; } LM_DBG("Forked pid %d\n", pid); schedule_to_kill(pid); wait(&exit_status); /* read now line by line */ i=0; crt = avpl; while (fgets(res_line, MAX_URI_SIZE, pipe)) { res.s = res_line; res.len=strlen(res.s); trim_trailing(&res); /* skip empty line */ if (res.len==0) continue; /* ZT */ res.s[res.len]=0; avp_type = 0; if(crt==NULL) { avp_name.s.s = int2str(i + 1, &avp_name.s.len); if (!avp_name.s.s) { LM_ERR("cannot convert %d to string\n", i + 1); goto error; } avp_name.n = get_avp_id(&avp_name.s); if (avp_name.n < 0) { LM_ERR("cannot get avp id\n"); goto error; } } else { if(pv_get_avp_name(msg, &(crt->sname.pvp), &avp_name.n, &avp_type)!=0) { LM_ERR("can't get item name [%d]\n",i); goto error; } } avp_type |= AVP_VAL_STR; avp_val.s = res; if(add_avp(avp_type, avp_name.n, avp_val)!=0) { LM_ERR("unable to add avp\n"); goto error; } if(crt) crt = crt->next; i++; } if (i==0) LM_DBG("no result from %s\n", cmd); /* success */ ret=1; error: if (ferror(pipe)) { LM_ERR("pipe: %d/%s\n", errno, strerror(errno)); ser_error=E_EXEC; ret=-1; } pclose(pipe); if (WIFEXITED(exit_status)) { /* exited properly .... */ /* return false if script exited with non-zero status */ if (WEXITSTATUS(exit_status)!=0) ret=-1; } else { /* exited erroneously */ LM_ERR("cmd %s failed. exit_status=%d, errno=%d: %s\n", cmd, exit_status, errno, strerror(errno) ); ret=-1; } return ret; }
int h350_auth_lookup( struct sip_msg* _msg, pv_elem_t* _digest_username, struct h350_auth_lookup_avp_params* _avp_specs) { str digest_username, digest_username_escaped, digest_password; static char digest_username_buf[DIGEST_USERNAME_BUF_SIZE]; struct berval **attr_vals = NULL; int username_avp_name, password_avp_name; int_str avp_val; unsigned short username_avp_type, password_avp_type; int rc, ld_result_count; /* * get digest_username str */ if (_digest_username) { if (pv_printf_s(_msg, _digest_username, &digest_username) != 0) { LM_ERR("pv_printf_s failed\n"); return E_H350_INTERNAL; } } else { LM_ERR("empty digest username\n"); return E_H350_NO_SUCCESS; } /* * get AVP names for username and password */ if (pv_get_avp_name( _msg, &(_avp_specs->username_avp_spec.pvp), &username_avp_name, &username_avp_type) != 0) { LM_ERR("error getting AVP name - pv_get_avp_name failed\n"); return E_H350_INTERNAL; } if (pv_get_avp_name(_msg, &(_avp_specs->password_avp_spec.pvp), &password_avp_name, &password_avp_type) != 0) { LM_ERR("error getting AVP name - pv_get_avp_name failed\n"); return E_H350_INTERNAL; } /* * search for sip digest username in H.350, store digest password */ /* ldap filter escape digest username */ digest_username_escaped.s = digest_username_buf; digest_username_escaped.len = DIGEST_USERNAME_BUF_SIZE - 1; if (ldap_api.ldap_rfc4515_escape( &digest_username, &digest_username_escaped, 0) ) { LM_ERR("ldap_rfc4515_escape() failed\n"); return E_H350_INTERNAL; } /* do ldap search */ if (ldap_api.ldap_params_search(&ld_result_count, h350_ldap_session.s, h350_base_dn.s, h350_search_scope_int, NULL, H350_AUTH_FILTER_PATTERN, digest_username_escaped.s) != 0) { LM_ERR("LDAP search failed\n"); return E_H350_INTERNAL; } if (ld_result_count < 1) { LM_INFO("no H.350 entry found for username [%s]\n", digest_username_escaped.s); return E_H350_NO_SUCCESS; } if (ld_result_count > 1) { LM_WARN("more than one [%d] H.350 entry found for username [%s]\n", ld_result_count, digest_username_escaped.s); } /* get ldap result values */ rc = ldap_api.ldap_result_attr_vals(&h350_sip_pwd_name, &attr_vals); if (rc < 0) { LM_ERR("getting LDAP attribute values failed\n"); ldap_api.ldap_value_free_len(attr_vals); return E_H350_INTERNAL; } if ((rc > 0) || (attr_vals == NULL)) { LM_INFO("no values found in LDAP entry for username [%s]\n", digest_username_escaped.s); ldap_api.ldap_value_free_len(attr_vals); return E_H350_INTERNAL; } digest_password.s = attr_vals[0]->bv_val; digest_password.len = attr_vals[0]->bv_len; /* * write AVPs */ avp_val.s = digest_username; if (add_avp( username_avp_type | AVP_VAL_STR, username_avp_name, avp_val) < 0) { LM_ERR("failed to create new AVP\n"); ldap_api.ldap_value_free_len(attr_vals); return E_H350_INTERNAL; } avp_val.s = digest_password; if (add_avp( password_avp_type | AVP_VAL_STR, password_avp_name, avp_val) < 0) { LM_ERR("failed to create new AVP\n"); ldap_api.ldap_value_free_len(attr_vals); return E_H350_INTERNAL; } ldap_api.ldap_value_free_len(attr_vals); return E_H350_SUCCESS; }
int w_insert_avp(struct sip_msg* msg, char* name, char* value, char *index_char) { int index = *(int*)index_char; int avp_name; struct usr_avp *avp= NULL, *prev_avp= NULL; struct usr_avp *avp_new; unsigned short name_type; pv_value_t xvalue; int flags = 0; int_str avp_val; pv_elem_t* pv_dest = (pv_elem_t*)name; pv_elem_t* pv_src = (pv_elem_t*)value; /* get avp name */ if(pv_get_avp_name(msg, &pv_dest->spec.pvp, &avp_name, &name_type)< 0) { LM_ERR("failed to get src AVP name\n"); return -1; } /* get value to be inserted */ avp = NULL; flags = 0; if(pv_src->spec.type == PVT_NONE) { avp_val.s = pv_src->text; flags = AVP_VAL_STR; } else { if(pv_get_spec_value(msg, &(pv_src->spec), &xvalue)!=0) { LM_ERR("cannot get src value\n"); return -1; } if(xvalue.flags&PV_TYPE_INT) { avp_val.n = xvalue.ri; } else { flags = AVP_VAL_STR; avp_val.s = xvalue.rs; } } name_type |= flags; /* insert it at the right place */ if(index == 0) { if(add_avp(name_type, avp_name, avp_val) < 0) { LM_ERR("Failed to add new avp\n"); return -1; } return 1; } /* search the previous avp */ index--; avp = NULL; while ( (avp=search_first_avp( name_type, avp_name, 0, avp))!=0 ) { if( index == 0 ) { break; } index--; prev_avp = avp; } /* if the index is greater then the count */ if(avp == NULL) { if(prev_avp == NULL) { if(add_avp(name_type, avp_name, avp_val) < 0) { LM_ERR("Failed to add new avp\n"); return -1; } return 1; } avp = prev_avp; } /* if a previous record was found -> insert the new avp after it */ avp_new = new_avp(name_type, avp_name, avp_val); if(avp_new == NULL) { LM_ERR("Failed to allocate new avp structure\n"); return -1; } LM_DBG("am alocat un avp nou\n"); avp_new->next = avp->next; avp->next = avp_new; return 1; }
int mt_match_prefix(struct sip_msg *msg, m_tree_t *it, str *tomatch, int mode) { int l, len, n; int i, j; mt_node_t *itn; is_t *tvalue; int_str dstid_avp_name; unsigned short dstid_name_type; int_str weight_avp_name; unsigned short weight_name_type; int_str avp_value; mt_dw_t *dw; pv_value_t val; #define MT_MAX_DST_LIST 64 unsigned int tmp_list[2*(MT_MAX_DST_LIST+1)]; if(it==NULL || tomatch == NULL || tomatch->s == NULL) { LM_ERR("bad parameters\n"); return -1; } l = len = 0; n = 0; if ((it->type==MT_TREE_SVAL) || (it->type==MT_TREE_IVAL)) { if (mode == 2) return mt_add_tvalues(msg, it, tomatch); tvalue = mt_get_tvalue(it, tomatch); if (tvalue == NULL) { LM_DBG("no match for: %.*s\n", tomatch->len, tomatch->s); return -1; } memset(&val, 0, sizeof(pv_value_t)); if (it->type==MT_TREE_SVAL) { val.flags = PV_VAL_STR; val.rs = tvalue->s; if(pv_value.setf(msg, &pv_value.pvp, (int)EQ_T, &val)<0) { LM_ERR("setting PV failed\n"); return -2; } } else { val.flags = PV_VAL_INT; val.ri = tvalue->n; if(pv_value.setf(msg, &pv_value.pvp, (int)EQ_T, &val)<0) { LM_ERR("setting PV failed\n"); return -2; } } return 0; } if(it->type!=MT_TREE_DW) return -1; /* wrong tree type */ if(pv_get_avp_name(msg, &pv_dstid.pvp, &dstid_avp_name, &dstid_name_type)<0) { LM_ERR("cannot get dstid avp name\n"); return -1; } if(pv_get_avp_name(msg, &pv_weight.pvp, &weight_avp_name, &weight_name_type)<0) { LM_ERR("cannot get weight avp name\n"); return -1; } itn = it->head; memset(tmp_list, 0, sizeof(unsigned int)*2*(MT_MAX_DST_LIST+1)); while(itn!=NULL && l < tomatch->len && l < MT_MAX_DEPTH) { /* check validity */ if(_mt_char_table[(unsigned int)tomatch->s[l]]==255) { LM_ERR("invalid char at %d in [%.*s]\n", l, tomatch->len, tomatch->s); return -1; } if(itn[_mt_char_table[(unsigned int)tomatch->s[l]]].tvalues!=NULL) { dw = (mt_dw_t*)itn[_mt_char_table[(unsigned int)tomatch->s[l]]].data; while(dw) { tmp_list[2*n]=dw->dstid; tmp_list[2*n+1]=dw->weight; n++; if(n==MT_MAX_DST_LIST) break; dw = dw->next; } len = l+1; } if(n==MT_MAX_DST_LIST) break; itn = itn[_mt_char_table[(unsigned int)tomatch->s[l]]].child; l++; } if(n==0) return -1; /* no match */ /* invalidate duplicated dstid, keeping longest match */ for(i=(n-1); i>0; i--) { if (tmp_list[2*i]!=0) { for(j=0; j<i; j++) if(tmp_list[2*i]==tmp_list[2*j]) tmp_list[2*j] = 0; } } /* sort the table -- bubble sort -- reverse order */ for (i = (n - 1); i >= 0; i--) { for (j = 1; j <= i; j++) { if (tmp_list[2*(j-1)+1] < tmp_list[2*j+1]) { tmp_list[2*MT_MAX_DST_LIST] = tmp_list[2*(j-1)]; tmp_list[2*MT_MAX_DST_LIST+1] = tmp_list[2*(j-1)+1]; tmp_list[2*(j-1)] = tmp_list[2*j]; tmp_list[2*(j-1)+1] = tmp_list[2*j+1]; tmp_list[2*j] = tmp_list[2*MT_MAX_DST_LIST]; tmp_list[2*j+1] = tmp_list[2*MT_MAX_DST_LIST+1]; } } } /* add as avp */ for(i=0; i<n; i++) { if(tmp_list[2*i]!=0) { avp_value.n = (int)tmp_list[2*i+1]; add_avp(weight_name_type, weight_avp_name, avp_value); avp_value.n = (int)tmp_list[2*i]; add_avp(dstid_name_type, dstid_avp_name, avp_value); } } return 0; }
int ldap_write_result( struct sip_msg* _msg, struct ldap_result_params* _lrp, struct subst_expr* _se) { int dst_avp_name; int_str dst_avp_val; unsigned short dst_avp_type; int nmatches, rc, i, added_avp_count = 0; struct berval **attr_vals; str avp_val_str, *subst_result = NULL; int avp_val_int; /* * get dst AVP name (dst_avp_name) */ if (pv_get_avp_name( _msg, &(_lrp->dst_avp_spec.pvp), &dst_avp_name, &dst_avp_type) != 0) { LM_ERR("error getting dst AVP name\n"); return -2; } /* * get LDAP attr values */ if ((rc = ldap_get_attr_vals(&_lrp->ldap_attr_name, &attr_vals)) != 0) { if (rc > 0) { return -1; } else { return -2; } } /* * add AVPs */ for (i = 0; attr_vals[i] != NULL; i++) { if (_se == NULL) { avp_val_str.s = attr_vals[i]->bv_val; avp_val_str.len = attr_vals[i]->bv_len; } else { subst_result = subst_str(attr_vals[i]->bv_val, _msg, _se, &nmatches); if ((subst_result == NULL) || (nmatches < 1)) { continue; } avp_val_str = *subst_result; } if (_lrp->dst_avp_val_type == 1) { /* try to convert ldap value to integer */ if (!str2sint(&avp_val_str, &avp_val_int)) { dst_avp_val.n = avp_val_int; rc = add_avp(dst_avp_type, dst_avp_name, dst_avp_val); } else { continue; } } else { /* save ldap value as string */ dst_avp_val.s = avp_val_str; rc = add_avp(dst_avp_type|AVP_VAL_STR, dst_avp_name, dst_avp_val); } if (subst_result != NULL) { if (subst_result->s != 0) { pkg_free(subst_result->s); } pkg_free(subst_result); subst_result = NULL; } if (rc < 0) { LM_ERR("failed to create new AVP\n"); ldap_value_free_len(attr_vals); return -2; } added_avp_count++; } ldap_value_free_len(attr_vals); if (added_avp_count > 0) { return added_avp_count; } else { return -1; } }
static int mod_init(void) { pv_spec_t avp_spec; str s; bind_usrloc_t bind_usrloc; qvalue_t dq; callback_singleton = shm_malloc(sizeof (int)); *callback_singleton = 0; /*build the required strings */ scscf_serviceroute_uri_str.s = (char*) pkg_malloc(orig_prefix.len + scscf_name_str.len); if (!scscf_serviceroute_uri_str.s) { LM_ERR("Unable to allocate memory for service route uri\n"); return -1; } if (contact_expires_buffer_percentage < 0 || contact_expires_buffer_percentage > 90) { LM_ERR("contact expires percentage not valid, must be >0 and <=90"); return -1; } memcpy(scscf_serviceroute_uri_str.s, orig_prefix.s, orig_prefix.len); scscf_serviceroute_uri_str.len = orig_prefix.len; if (scscf_name_str.len > 4 && strncasecmp(scscf_name_str.s, "sip:", 4) == 0) { memcpy(scscf_serviceroute_uri_str.s + scscf_serviceroute_uri_str.len, scscf_name_str.s + 4, scscf_name_str.len - 4); scscf_serviceroute_uri_str.len += scscf_name_str.len - 4; } else { memcpy(scscf_serviceroute_uri_str.s + scscf_serviceroute_uri_str.len, scscf_name_str.s, scscf_name_str.len); scscf_serviceroute_uri_str.len += scscf_name_str.len; } pv_tmx_data_init(); /* </build required strings> */ #ifdef STATISTICS /* register statistics */ if (register_module_stats(exports.name, mod_stats) != 0) { LM_ERR("failed to register core statistics\n"); return -1; } if (!register_stats()) { LM_ERR("Unable to register statistics\n"); return -1; } #endif /*register space for notification processors*/ register_procs(notification_processes); cfg_register_child(notification_processes); /* bind the SL API */ if (sl_load_api(&slb) != 0) { LM_ERR("cannot bind to SL API\n"); return -1; } /* load the TM API */ if (load_tm_api(&tmb) != 0) { LM_ERR("can't load TM API\n"); return -1; } /* load the CDP API */ if (load_cdp_api(&cdpb) != 0) { LM_ERR("can't load CDP API\n"); return -1; } cdp_avp = load_cdp_avp(); if (!cdp_avp) { LM_ERR("can't load CDP_AVP API\n"); return -1; } if (cfg_declare("registrar", registrar_cfg_def, &default_registrar_cfg, cfg_sizeof(registrar), ®istrar_cfg)) { LM_ERR("Fail to declare the configuration\n"); return -1; } if (rcv_avp_param && *rcv_avp_param) { s.s = rcv_avp_param; s.len = strlen(s.s); if (pv_parse_spec(&s, &avp_spec) == 0 || avp_spec.type != PVT_AVP) { LM_ERR("malformed or non AVP %s AVP definition\n", rcv_avp_param); return -1; } if (pv_get_avp_name(0, &avp_spec.pvp, &rcv_avp_name, &rcv_avp_type) != 0) { LM_ERR("[%s]- invalid AVP definition\n", rcv_avp_param); return -1; } } else { rcv_avp_name.n = 0; rcv_avp_type = 0; } if (aor_avp_param && *aor_avp_param) { s.s = aor_avp_param; s.len = strlen(s.s); if (pv_parse_spec(&s, &avp_spec) == 0 || avp_spec.type != PVT_AVP) { LM_ERR("malformed or non AVP %s AVP definition\n", aor_avp_param); return -1; } if (pv_get_avp_name(0, &avp_spec.pvp, &aor_avp_name, &aor_avp_type) != 0) { LM_ERR("[%s]- invalid AVP definition\n", aor_avp_param); return -1; } } else { aor_avp_name.n = 0; aor_avp_type = 0; } if (reg_callid_avp_param && *reg_callid_avp_param) { s.s = reg_callid_avp_param; s.len = strlen(s.s); if (pv_parse_spec(&s, &avp_spec) == 0 || avp_spec.type != PVT_AVP) { LM_ERR("malformed or non AVP %s AVP definition\n", reg_callid_avp_param); return -1; } if (pv_get_avp_name(0, &avp_spec.pvp, ®_callid_avp_name, ®_callid_avp_type) != 0) { LM_ERR("[%s]- invalid AVP definition\n", reg_callid_avp_param); return -1; } } else { reg_callid_avp_name.n = 0; reg_callid_avp_type = 0; } bind_usrloc = (bind_usrloc_t) find_export("ul_bind_usrloc", 1, 0); if (!bind_usrloc) { LM_ERR("can't bind usrloc\n"); return -1; } /* Normalize default_q parameter */ dq = cfg_get(registrar, registrar_cfg, default_q); if (dq != Q_UNSPECIFIED) { if (dq > MAX_Q) { LM_DBG("default_q = %d, lowering to MAX_Q: %d\n", dq, MAX_Q); dq = MAX_Q; } else if (dq < MIN_Q) { LM_DBG("default_q = %d, raising to MIN_Q: %d\n", dq, MIN_Q); dq = MIN_Q; } } cfg_get(registrar, registrar_cfg, default_q) = dq; if (bind_usrloc(&ul) < 0) { return -1; } /*Register for callback of URECORD being deleted - so we can send a SAR*/ if (ul.register_ulcb == NULL) { LM_ERR("Could not import ul_register_ulcb\n"); return -1; } if (ul.register_ulcb(0, 0, UL_IMPU_INSERT, ul_impu_inserted, 0) < 0) { LM_ERR("can not register callback for insert\n"); return -1; } if (sock_hdr_name.s) { if (sock_hdr_name.len == 0 || sock_flag == -1) { LM_WARN("empty sock_hdr_name or sock_flag no set -> reseting\n"); sock_hdr_name.len = 0; sock_flag = -1; } } else if (sock_flag != -1) { LM_WARN("sock_flag defined but no sock_hdr_name -> reseting flag\n"); sock_flag = -1; } /* fix the flags */ sock_flag = (sock_flag != -1) ? (1 << sock_flag) : 0; tcp_persistent_flag = (tcp_persistent_flag != -1) ? (1 << tcp_persistent_flag) : 0; /* init the registrar notifications */ if (!notify_init()) return -1; /* register the registrar notifications timer */ //Currently we do not use this - we send notifies immediately //if (register_timer(notification_timer, notification_list, 5) < 0) return -1; return 0; }
/** * init module function */ static int mod_init(void) { pv_spec_t avp_spec; if(register_mi_mod(exports.name, mi_cmds)!=0) { LM_ERR("failed to register MI commands\n"); return -1; } if(ds_init_rpc()<0) { LM_ERR("failed to register RPC commands\n"); return -1; } if (dst_avp_param.s) dst_avp_param.len = strlen(dst_avp_param.s); if (grp_avp_param.s) grp_avp_param.len = strlen(grp_avp_param.s); if (cnt_avp_param.s) cnt_avp_param.len = strlen(cnt_avp_param.s); if (dstid_avp_param.s) dstid_avp_param.len = strlen(dstid_avp_param.s); if (attrs_avp_param.s) attrs_avp_param.len = strlen(attrs_avp_param.s); if (hash_pvar_param.s) hash_pvar_param.len = strlen(hash_pvar_param.s); if (ds_setid_pvname.s) ds_setid_pvname.len = strlen(ds_setid_pvname.s); if (ds_attrs_pvname.s) ds_attrs_pvname.len = strlen(ds_attrs_pvname.s); if (ds_ping_from.s) ds_ping_from.len = strlen(ds_ping_from.s); if (ds_ping_method.s) ds_ping_method.len = strlen(ds_ping_method.s); if (ds_outbound_proxy.s) ds_outbound_proxy.len = strlen(ds_outbound_proxy.s); if(cfg_declare("dispatcher", dispatcher_cfg_def, &default_dispatcher_cfg, cfg_sizeof(dispatcher), &dispatcher_cfg)){ LM_ERR("Fail to declare the configuration\n"); return -1; } /* Initialize the counter */ ds_ping_reply_codes = (int**)shm_malloc(sizeof(unsigned int*)); *ds_ping_reply_codes = 0; ds_ping_reply_codes_cnt = (int*)shm_malloc(sizeof(int)); *ds_ping_reply_codes_cnt = 0; if(ds_ping_reply_codes_str.s) { ds_ping_reply_codes_str.len = strlen(ds_ping_reply_codes_str.s); cfg_get(dispatcher, dispatcher_cfg, ds_ping_reply_codes_str) = ds_ping_reply_codes_str; if(ds_parse_reply_codes()< 0) { return -1; } } /* Copy Threshhold to Config */ cfg_get(dispatcher, dispatcher_cfg, probing_threshhold) = probing_threshhold; if(init_data()!= 0) return -1; if(ds_db_url.s) { ds_db_url.len = strlen(ds_db_url.s); ds_table_name.len = strlen(ds_table_name.s); ds_set_id_col.len = strlen(ds_set_id_col.s); ds_dest_uri_col.len = strlen(ds_dest_uri_col.s); ds_dest_flags_col.len = strlen(ds_dest_flags_col.s); ds_dest_priority_col.len = strlen(ds_dest_priority_col.s); ds_dest_attrs_col.len = strlen(ds_dest_attrs_col.s); if(init_ds_db()!= 0) { LM_ERR("could not initiate a connect to the database\n"); return -1; } } else { if(ds_load_list(dslistfile)!=0) { LM_ERR("no dispatching list loaded from file\n"); return -1; } else { LM_DBG("loaded dispatching list\n"); } } if (dst_avp_param.s && dst_avp_param.len > 0) { if (pv_parse_spec(&dst_avp_param, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", dst_avp_param.len, dst_avp_param.s); return -1; } if(pv_get_avp_name(0, &(avp_spec.pvp), &dst_avp_name, &dst_avp_type)!=0) { LM_ERR("[%.*s]- invalid AVP definition\n", dst_avp_param.len, dst_avp_param.s); return -1; } } else { dst_avp_name.n = 0; dst_avp_type = 0; } if (grp_avp_param.s && grp_avp_param.len > 0) { if (pv_parse_spec(&grp_avp_param, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", grp_avp_param.len, grp_avp_param.s); return -1; } if(pv_get_avp_name(0, &(avp_spec.pvp), &grp_avp_name, &grp_avp_type)!=0) { LM_ERR("[%.*s]- invalid AVP definition\n", grp_avp_param.len, grp_avp_param.s); return -1; } } else { grp_avp_name.n = 0; grp_avp_type = 0; } if (cnt_avp_param.s && cnt_avp_param.len > 0) { if (pv_parse_spec(&cnt_avp_param, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", cnt_avp_param.len, cnt_avp_param.s); return -1; } if(pv_get_avp_name(0, &(avp_spec.pvp), &cnt_avp_name, &cnt_avp_type)!=0) { LM_ERR("[%.*s]- invalid AVP definition\n", cnt_avp_param.len, cnt_avp_param.s); return -1; } } else { cnt_avp_name.n = 0; cnt_avp_type = 0; } if (dstid_avp_param.s && dstid_avp_param.len > 0) { if (pv_parse_spec(&dstid_avp_param, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", dstid_avp_param.len, dstid_avp_param.s); return -1; } if(pv_get_avp_name(0, &(avp_spec.pvp), &dstid_avp_name, &dstid_avp_type)!=0) { LM_ERR("[%.*s]- invalid AVP definition\n", dstid_avp_param.len, dstid_avp_param.s); return -1; } } else { dstid_avp_name.n = 0; dstid_avp_type = 0; } if (attrs_avp_param.s && attrs_avp_param.len > 0) { if (pv_parse_spec(&attrs_avp_param, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", attrs_avp_param.len, attrs_avp_param.s); return -1; } if(pv_get_avp_name(0, &(avp_spec.pvp), &attrs_avp_name, &attrs_avp_type)!=0) { LM_ERR("[%.*s]- invalid AVP definition\n", attrs_avp_param.len, attrs_avp_param.s); return -1; } } else { attrs_avp_name.n = 0; attrs_avp_type = 0; } if (hash_pvar_param.s && *hash_pvar_param.s) { if(pv_parse_format(&hash_pvar_param, &hash_param_model) < 0 || hash_param_model==NULL) { LM_ERR("malformed PV string: %s\n", hash_pvar_param.s); return -1; } } else { hash_param_model = NULL; } if(ds_setid_pvname.s!=0) { if(pv_parse_spec(&ds_setid_pvname, &ds_setid_pv)==NULL || !pv_is_w(&ds_setid_pv)) { LM_ERR("[%s]- invalid setid_pvname\n", ds_setid_pvname.s); return -1; } } if(ds_attrs_pvname.s!=0) { if(pv_parse_spec(&ds_attrs_pvname, &ds_attrs_pv)==NULL || !pv_is_w(&ds_attrs_pv)) { LM_ERR("[%s]- invalid attrs_pvname\n", ds_attrs_pvname.s); return -1; } } if (dstid_avp_param.s && dstid_avp_param.len > 0) { if(ds_hash_size>0) { if(ds_hash_load_init(1<<ds_hash_size, ds_hash_expire, ds_hash_initexpire)<0) return -1; register_timer(ds_ht_timer, NULL, ds_hash_check_interval); } else { LM_ERR("call load dispatching DSTID_AVP set but no size" " for hash table\n"); return -1; } } /* Only, if the Probing-Timer is enabled the TM-API needs to be loaded: */ if (ds_ping_interval > 0) { /***************************************************** * TM-Bindings *****************************************************/ if (load_tm_api( &tmb ) == -1) { LM_ERR("could not load the TM-functions - disable DS ping\n"); return -1; } /***************************************************** * Register the PING-Timer *****************************************************/ register_timer(ds_check_timer, NULL, ds_ping_interval); } return 0; }
/*! \brief * Initialize parent */ static int mod_init(void) { pv_spec_t avp_spec; str s; bind_usrloc_t bind_usrloc; qvalue_t dq; if(sruid_init(&_reg_sruid, '-', "uloc", SRUID_INC)<0) return -1; #ifdef STATISTICS /* register statistics */ if (register_module_stats( exports.name, mod_stats)!=0 ) { LM_ERR("failed to register core statistics\n"); return -1; } #endif /* bind the SL API */ if (sl_load_api(&slb)!=0) { LM_ERR("cannot bind to SL API\n"); return -1; } if(cfg_declare("registrar", registrar_cfg_def, &default_registrar_cfg, cfg_sizeof(registrar), ®istrar_cfg)){ LM_ERR("Fail to declare the configuration\n"); return -1; } if (rcv_avp_param && *rcv_avp_param) { s.s = rcv_avp_param; s.len = strlen(s.s); if (pv_parse_spec(&s, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %s AVP definition\n", rcv_avp_param); return -1; } if(pv_get_avp_name(0, &avp_spec.pvp, &rcv_avp_name, &rcv_avp_type)!=0) { LM_ERR("[%s]- invalid AVP definition\n", rcv_avp_param); return -1; } } else { rcv_avp_name.n = 0; rcv_avp_type = 0; } if (reg_callid_avp_param && *reg_callid_avp_param) { s.s = reg_callid_avp_param; s.len = strlen(s.s); if (pv_parse_spec(&s, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %s AVP definition\n", reg_callid_avp_param); return -1; } if(pv_get_avp_name(0, &avp_spec.pvp, ®_callid_avp_name, ®_callid_avp_type)!=0) { LM_ERR("[%s]- invalid AVP definition\n", reg_callid_avp_param); return -1; } } else { reg_callid_avp_name.n = 0; reg_callid_avp_type = 0; } bind_usrloc = (bind_usrloc_t)find_export("ul_bind_usrloc", 1, 0); if (!bind_usrloc) { LM_ERR("can't bind usrloc\n"); return -1; } /* Normalize default_q parameter */ dq = cfg_get(registrar, registrar_cfg, default_q); if ( dq!= Q_UNSPECIFIED) { if (dq > MAX_Q) { LM_DBG("default_q = %d, lowering to MAX_Q: %d\n", dq, MAX_Q); dq = MAX_Q; } else if (dq < MIN_Q) { LM_DBG("default_q = %d, raising to MIN_Q: %d\n", dq, MIN_Q); dq = MIN_Q; } } cfg_get(registrar, registrar_cfg, default_q) = dq; if (bind_usrloc(&ul) < 0) { return -1; } if(ul.register_ulcb != NULL) { reg_expire_event_rt = route_lookup(&event_rt, "usrloc:contact-expired"); if (reg_expire_event_rt>=0 && event_rt.rlist[reg_expire_event_rt]==0) reg_expire_event_rt=-1; /* disable */ if (reg_expire_event_rt>=0) { set_child_rpc_sip_mode(); if(ul.register_ulcb(UL_CONTACT_EXPIRE, reg_ul_expired_contact, 0)< 0) { LM_ERR("can not register callback for expired contacts\n"); return -1; } } } /* * Import use_domain parameter from usrloc */ reg_use_domain = ul.use_domain; if (sock_hdr_name.s) { if (sock_hdr_name.len==0 || sock_flag==-1) { LM_WARN("empty sock_hdr_name or sock_flag no set -> reseting\n"); sock_hdr_name.len = 0; sock_flag = -1; } } else if (sock_flag!=-1) { LM_WARN("sock_flag defined but no sock_hdr_name -> reseting flag\n"); sock_flag = -1; } if (reg_outbound_mode < 0 || reg_outbound_mode > 2) { LM_ERR("outbound_mode modparam must be 0 (not supported), 1 (supported), or 2 (supported and required)\n"); return -1; } if (reg_regid_mode < 0 || reg_regid_mode > 1) { LM_ERR("regid_mode modparam must be 0 (use with outbound), 1 (use always)\n"); return -1; } if (reg_flow_timer < 0 || reg_flow_timer > REG_FLOW_TIMER_MAX || (reg_flow_timer > 0 && reg_outbound_mode == REG_OUTBOUND_NONE)) { LM_ERR("bad value for flow_timer\n"); return -1; } /* fix the flags */ sock_flag = (sock_flag!=-1)?(1<<sock_flag):0; tcp_persistent_flag = (tcp_persistent_flag!=-1)?(1<<tcp_persistent_flag):0; return 0; }
static int mod_init(void) { pv_spec_t avp_spec; // initialize the canonical_uri_avp structure if (canonical_uri_avp.spec.s==NULL || *(canonical_uri_avp.spec.s)==0) { LM_ERR("missing/empty canonical_uri_avp parameter. using default.\n"); canonical_uri_avp.spec.s = CANONICAL_URI_AVP_SPEC; } canonical_uri_avp.spec.len = strlen(canonical_uri_avp.spec.s); if (pv_parse_spec(&(canonical_uri_avp.spec), &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_CRIT("invalid AVP specification for canonical_uri_avp: `%s'\n", canonical_uri_avp.spec.s); return -1; } if (pv_get_avp_name(0, &(avp_spec.pvp), &(canonical_uri_avp.name), &(canonical_uri_avp.type))!=0) { LM_CRIT("invalid AVP specification for canonical_uri_avp: `%s'\n", canonical_uri_avp.spec.s); return -1; } // initialize the signaling_ip_avp structure if (signaling_ip_avp.spec.s==NULL || *(signaling_ip_avp.spec.s)==0) { LM_ERR("missing/empty signaling_ip_avp parameter. using default.\n"); signaling_ip_avp.spec.s = SIGNALING_IP_AVP_SPEC; } signaling_ip_avp.spec.len = strlen(signaling_ip_avp.spec.s); if (pv_parse_spec(&(signaling_ip_avp.spec), &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_CRIT("invalid AVP specification for signaling_ip_avp: `%s'\n", signaling_ip_avp.spec.s); return -1; } if (pv_get_avp_name(0, &(avp_spec.pvp), &(signaling_ip_avp.name), &(signaling_ip_avp.type))!=0) { LM_CRIT("invalid AVP specification for signaling_ip_avp: `%s'\n", signaling_ip_avp.spec.s); return -1; } // initialize the call_limit_avp structure if (call_limit_avp.spec.s==NULL || *(call_limit_avp.spec.s)==0) { LM_ERR("missing/empty call_limit_avp parameter. using default.\n"); call_limit_avp.spec.s = CALL_LIMIT_AVP_SPEC; } call_limit_avp.spec.len = strlen(call_limit_avp.spec.s); if (pv_parse_spec(&(call_limit_avp.spec), &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_CRIT("invalid AVP specification for call_limit_avp: `%s'\n", call_limit_avp.spec.s); return -1; } if (pv_get_avp_name(0, &(avp_spec.pvp), &(call_limit_avp.name), &(call_limit_avp.type))!=0) { LM_CRIT("invalid AVP specification for call_limit_avp: `%s'\n", call_limit_avp.spec.s); return -1; } // initialize the call_token_avp structure if (call_token_avp.spec.s==NULL || *(call_token_avp.spec.s)==0) { LM_ERR("missing/empty call_token_avp parameter. using default.\n"); call_token_avp.spec.s = CALL_TOKEN_AVP_SPEC; } call_token_avp.spec.len = strlen(call_token_avp.spec.s); if (pv_parse_spec(&(call_token_avp.spec), &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_CRIT("invalid AVP specification for call_token_avp: `%s'\n", call_token_avp.spec.s); return -1; } if (pv_get_avp_name(0, &(avp_spec.pvp), &(call_token_avp.name), &(call_token_avp.type))!=0) { LM_CRIT("invalid AVP specification for call_token_avp: `%s'\n", call_token_avp.spec.s); return -1; } // initialize the diverter_avp structure if (diverter_avp.spec.s==NULL || *(diverter_avp.spec.s)==0) { LM_ERR("missing/empty diverter_avp parameter. using default.\n"); diverter_avp.spec.s = DIVERTER_AVP_SPEC; } diverter_avp.spec.len = strlen(diverter_avp.spec.s); if (pv_parse_spec(&(diverter_avp.spec), &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_CRIT("invalid AVP specification for diverter_avp: `%s'\n", diverter_avp.spec.s); return -1; } if (pv_get_avp_name(0, &(avp_spec.pvp), &(diverter_avp.name), &(diverter_avp.type))!=0) { LM_CRIT("invalid AVP specification for diverter_avp: `%s'\n", diverter_avp.spec.s); return -1; } // bind to the dialog API if (load_dlg_api(&dlg_api)!=0) { LM_CRIT("cannot load the dialog module API\n"); return -1; } // register dialog loading callback if (dlg_api.register_dlgcb(NULL, DLGCB_LOADED, __dialog_loaded, NULL, NULL) != 0) { LM_CRIT("cannot register callback for dialogs loaded from the database\n"); } fix_flag_name(prepaid_account_str, prepaid_account_flag); prepaid_account_flag = get_flag_id_by_name(FLAG_TYPE_MSG, prepaid_account_str); return 0; }
static int mod_init(void) { pv_spec_t avp_spec; int i; init_db_url( db_url , 0 /*cannot be null*/); siptrace_table.len = strlen(siptrace_table.s); date_column.len = strlen(date_column.s); callid_column.len = strlen(callid_column.s); traced_user_column.len = strlen(traced_user_column.s); msg_column.len = strlen(msg_column.s); method_column.len = strlen(method_column.s); status_column.len = strlen(status_column.s); fromproto_column.len = strlen(fromproto_column.s); fromip_column.len = strlen(fromip_column.s); fromport_column.len = strlen(fromport_column.s); toproto_column.len = strlen(toproto_column.s); toip_column.len = strlen(toip_column.s); toport_column.len = strlen(toport_column.s); fromtag_column.len = strlen(fromtag_column.s); direction_column.len = strlen(direction_column.s); if (traced_user_avp_str.s) traced_user_avp_str.len = strlen(traced_user_avp_str.s); if (trace_table_avp_str.s) trace_table_avp_str.len = strlen(trace_table_avp_str.s); if (dup_uri_str.s) dup_uri_str.len = strlen(dup_uri_str.s); if (trace_local_ip.s) parse_trace_local_ip(); LM_INFO("initializing...\n"); fix_flag_name(trace_flag_str, trace_flag); trace_flag = get_flag_id_by_name(FLAG_TYPE_MSG, trace_flag_str); if (flag_idx2mask(&trace_flag)<0) return -1; trace_to_database_flag = (int*)shm_malloc(sizeof(int)); if(trace_to_database_flag==NULL) { LM_ERR("no more shm memory left\n"); return -1; } *trace_to_database_flag = trace_to_database; if(trace_to_database_flag!=NULL && *trace_to_database_flag!=0) { /* Find a database module */ if (db_bind_mod(&db_url, &db_funcs)) { LM_ERR("unable to bind database module\n"); return -1; } if (trace_to_database_flag && !DB_CAPABILITY(db_funcs, DB_CAP_INSERT)) { LM_ERR("database modules does not provide all functions needed by module\n"); return -1; } if ((db_con = db_funcs.init(&db_url)) == 0) { LM_CRIT("Cannot connect to DB\n"); return -1; } if(db_check_table_version(&db_funcs, db_con, &siptrace_table, SIPTRACE_TABLE_VERSION) < 0) { LM_ERR("error during table version check.\n"); return -1; } db_funcs.close(db_con); db_con = 0; } trace_on_flag = (int*)shm_malloc(sizeof(int)); if(trace_on_flag==NULL) { LM_ERR("no more shm memory left\n"); return -1; } *trace_on_flag = trace_on; /* register callbacks to TM */ if (load_tm_api(&tmb)!=0) { LM_ERR("can't load tm api\n"); return -1; } if(tmb.register_tmcb( 0, 0, TMCB_REQUEST_IN, trace_onreq_in, 0, 0) <=0) { LM_ERR("can't register trace_onreq_in\n"); return -1; } /* register sl callback */ register_slcb_f = (register_slcb_t)find_export("register_slcb", 0, 0); if(register_slcb_f==NULL) { LM_ERR("can't load sl api\n"); return -1; } if(register_slcb_f(SLCB_REPLY_OUT,trace_sl_onreply_out, NULL)!=0) { LM_ERR("can't register trace_sl_onreply_out\n"); return -1; } if(register_fwdcb(trace_msg_out_w)!=0) { LM_ERR("can't register trace_sl_ack_out\n"); return -1; } if(enable_ack_trace&®ister_slcb_f(SLCB_ACK_IN,trace_sl_ack_in,NULL)!=0) { LM_ERR("can't register trace_sl_ack_in\n"); return -1; } if(dup_uri_str.s!=0) { dup_uri_str.len = strlen(dup_uri_str.s); dup_uri = (struct sip_uri *)pkg_malloc(sizeof(struct sip_uri)); if(dup_uri==0) { LM_ERR("no more pkg memory left\n"); return -1; } memset(dup_uri, 0, sizeof(struct sip_uri)); if(parse_uri(dup_uri_str.s, dup_uri_str.len, dup_uri)<0) { LM_ERR("bad dup uri\n"); return -1; } } if(traced_user_avp_str.s && traced_user_avp_str.len > 0) { if (pv_parse_spec(&traced_user_avp_str, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", traced_user_avp_str.len, traced_user_avp_str.s); return -1; } if(pv_get_avp_name(0, &avp_spec.pvp, &traced_user_avp, &traced_user_avp_type)!=0) { LM_ERR("[%.*s] - invalid AVP definition\n", traced_user_avp_str.len, traced_user_avp_str.s); return -1; } } else { traced_user_avp = -1; traced_user_avp_type = 0; } if(trace_table_avp_str.s && trace_table_avp_str.len > 0) { if (pv_parse_spec(&trace_table_avp_str, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", trace_table_avp_str.len, trace_table_avp_str.s); return -1; } if(pv_get_avp_name(0, &avp_spec.pvp, &trace_table_avp, &trace_table_avp_type)!=0) { LM_ERR("[%.*s] - invalid AVP definition\n" , trace_table_avp_str.len, trace_table_avp_str.s); return -1; } } else { trace_table_avp = -1; trace_table_avp_type = 0; } if (duplicate_with_hep) { load_hep = (load_hep_f)find_export("load_hep", 1, 0); if (!load_hep) { LM_ERR("Can't bind proto hep!\n"); return -1; } if (load_hep(&hep_api)) { LM_ERR("can't bind proto hep\n"); return -1; } } /* init the DB keys for future queries */ db_keys[0] = &msg_column; db_keys[1] = &callid_column; db_keys[2] = &method_column; db_keys[3] = &status_column; db_keys[4] = &fromproto_column; db_keys[5] = &fromip_column; db_keys[6] = &fromport_column; db_keys[7] = &toproto_column; db_keys[8] = &toip_column; db_keys[9] = &toport_column; db_keys[10] = &date_column; db_keys[11] = &direction_column; db_keys[12] = &fromtag_column; db_keys[13] = &traced_user_column; /* init DB values info which is constant ( type, null ) */ db_vals[0].type = DB_BLOB; db_vals[1].type = DB_STR; db_vals[2].type = DB_STR; db_vals[3].type = DB_STR; db_vals[4].type = DB_STR; db_vals[5].type = DB_STR; db_vals[6].type = DB_INT; db_vals[7].type = DB_STR; db_vals[8].type = DB_STR; db_vals[9].type = DB_INT; db_vals[10].type = DB_DATETIME; db_vals[11].type = DB_STRING; db_vals[12].type = DB_STR; db_vals[13].type = DB_STR; /* no field can be null */ for (i=0;i<NR_KEYS;i++) db_vals[i].nul = 0; return 0; }
int pv_get_tm_branch_avp(struct sip_msg *msg, pv_param_t *param, pv_value_t *val) { int avp_name; int_str avp_value; unsigned short name_type; int idx, idxf, res=0; struct usr_avp **old_list=NULL; struct usr_avp **avp_list=NULL; struct usr_avp *avp; int_str avp_value0; struct usr_avp *avp0; int n=0; char *p; if (!msg || !val) goto error; avp_list = get_bavp_list(); if (!avp_list) { pv_get_null(msg, param, val); goto success; } if (!param) { LM_ERR("bad parameters\n"); goto error; } if (pv_get_avp_name(msg, param, &avp_name, &name_type)) { LM_ALERT("BUG in getting bavp name\n"); goto error; } /* get the index */ if(pv_get_spec_index(msg, param, &idx, &idxf)!=0) { LM_ERR("invalid index\n"); goto error; } /* setting the avp head */ old_list = set_avp_list(avp_list); if (!old_list) { LM_CRIT("no bavp head list found\n"); goto error; } if ((avp=search_first_avp(name_type, avp_name, &avp_value, 0))==0) { pv_get_null(msg, param, val); goto success; } val->flags = PV_VAL_STR; if ( (idxf==0 || idxf==PV_IDX_INT) && idx==0) { if(avp->flags & AVP_VAL_STR) { val->rs = avp_value.s; } else { val->rs.s = sint2str(avp_value.n, &val->rs.len); val->ri = avp_value.n; val->flags |= PV_VAL_INT|PV_TYPE_INT; } goto success; } if(idxf==PV_IDX_ALL) { p = pv_local_buf; do { if(avp->flags & AVP_VAL_STR) { val->rs = avp_value.s; } else { val->rs.s = sint2str(avp_value.n, &val->rs.len); } if(p-pv_local_buf+val->rs.len+1>PV_LOCAL_BUF_SIZE) { LM_ERR("local buffer length exceeded!\n"); pv_get_null(msg, param, val); goto success; } memcpy(p, val->rs.s, val->rs.len); p += val->rs.len; if(p-pv_local_buf+PV_FIELD_DELIM_LEN+1>PV_LOCAL_BUF_SIZE) { LM_ERR("local buffer length exceeded\n"); pv_get_null(msg, param, val); goto success; } memcpy(p, PV_FIELD_DELIM, PV_FIELD_DELIM_LEN); p += PV_FIELD_DELIM_LEN; } while ((avp=search_first_avp(name_type, avp_name, &avp_value, avp))!=0); *p = 0; val->rs.s = pv_local_buf; val->rs.len = p - pv_local_buf; goto success; } /* we have a numeric index */ if(idx<0) { n = 1; avp0 = avp; while ((avp0=search_first_avp(name_type, avp_name, &avp_value0, avp0))!=0) n++; idx = -idx; if(idx>n) { LM_DBG("index out of range\n"); pv_get_null(msg, param, val); goto success; } idx = n - idx; if(idx==0) { if(avp->flags & AVP_VAL_STR) { val->rs = avp_value.s; } else { val->rs.s = sint2str(avp_value.n, &val->rs.len); val->ri = avp_value.n; val->flags |= PV_VAL_INT|PV_TYPE_INT; } goto success; } } n=0; while(n<idx && (avp=search_first_avp(name_type, avp_name, &avp_value, avp))!=0) n++; if(avp!=0) { if(avp->flags & AVP_VAL_STR) { val->rs = avp_value.s; } else { val->rs.s = sint2str(avp_value.n, &val->rs.len); val->ri = avp_value.n; val->flags |= PV_VAL_INT|PV_TYPE_INT; } } goto success; error: res = -1; success: if (old_list) set_avp_list(old_list); return res; }
int pv_set_tm_branch_avp(struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val) { int avp_name; int_str avp_val; int flags, res=0; unsigned short name_type; int idx, idxf; struct usr_avp **old_list=NULL; struct usr_avp **avp_list=NULL; if (!msg || !val) goto error; avp_list = get_bavp_list(); if (!avp_list) { pv_get_null(msg, param, val); goto success; } if (!param) { LM_ERR("bad parameters\n"); goto error; } if (pv_get_avp_name(msg, param, &avp_name, &name_type)) { LM_ALERT("BUG in getting bavp name\n"); goto error; } /* get the index */ if(pv_get_spec_index(msg, param, &idx, &idxf)!=0) { LM_ERR("invalid index\n"); goto error; } /* setting the avp head */ old_list = set_avp_list(avp_list); if (!old_list) { LM_CRIT("no bavp head list found\n"); goto error; } if(val == NULL) { if(op == COLONEQ_T || idxf == PV_IDX_ALL) destroy_avps(name_type, avp_name, 1); else { if(idx < 0) { LM_ERR("index with negative value\n"); goto error; } destroy_index_avp(name_type, avp_name, idx); } /* restoring head */ goto success; } if(op == COLONEQ_T || idxf == PV_IDX_ALL) destroy_avps(name_type, avp_name, 1); flags = name_type; if(val->flags&PV_TYPE_INT) { avp_val.n = val->ri; } else { avp_val.s = val->rs; flags |= AVP_VAL_STR; } if(idxf == PV_IDX_INT || idxf == PV_IDX_PVAR) { if(replace_avp(flags, avp_name, avp_val, idx)< 0) { LM_ERR("failed to replace bavp\n"); goto error; } } else { if (add_avp(flags, avp_name, avp_val)<0) { LM_ERR("error - cannot add bavp\n"); goto error; } } goto success; error: res = -1; success: if (old_list) set_avp_list(old_list); return res; }
static int mmg_lookup_cmd(struct sip_msg *msg, char *_fields_pv, char *_ipaddr_pv, char *_dst_spec) { pv_elem_t *fields_pv=(pv_elem_t*)_fields_pv, *ipaddr_pv=(pv_elem_t*)_ipaddr_pv; pv_spec_t *dst_spec=(pv_spec_t*)_dst_spec; GeoIPRecord *gir=0; str field_str, ipaddr_str; char rslt_buf[256], ipaddr_buf[256], field_buf[256]; char *token=0, *saveptr=0; int dst_name=-1; int_str rslt=(int_str)0; unsigned short dstType=0; /* Sanity checks */ if(!(ipaddr_pv && fields_pv && dst_spec)) { LM_ERR("Missing argument(s).\n"); return -1; } if(dst_spec->type != PVT_AVP) { LM_ERR("Invalid destination spec -- expected AVP.\n"); return -1; } if(pv_get_avp_name(msg, &(dst_spec->pvp), &dst_name, &dstType)!=0) { LM_ERR("Internal error getting AVP name.\n"); return -1; } /* Expand input args: lookup field list and IP address.*/ *ipaddr_buf=0; ipaddr_str.s=ipaddr_buf; ipaddr_str.len=sizeof ipaddr_buf; if(pv_printf(msg, ipaddr_pv, ipaddr_buf, &ipaddr_str.len) || ipaddr_str.len==0) { LM_ERR("Internal error parsing IP address.\n"); return -1; } *field_buf=0; field_str.s=field_buf; field_str.len=sizeof field_buf; if(pv_printf(msg, fields_pv, field_buf, &field_str.len) || field_str.len==0) { LM_ERR("Internal error parsing lookup fields.\n"); return -1; } /* Attempt lookup */ if(!(gir=GeoIP_record_by_name (MMG_gi,ipaddr_buf))){ LM_DBG("'%s'--> 'Unknown'.\n", *ipaddr_buf?ipaddr_buf:"Undefined"); return -1; } /* Construct return data. Know fields are: */ /* lat - latitude */ /* lon - longitude */ /* cont - continent */ /* cc - country code */ /* reg - region */ /* city - city */ /* pc - postal code */ /* dma - dma code */ /* ac - area code */ /* tz - timezone */ #define MMG_FAIL_EXIT if(gir) GeoIPRecord_delete(gir); return -1 LM_DBG("ipaddr:'%.*s'; fields:'%.*s'.\n", ipaddr_str.len, ipaddr_str.s, field_str.len, field_str.s); *rslt_buf=0; rslt.s.s=rslt_buf; token=strtok_r(field_buf,MMG_OP_DELIMS,&saveptr); while (token) { if(!strcmp(token,"lat")) { rslt.s.len=snprintf(rslt_buf,sizeof rslt_buf,"%f",gir->latitude); } else if(!strcmp(token,"lon")) { rslt.s.len=snprintf(rslt_buf,sizeof rslt_buf,"%f",gir->longitude); } else if(!strcmp(token,"cont")) { rslt.s.len=snprintf(rslt_buf,sizeof rslt_buf,"%s",gir->continent_code); } else if(!strcmp(token,"cc")) { rslt.s.len=snprintf(rslt_buf,sizeof rslt_buf,"%s",gir->country_code); } else if(!strcmp(token,"reg")) { rslt.s.len=snprintf(rslt_buf,sizeof rslt_buf,"%s",gir->region); } else if(!strcmp(token,"city")) { rslt.s.len=snprintf(rslt_buf,sizeof rslt_buf,"%s",gir->city); } else if(!strcmp(token,"pc")) { rslt.s.len=snprintf(rslt_buf,sizeof rslt_buf,"%s",gir->postal_code); } else if(!strcmp(token,"dma")) { rslt.s.len=snprintf(rslt_buf,sizeof rslt_buf,"%d",gir->dma_code); } else if(!strcmp(token,"ac")) { rslt.s.len=snprintf(rslt_buf,sizeof rslt_buf,"%d",gir->area_code); } else if(!strcmp(token,"rbc")) { rslt.s.len=snprintf( rslt_buf,sizeof rslt_buf,"%s",GeoIP_region_name_by_code(gir->country_code, gir->region)); } else if(!strcmp(token,"tz")) { rslt.s.len=snprintf( rslt_buf,sizeof rslt_buf,"%s",GeoIP_time_zone_by_country_and_region(gir->country_code, gir->region)); } else { LM_ERR("unknown field:'%s'\n",token); MMG_FAIL_EXIT; } if(rslt.s.len<0 || rslt.s.len>sizeof rslt_buf || add_avp(dstType|AVP_VAL_STR,dst_name,rslt)==-1 ) { LM_ERR("Internal error processing field/IP '%s/%s'.\n", token,ipaddr_buf); MMG_FAIL_EXIT; } LM_DBG("field %s[%s] %.*s\n",ipaddr_buf,token,rslt.s.len,rslt.s.s); token=strtok_r(0,MMG_OP_DELIMS,&saveptr); } GeoIPRecord_delete(gir); return 1; }
static int mod_init( void ) { pv_spec_t avp_spec; LM_INFO("initializing...\n"); if (db_url.s) db_url.len = strlen(db_url.s); db_table_acc.len = strlen(db_table_acc.s); db_table_mc.len = strlen(db_table_mc.s); acc_method_col.len = strlen(acc_method_col.s); acc_fromtag_col.len = strlen(acc_fromtag_col.s); acc_totag_col.len = strlen(acc_totag_col.s); acc_callid_col.len = strlen(acc_callid_col.s); acc_sipcode_col.len = strlen(acc_sipcode_col.s); acc_sipreason_col.len = strlen(acc_sipreason_col.s); acc_time_col.len = strlen(acc_time_col.s); if (log_facility_str) { int tmp = str2facility(log_facility_str); if (tmp != -1) acc_log_facility = tmp; else { LM_ERR("invalid log facility configured"); return -1; } } /* ----------- GENERIC INIT SECTION ----------- */ fix_flag_name(failed_transaction_string, failed_transaction_flag); failed_transaction_flag = get_flag_id_by_name(FLAG_TYPE_MSG, failed_transaction_string); if (flag_idx2mask(&failed_transaction_flag)<0) return -1; fix_flag_name(cdr_string, cdr_flag); cdr_flag = get_flag_id_by_name(FLAG_TYPE_MSG, cdr_string); if (flag_idx2mask(&cdr_flag)<0) return -1; /* load the TM API */ if (load_tm_api(&tmb)!=0) { LM_ERR("can't load TM API\n"); return -1; } if (load_dlg_api(&dlg_api)!=0) LM_DBG("failed to find dialog API - is dialog module loaded?\n"); if (cdr_flag && !dlg_api.get_dlg) { LM_WARN("error loading dialog module - cdrs cannot be generated\n"); cdr_flag = 0; } /* if detect_direction is enabled, load rr also */ if (detect_direction) { if (load_rr_api(&rrb)!=0) { LM_ERR("can't load RR API\n"); return -1; } /* we need the append_fromtag on in RR */ if (!rrb.append_fromtag) { LM_ERR("'append_fromtag' RR param is not enabled!" " - required by 'detect_direction'\n"); return -1; } } /* listen for all incoming requests */ if ( tmb.register_tmcb( 0, 0, TMCB_REQUEST_IN, acc_onreq, 0, 0 ) <=0 ) { LM_ERR("cannot register TMCB_REQUEST_IN callback\n"); return -1; } /* init the extra engine */ init_acc_extra(); /* configure multi-leg accounting */ if (leg_info_str && (leg_info=parse_acc_leg(leg_info_str))==0 ) { LM_ERR("failed to parse multi_leg_info param\n"); return -1; } if (leg_bye_info_str && (leg_bye_info=parse_acc_leg(leg_bye_info_str))==0 ) { LM_ERR("failed to parse multi_leg_bye_info param\n"); return -1; } /* ----------- SYSLOG INIT SECTION ----------- */ /* parse the extra string, if any */ if (log_extra_str && (log_extra=parse_acc_extra(log_extra_str, 1))==0 ) { LM_ERR("failed to parse log_extra param\n"); return -1; } if (log_extra_bye_str && (log_extra_bye=parse_acc_extra(log_extra_bye_str, 0))==0 ) { LM_ERR("failed to parse log_extra_bye param\n"); return -1; } fix_flag_name(log_string, log_flag); log_flag = get_flag_id_by_name(FLAG_TYPE_MSG, log_string); if (flag_idx2mask(&log_flag)<0) return -1; fix_flag_name(log_missed_string, log_missed_flag); log_missed_flag = get_flag_id_by_name(FLAG_TYPE_MSG, log_missed_string); if (flag_idx2mask(&log_missed_flag)<0) return -1; acc_log_init(); /* ------------ SQL INIT SECTION ----------- */ if (db_url.s && db_url.len > 0) { /* parse the extra string, if any */ if (db_extra_str && (db_extra=parse_acc_extra(db_extra_str, 1))==0 ) { LM_ERR("failed to parse db_extra param\n"); return -1; } if (db_extra_bye_str && (db_extra_bye=parse_acc_extra(db_extra_bye_str, 0))==0 ) { LM_ERR("failed to parse db_extra_bye param\n"); return -1; } if (acc_db_init(&db_url)<0){ LM_ERR("failed...did you load a database module?\n"); return -1; } /* fix the flags */ fix_flag_name(db_string, db_flag); db_flag = get_flag_id_by_name(FLAG_TYPE_MSG, db_string); if (flag_idx2mask(&db_flag)<0) return -1; fix_flag_name(db_missed_string, db_missed_flag); db_missed_flag = get_flag_id_by_name(FLAG_TYPE_MSG, db_missed_string); if (flag_idx2mask(&db_missed_flag)<0) return -1; if (db_table_avp.s) { db_table_avp.len = strlen(db_table_avp.s); if (pv_parse_spec(&db_table_avp, &avp_spec) == 0 || avp_spec.type != PVT_AVP) { LM_ERR("malformed or non AVP %s\n", db_table_avp.s); return -1; } if (pv_get_avp_name(0, &avp_spec.pvp, &db_table_name, &db_table_name_type)) { LM_ERR("invalid definition of AVP %s\n", db_table_avp.s); return -1; } } } else { db_flag = 0; db_missed_flag = 0; } /* ------------ AAA PROTOCOL INIT SECTION ----------- */ if (aaa_proto_url && aaa_proto_url[0]) { /* parse the extra string, if any */ if (aaa_extra_str && (aaa_extra = parse_acc_extra(aaa_extra_str, 1))==0) { LM_ERR("failed to parse aaa_extra param\n"); return -1; } if (aaa_extra_bye_str && (aaa_extra_bye = parse_acc_extra(aaa_extra_bye_str, 0))==0) { LM_ERR("failed to parse aaa_extra_bye param\n"); return -1; } /* fix the flags */ fix_flag_name(aaa_string, aaa_flag); aaa_flag = get_flag_id_by_name(FLAG_TYPE_MSG, aaa_string); if (flag_idx2mask(&aaa_flag)<0) return -1; fix_flag_name(aaa_missed_string, aaa_missed_flag); aaa_missed_flag = get_flag_id_by_name(FLAG_TYPE_MSG, aaa_missed_string); if (flag_idx2mask(&aaa_missed_flag)<0) return -1; if (init_acc_aaa(aaa_proto_url, service_type)!=0 ) { LM_ERR("failed to init radius\n"); return -1; } } else { aaa_proto_url = NULL; aaa_flag = 0; aaa_missed_flag = 0; } /* ------------ DIAMETER INIT SECTION ----------- */ #ifdef DIAM_ACC /* fix the flags */ fix_flag_name(diameter_string, diameter_flag); diameter_flag = get_flag_id_by_name(FLAG_TYPE_MSG, diameter_string); if (flag_idx2mask(&diameter_flag)<0) return -1; fix_flag_name(diameter_missed_string, diameter_missed_flag); diameter_missed_flag=get_flag_id_by_name(FLAG_TYPE_MSG, diameter_missed_string); if (flag_idx2mask(&diameter_missed_flag)<0) return -1; /* parse the extra string, if any */ if (dia_extra_str && (dia_extra=parse_acc_extra(dia_extra_str))==0 ) { LM_ERR("failed to parse dia_extra param\n"); return -1; } if (acc_diam_init()!=0) { LM_ERR("failed to init diameter engine\n"); return -1; } #endif /* ------------ EVENTS INIT SECTION ----------- */ if (evi_extra_str && (evi_extra = parse_acc_extra(evi_extra_str, 1))==0) { LM_ERR("failed to parse evi_extra param\n"); return -1; } if (evi_extra_bye_str && (evi_extra_bye = parse_acc_extra(evi_extra_bye_str, 0))==0) { LM_ERR("failed to parse evi_extra_bye param\n"); return -1; } /* fix the flags */ fix_flag_name(evi_string, evi_flag); evi_flag = get_flag_id_by_name(FLAG_TYPE_MSG, evi_string); if (flag_idx2mask(&evi_flag)<0) return -1; fix_flag_name(evi_missed_string, evi_missed_flag); evi_missed_flag = get_flag_id_by_name(FLAG_TYPE_MSG, evi_missed_string); if (flag_idx2mask(&evi_missed_flag)<0) return -1; if (init_acc_evi() < 0) { LM_ERR("cannot init acc events\n"); return -1; } /* load callbacks */ if (cdr_flag && dlg_api.get_dlg && dlg_api.register_dlgcb(NULL, DLGCB_LOADED,acc_loaded_callback, NULL, NULL) < 0) LM_ERR("cannot register callback for dialog loaded - accounting " "for ongoing calls will be lost after restart\n"); return 0; }
/** * init module function */ static int mod_init(void) { pv_spec_t avp_spec; LM_DBG("initializing ...\n"); if (dst_avp_param.s) dst_avp_param.len = strlen(dst_avp_param.s); if (grp_avp_param.s) grp_avp_param.len = strlen(grp_avp_param.s); if (cnt_avp_param.s) cnt_avp_param.len = strlen(cnt_avp_param.s); if (attrs_avp_param.s) attrs_avp_param.len = strlen(attrs_avp_param.s); if (hash_pvar_param.s) hash_pvar_param.len = strlen(hash_pvar_param.s); if (ds_setid_pvname.s) ds_setid_pvname.len = strlen(ds_setid_pvname.s); if (ds_ping_from.s) ds_ping_from.len = strlen(ds_ping_from.s); if (ds_ping_method.s) ds_ping_method.len = strlen(ds_ping_method.s); if(options_reply_codes_str.s) { options_reply_codes_str.len = strlen(options_reply_codes_str.s); if(parse_reply_codes( &options_reply_codes_str, &options_reply_codes, &options_codes_no )< 0) { LM_ERR("Bad format for options_reply_code parameter" " - Need a code list separated by commas\n"); return -1; } } if(init_data()!= 0) return -1; if(ds_db_url.s) { ds_db_url.len = strlen(ds_db_url.s); ds_table_name.len = strlen(ds_table_name.s); ds_set_id_col.len = strlen(ds_set_id_col.s); ds_dest_uri_col.len = strlen(ds_dest_uri_col.s); ds_dest_flags_col.len = strlen(ds_dest_flags_col.s); ds_dest_weight_col.len= strlen(ds_dest_weight_col.s); ds_dest_attrs_col.len = strlen(ds_dest_attrs_col.s); if(init_ds_db()!= 0) { LM_ERR("could not initiate a connect to the database\n"); return -1; } } else { if(ds_load_list(dslistfile)!=0) { LM_ERR("no dispatching list loaded from file\n"); return -1; } else { LM_DBG("loaded dispatching list\n"); } } if (dst_avp_param.s && dst_avp_param.len > 0) { if (pv_parse_spec(&dst_avp_param, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", dst_avp_param.len, dst_avp_param.s); return -1; } if(pv_get_avp_name(0, &(avp_spec.pvp), &dst_avp_name,&dst_avp_type)!=0) { LM_ERR("[%.*s]- invalid AVP definition\n", dst_avp_param.len, dst_avp_param.s); return -1; } } else { dst_avp_name.n = 0; dst_avp_type = 0; } if (grp_avp_param.s && grp_avp_param.len > 0) { if (pv_parse_spec(&grp_avp_param, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", grp_avp_param.len, grp_avp_param.s); return -1; } if(pv_get_avp_name(0, &(avp_spec.pvp), &grp_avp_name,&grp_avp_type)!=0) { LM_ERR("[%.*s]- invalid AVP definition\n", grp_avp_param.len, grp_avp_param.s); return -1; } } else { grp_avp_name.n = 0; grp_avp_type = 0; } if (cnt_avp_param.s && cnt_avp_param.len > 0) { if (pv_parse_spec(&cnt_avp_param, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", cnt_avp_param.len, cnt_avp_param.s); return -1; } if(pv_get_avp_name(0, &(avp_spec.pvp), &cnt_avp_name,&cnt_avp_type)!=0) { LM_ERR("[%.*s]- invalid AVP definition\n", cnt_avp_param.len, cnt_avp_param.s); return -1; } } else { cnt_avp_name.n = 0; cnt_avp_type = 0; } if (attrs_avp_param.s && attrs_avp_param.len > 0) { if (pv_parse_spec(&attrs_avp_param, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", attrs_avp_param.len, attrs_avp_param.s); return -1; } if (pv_get_avp_name(0, &(avp_spec.pvp), &attrs_avp_name, &attrs_avp_type)!=0){ LM_ERR("[%.*s]- invalid AVP definition\n", attrs_avp_param.len, attrs_avp_param.s); return -1; } } else { attrs_avp_name.n = 0; attrs_avp_type = 0; } if (hash_pvar_param.s && *hash_pvar_param.s) { if(pv_parse_format(&hash_pvar_param, &hash_param_model) < 0 || hash_param_model==NULL) { LM_ERR("malformed PV string: %s\n", hash_pvar_param.s); return -1; } } else { hash_param_model = NULL; } if(ds_setid_pvname.s!=0) { if(pv_parse_spec(&ds_setid_pvname, &ds_setid_pv)==NULL || !pv_is_w(&ds_setid_pv)) { LM_ERR("[%s]- invalid setid_pvname\n", ds_setid_pvname.s); return -1; } } /* Only, if the Probing-Timer is enabled the TM-API needs to be loaded: */ if (ds_ping_interval > 0) { load_tm_f load_tm; str host; int port,proto; if (probing_sock_s && probing_sock_s[0]!=0 ) { if (parse_phostport( probing_sock_s, strlen(probing_sock_s), &host.s, &host.len, &port, &proto)!=0 ) { LM_ERR("socket description <%s> is not valid\n", probing_sock_s); return -1; } probing_sock = grep_sock_info( &host, port, proto); if (probing_sock==NULL) { LM_ERR("socket <%s> is not local to opensips (we must listen " "on it\n", probing_sock_s); return -1; } } /* TM-Bindings */ load_tm=(load_tm_f)find_export("load_tm", 0, 0); if (load_tm==NULL) { LM_ERR("failed to bind to the TM-Module - required for probing\n"); return -1; } /* let the auto-loading function load all TM stuff */ if (load_tm( &tmb ) == -1) { LM_ERR("could not load the TM-functions - disable DS ping\n"); return -1; } /* Register the PING-Timer */ if (register_timer(ds_check_timer, NULL, ds_ping_interval)<0) { LM_ERR("failed to register timer for probing!\n"); return -1; } } return 0; }
static int partition_init(ds_db_head_t *db_head, ds_partition_t *partition) { /* Load stuff from DB. URL cannot be null!*/ if (db_head->db_url.s == NULL){ LM_ERR("[%.*s] DB URL is not defined!\n", db_head->partition_name.len, db_head->partition_name.s); return -1; } memset(partition, 0, sizeof(ds_partition_t)); partition->name = db_head->partition_name; partition->table_name = db_head->table_name; partition->db_url = db_head->db_url; partition->db_handle = pkg_malloc(sizeof(struct db_con_t *)); if (partition->db_handle == NULL) { LM_ERR("Failed to allocate private data\n"); return -1; } *partition->db_handle = NULL; /* handle AVPs spec */ pv_spec_t avp_spec; if (pv_parse_spec(&db_head->dst_avp, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", db_head->dst_avp.len, db_head->dst_avp.s); return -1; } if(pv_get_avp_name(0, &(avp_spec.pvp), &partition->dst_avp_name, &partition->dst_avp_type)!=0) { LM_ERR("[%.*s]- invalid AVP definition\n", db_head->dst_avp.len, db_head->dst_avp.s); return -1; } if (pv_parse_spec(&db_head->grp_avp, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", db_head->grp_avp.len, db_head->grp_avp.s); return -1; } if(pv_get_avp_name(0, &(avp_spec.pvp), &partition->grp_avp_name, &partition->grp_avp_type)!=0) { LM_ERR("[%.*s]- invalid AVP definition\n", db_head->grp_avp.len, db_head->grp_avp.s); return -1; } if (pv_parse_spec(&db_head->cnt_avp, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", db_head->cnt_avp.len, db_head->cnt_avp.s); return -1; } if(pv_get_avp_name(0, &(avp_spec.pvp), &partition->cnt_avp_name, &partition->cnt_avp_type)!=0) { LM_ERR("[%.*s]- invalid AVP definition\n", db_head->cnt_avp.len, db_head->cnt_avp.s); return -1; } if (pv_parse_spec(&db_head->sock_avp, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", db_head->sock_avp.len, db_head->sock_avp.s); return -1; } if(pv_get_avp_name(0, &(avp_spec.pvp), &partition->sock_avp_name, &partition->sock_avp_type)!=0){ LM_ERR("[%.*s]- invalid AVP definition\n", db_head->sock_avp.len, db_head->sock_avp.s); return -1; } if (db_head->attrs_avp.s && db_head->attrs_avp.len > 0) { if (pv_parse_spec(&db_head->attrs_avp, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", db_head->attrs_avp.len, db_head->attrs_avp.s); return -1; } if (pv_get_avp_name(0, &(avp_spec.pvp), &partition->attrs_avp_name, &partition->attrs_avp_type)!=0){ LM_ERR("[%.*s]- invalid AVP definition\n", db_head->attrs_avp.len, db_head->attrs_avp.s); return -1; } } else { partition->attrs_avp_name = -1; partition->attrs_avp_type = 0; } return 0; }
/** * init module function */ static int mod_init(void) { pv_spec_t avp_spec; LM_DBG("initializing ...\n"); /* Load stuff from DB */ init_db_url( ds_db_url , 0 /*cannot be null*/); ds_table_name.len = strlen(ds_table_name.s); ds_set_id_col.len = strlen(ds_set_id_col.s); ds_dest_uri_col.len = strlen(ds_dest_uri_col.s); ds_dest_sock_col.len = strlen(ds_dest_sock_col.s); ds_dest_state_col.len = strlen(ds_dest_state_col.s); ds_dest_weight_col.len = strlen(ds_dest_weight_col.s); ds_dest_attrs_col.len = strlen(ds_dest_attrs_col.s); /* handle AVPs spec */ dst_avp_param.len = strlen(dst_avp_param.s); if (pv_parse_spec(&dst_avp_param, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", dst_avp_param.len, dst_avp_param.s); return -1; } if(pv_get_avp_name(0, &(avp_spec.pvp), &dst_avp_name,&dst_avp_type)!=0) { LM_ERR("[%.*s]- invalid AVP definition\n", dst_avp_param.len, dst_avp_param.s); return -1; } grp_avp_param.len=strlen(grp_avp_param.s); if (pv_parse_spec(&grp_avp_param, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", grp_avp_param.len, grp_avp_param.s); return -1; } if(pv_get_avp_name(0, &(avp_spec.pvp), &grp_avp_name,&grp_avp_type)!=0) { LM_ERR("[%.*s]- invalid AVP definition\n", grp_avp_param.len, grp_avp_param.s); return -1; } cnt_avp_param.len=strlen(cnt_avp_param.s); if (pv_parse_spec(&cnt_avp_param, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", cnt_avp_param.len, cnt_avp_param.s); return -1; } if(pv_get_avp_name(0, &(avp_spec.pvp), &cnt_avp_name,&cnt_avp_type)!=0) { LM_ERR("[%.*s]- invalid AVP definition\n", cnt_avp_param.len, cnt_avp_param.s); return -1; } sock_avp_param.len=strlen(sock_avp_param.s); if (pv_parse_spec(&sock_avp_param, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", sock_avp_param.len, sock_avp_param.s); return -1; } if(pv_get_avp_name(0, &(avp_spec.pvp), &sock_avp_name,&sock_avp_type)!=0){ LM_ERR("[%.*s]- invalid AVP definition\n", sock_avp_param.len, sock_avp_param.s); return -1; } if (attrs_avp_param.s && (attrs_avp_param.len=strlen(attrs_avp_param.s)) > 0) { if (pv_parse_spec(&attrs_avp_param, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", attrs_avp_param.len, attrs_avp_param.s); return -1; } if (pv_get_avp_name(0, &(avp_spec.pvp), &attrs_avp_name, &attrs_avp_type)!=0){ LM_ERR("[%.*s]- invalid AVP definition\n", attrs_avp_param.len, attrs_avp_param.s); return -1; } } else { attrs_avp_name = -1; attrs_avp_type = 0; } if (hash_pvar_param.s && (hash_pvar_param.len=strlen(hash_pvar_param.s))>0 ) { if(pv_parse_format(&hash_pvar_param, &hash_param_model) < 0 || hash_param_model==NULL) { LM_ERR("malformed PV string: %s\n", hash_pvar_param.s); return -1; } } else { hash_param_model = NULL; } if (ds_setid_pvname.s && (ds_setid_pvname.len=strlen(ds_setid_pvname.s))>0 ) { if(pv_parse_spec(&ds_setid_pvname, &ds_setid_pv)==NULL || !pv_is_w(&ds_setid_pv)) { LM_ERR("[%s]- invalid setid_pvname\n", ds_setid_pvname.s); return -1; } } pvar_algo_param.len = strlen(pvar_algo_param.s); if (pvar_algo_param.len) ds_pvar_parse_pattern(pvar_algo_param); if (init_ds_bls()!=0) { LM_ERR("failed to init DS blacklists\n"); return E_CFG; } if (init_ds_data()!=0) { LM_ERR("failed to init DS data holder\n"); return -1; } /* open DB connection to load provisioning data */ if (init_ds_db()!= 0) { LM_ERR("failed to init database support\n"); return -1; } /* do the actula data load */ if (ds_reload_db()!=0) { LM_ERR("failed to load data from DB\n"); return -1; } /* close DB connection */ ds_disconnect_db(); /* Only, if the Probing-Timer is enabled the TM-API needs to be loaded: */ if (ds_ping_interval > 0) { load_tm_f load_tm; str host; int port,proto; if (ds_ping_from.s) ds_ping_from.len = strlen(ds_ping_from.s); if (ds_ping_method.s) ds_ping_method.len = strlen(ds_ping_method.s); /* parse the list of reply codes to be counted as success */ if(options_reply_codes_str.s) { options_reply_codes_str.len = strlen(options_reply_codes_str.s); if(parse_reply_codes( &options_reply_codes_str, &options_reply_codes, &options_codes_no )< 0) { LM_ERR("Bad format for options_reply_code parameter" " - Need a code list separated by commas\n"); return -1; } } /* parse and look for the socket to ping from */ if (probing_sock_s && probing_sock_s[0]!=0 ) { if (parse_phostport( probing_sock_s, strlen(probing_sock_s), &host.s, &host.len, &port, &proto)!=0 ) { LM_ERR("socket description <%s> is not valid\n", probing_sock_s); return -1; } probing_sock = grep_sock_info( &host, port, proto); if (probing_sock==NULL) { LM_ERR("socket <%s> is not local to opensips (we must listen " "on it\n", probing_sock_s); return -1; } } /* TM-Bindings */ load_tm=(load_tm_f)find_export("load_tm", 0, 0); if (load_tm==NULL) { LM_ERR("failed to bind to the TM-Module - required for probing\n"); return -1; } /* let the auto-loading function load all TM stuff */ if (load_tm( &tmb ) == -1) { LM_ERR("could not load the TM-functions - disable DS ping\n"); return -1; } /* Register the PING-Timer */ if (register_timer("ds-pinger",ds_check_timer,NULL,ds_ping_interval)<0){ LM_ERR("failed to register timer for probing!\n"); return -1; } } /* register timer to flush the state of destination back to DB */ if (register_timer("ds-flusher",ds_flusher_routine,NULL, 30)<0){ LM_ERR("failed to register timer for DB flushing!\n"); return -1; } dispatch_evi_id = evi_publish_event(dispatcher_event); if (dispatch_evi_id == EVI_ERROR) LM_ERR("cannot register dispatcher event\n"); return 0; }
/** Module init function */ static int mod_init(void) { unsigned int i; LM_DBG("start\n"); init_db_url( db_url , 0 /*cannot be null*/); /* load tm api */ if(load_tm_api(&tmb)==-1) { LM_ERR("can't load tm functions\n"); return -1; } /* load pua api */ if(load_pua_api(&pua_api) < 0) { LM_ERR("Can't bind pua\n"); return -1; } /* add event in pua module */ if(pua_api.add_event(CALLINFO_EVENT, "call-info", NULL, 0) < 0) { LM_ERR("failed to add 'call-info' event to pua module\n"); return -1; } /* load b2b_logic api */ if(load_b2b_logic_api(&b2bl_api)< 0) { LM_ERR("Failed to load b2b_logic api\n"); return -1; } if(b2b_sca_hsize<1 || b2b_sca_hsize>20) { LM_ERR("Wrong hash size. Needs to be greater than 1" " and smaller than 20. Be aware that you should set the log 2" " value of the real size\n"); return -1; } b2b_sca_hsize = 1<<b2b_sca_hsize; if(presence_server.s) presence_server.len = strlen(presence_server.s); LM_DBG("fix db columns\n"); sca_table_name.len = strlen(sca_table_name.s); shared_line_column.len = strlen(shared_line_column.s); watchers_column.len = strlen(watchers_column.s); for (i=0; i<MAX_APPEARANCE_INDEX; i++) { app_shared_entity_column[i].len = strlen(app_shared_entity_column[i].s); app_call_state_column[i].len = strlen(app_call_state_column[i].s); app_call_info_uri_column[i].len = strlen(app_call_info_uri_column[i].s); app_call_info_appearance_uri_column[i].len = strlen(app_call_info_appearance_uri_column[i].s); app_b2bl_key_column[i].len = strlen(app_b2bl_key_column[i].s); } LM_DBG("fix AVP spec\n"); /* fix AVP spec */ if(watchers_avp_spec.s) { watchers_avp_spec.len = strlen(watchers_avp_spec.s); if(pv_parse_spec(&watchers_avp_spec, &watchers_spec)==NULL || watchers_spec.type != PVT_AVP) { LM_ERR("failed to parse watchers spec [%.*s]\n", watchers_avp_spec.len, watchers_avp_spec.s); return E_CFG; } if(pv_get_avp_name(NULL, &(watchers_spec.pvp), &(watchers_avp_name), &(watchers_avp_type) )!=0) { LM_ERR("[%.*s]- invalid AVP definition for watchers_avp_spec\n", watchers_avp_spec.len, watchers_avp_spec.s); } } else { watchers_avp_name = -1; watchers_avp_type = 0; } if(shared_line_spec_param.s) { shared_line_spec_param.len = strlen(shared_line_spec_param.s); if(pv_parse_spec(&shared_line_spec_param, &shared_line_spec)==NULL) { LM_ERR("failed to parse shared_line spec\n"); return E_CFG; } switch(shared_line_spec.type) { case PVT_NONE: case PVT_EMPTY: case PVT_NULL: case PVT_MARKER: case PVT_COLOR: LM_ERR("invalid shared_line spec\n"); return -3; default: ; } } if(appearance_name_addr_spec_param.s) { appearance_name_addr_spec_param.len = strlen(appearance_name_addr_spec_param.s); if(pv_parse_spec(&appearance_name_addr_spec_param, &appearance_name_addr_spec)==NULL) { LM_ERR("failed to parse appearance_name_addr spec\n"); return E_CFG; } switch(appearance_name_addr_spec.type) { case PVT_NONE: case PVT_EMPTY: case PVT_NULL: case PVT_MARKER: case PVT_COLOR: LM_ERR("invalid appearance_name_addr spec\n"); return -3; default: ; } } if(init_b2b_sca_htable() < 0) { LM_ERR("Failed to initialize b2b_sca hash table\n"); return -1; } if (sca_db_mode==DB_MODE_NONE) { db_url.s = NULL; db_url.len = 0; } else { if (sca_db_mode!=DB_MODE_REALTIME) { LM_ERR("unsupported db_mode %d\n", sca_db_mode); return -1; } if ( !db_url.s || db_url.len==0 ) { LM_ERR("db_url not configured for db_mode %d\n", sca_db_mode); return -1; } if (init_sca_db(&db_url, b2b_sca_hsize)!=0) { LM_ERR("failed to initialize the DB support\n"); return -1; } } return 0; }
/* * Verify parameters for OSP module * return 0 success, -1 failure */ static int ospVerifyParameters(void) { int i; pv_spec_t avp_spec; str avp_str; int result = 0; if ((_osp_work_mode < 0) || (_osp_work_mode > 1)) { _osp_work_mode = OSP_DEF_MODE; LM_WARN("work mode is out of range, reset to %d\n", OSP_DEF_MODE); } if ((_osp_service_type < 0) || (_osp_service_type > 1)) { _osp_service_type = OSP_DEF_SERVICE; LM_WARN("service type is out of range, reset to %d\n", OSP_DEF_SERVICE); } /* If use_security_features is 0, ignroe the certificate files */ if (_osp_use_security != 0) { /* Default location for the cert files is in the compile time variable CFG_DIR */ if (_osp_private_key == NULL) { sprintf(_osp_PRIVATE_KEY, "%spkey.pem", CFG_DIR); _osp_private_key = _osp_PRIVATE_KEY; } if (_osp_local_certificate == NULL) { sprintf(_osp_LOCAL_CERTIFICATE, "%slocalcert.pem", CFG_DIR); _osp_local_certificate = _osp_LOCAL_CERTIFICATE; } if (_osp_ca_certificate == NULL) { sprintf(_osp_CA_CERTIFICATE, "%scacert_0.pem", CFG_DIR); _osp_ca_certificate = _osp_CA_CERTIFICATE; } } if (_osp_device_ip != NULL) { ospConvertToInAddress(_osp_device_ip, _osp_in_device, sizeof(_osp_in_device)); ospConvertToOutAddress(_osp_device_ip, _osp_out_device, sizeof(_osp_out_device)); } else { _osp_in_device[0] = '\0'; _osp_out_device[0] = '\0'; } if (_osp_max_dests > OSP_MAX_DESTS || _osp_max_dests < 1) { _osp_max_dests = OSP_DEF_DESTS; LM_WARN("max_destinations is out of range, reset to %d\n", OSP_DEF_DESTS); } if (_osp_report_nid < 0 || _osp_report_nid > 3) { _osp_report_nid = OSP_DEF_REPORTNID; LM_WARN("report_networkid is out of range, reset to %d\n", OSP_DEF_REPORTNID); } if (_osp_token_format < 0 || _osp_token_format > 2) { _osp_token_format = OSP_DEF_TOKEN; LM_WARN("token_format is out of range, reset to %d\n", OSP_DEF_TOKEN); } _osp_sp_number = 0; for (i = 0; i < OSP_DEF_SPS; i++) { if (_osp_sp_uris[i] != NULL) { if (_osp_sp_number != i) { _osp_sp_uris[_osp_sp_number] = _osp_sp_uris[i]; _osp_sp_weights[_osp_sp_number] = _osp_sp_weights[i]; _osp_sp_uris[i] = NULL; _osp_sp_weights[i] = OSP_DEF_WEIGHT; } osp_index[_osp_sp_number] = i + 1; _osp_sp_number++; } } if (_osp_sp_number == 0) { LM_ERR("at least one service point uri must be configured\n"); result = -1; } if ((_osp_dnid_location < 0) || (_osp_dnid_location > 3)) { _osp_dnid_location = OSP_DEF_DNIDLOC; LM_WARN("networkid_location is out of range, reset to %d\n", OSP_DEF_DNIDLOC); } if (!(_osp_dnid_param && *_osp_dnid_param)) { _osp_dnid_param = OSP_DEF_DNIDPARAM; } if ((_osp_work_mode == 1) && _osp_srcdev_avp && *_osp_srcdev_avp) { avp_str.s = _osp_srcdev_avp; avp_str.len = strlen(_osp_srcdev_avp); if ((pv_parse_spec(&avp_str, &avp_spec) == NULL) || avp_spec.type != PVT_AVP || pv_get_avp_name(0, &(avp_spec.pvp), &_osp_srcdev_avpid, &_osp_srcdev_avptype) != 0) { LM_WARN("'%s' invalid AVP definition\n", _osp_srcdev_avp); _osp_srcdev_avpid = OSP_DEF_AVP; _osp_srcdev_avptype = 0; } } else { _osp_srcdev_avpid = OSP_DEF_AVP; _osp_srcdev_avptype = 0; } if (_osp_snid_avp && *_osp_snid_avp) { avp_str.s = _osp_snid_avp; avp_str.len = strlen(_osp_snid_avp); if (pv_parse_spec(&avp_str, &avp_spec) == NULL || avp_spec.type != PVT_AVP || pv_get_avp_name(0, &(avp_spec.pvp), &_osp_snid_avpid, &_osp_snid_avptype) != 0) { LM_WARN("'%s' invalid AVP definition\n", _osp_snid_avp); _osp_snid_avpid = OSP_DEF_AVP; _osp_snid_avptype = 0; } } else { _osp_snid_avpid = OSP_DEF_AVP; _osp_snid_avptype = 0; } if (_osp_cinfo_avp && *_osp_cinfo_avp) { avp_str.s = _osp_cinfo_avp; avp_str.len = strlen(_osp_cinfo_avp); if (pv_parse_spec(&avp_str, &avp_spec) == NULL || avp_spec.type != PVT_AVP || pv_get_avp_name(0, &(avp_spec.pvp), &_osp_cinfo_avpid, &_osp_cinfo_avptype) != 0) { LM_WARN("'%s' invalid AVP definition\n", _osp_cinfo_avp); _osp_cinfo_avpid = OSP_DEF_AVP; _osp_cinfo_avptype = 0; } } else { _osp_cinfo_avpid = OSP_DEF_AVP; _osp_cinfo_avptype = 0; } ospDumpParameters(); return result; }