int xavp_params_explode(str *params, str *xname) { param_t* params_list = NULL; param_hooks_t phooks; param_t *pit=NULL; str s; sr_xavp_t *xavp=NULL; sr_xval_t xval; if(params==NULL || xname==NULL || params->s==NULL || xname->s==NULL || params->len<=0 || xname->len<=0) { LM_ERR("invalid parameters\n"); return -1; } s.s = params->s; s.len = params->len; if(s.s[s.len-1]==';') s.len--; if (parse_params(&s, CLASS_ANY, &phooks, ¶ms_list)<0) { LM_DBG("invalid formatted values [%.*s]\n", params->len, params->s); return -1; } if(params_list==NULL) { return -1; } for (pit = params_list; pit; pit=pit->next) { memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_STR; xval.v.s = pit->body; if(xavp_add_value(&pit->name, &xval, &xavp)==NULL) { free_params(params_list); xavp_destroy_list(&xavp); return -1; } } free_params(params_list); /* add main xavp in root list */ memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_XAVP; xval.v.xavp = xavp; if(xavp_add_value(xname, &xval, NULL)==NULL) { xavp_destroy_list(&xavp); return -1; } return 0; }
int rtjson_init_routes(sip_msg_t *msg, str *rdoc) { sr_xavp_t *xavp=NULL; str xname; sr_xval_t xval; srjson_doc_t tdoc; srjson_InitDoc(&tdoc, NULL); tdoc.root = srjson_Parse(&tdoc, rdoc->s); if(tdoc.root == NULL) { LM_ERR("invalid json doc [[%s]]\n", rdoc->s); srjson_DestroyDoc(&tdoc); return -1; } /* basic validation */ srjson_DestroyDoc(&tdoc); memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_INT; xval.v.i = 0; xname.s = "idx"; xname.len = 3; if(xavp_add_value(&xname, &xval, &xavp)==NULL) { goto error; } memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_STR; xval.v.s = *rdoc; xname.s = "json"; xname.len = 4; if(xavp_add_value(&xname, &xval, &xavp)==NULL) { goto error; } memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_XAVP; xval.v.xavp = xavp; if(xavp_add_value(&_rtjson_xavp_name, &xval, NULL)==NULL) { goto error; } return 0; error: if(xavp) xavp_destroy_list(&xavp); return -1; }
/*! \brief * add xavp with details of the record (ruid, ...) */ int xavp_rcd_helper(ucontact_t* ptr) { sr_xavp_t **xavp=NULL; sr_xavp_t *list=NULL; sr_xavp_t *new_xavp=NULL; str xname_ruid = {"ruid", 4}; str xname_received = { "received", 8}; str xname_contact = { "contact", 7}; str xname_expires = {"expires", 7}; sr_xval_t xval; if(ptr==NULL) return -1; if(reg_xavp_rcd.s==NULL || reg_xavp_rcd.len<=0) return 0; list = xavp_get(®_xavp_rcd, NULL); xavp = list ? &list->val.v.xavp : &new_xavp; memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_STR; xval.v.s = ptr->ruid; xavp_add_value(&xname_ruid, &xval, xavp); if(ptr->received.len > 0) { memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_STR; xval.v.s = ptr->received; xavp_add_value(&xname_received, &xval, xavp); } memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_STR; xval.v.s = ptr->c; xavp_add_value(&xname_contact, &xval, xavp); memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_INT; xval.v.i = (int) (ptr->expires - time(0)); xavp_add_value(&xname_expires, &xval, xavp); if(list==NULL) { /* no reg_xavp_rcd xavp in root list - add it */ xval.type = SR_XTYPE_XAVP; xval.v.xavp = *xavp; if(xavp_add_value(®_xavp_rcd, &xval, NULL)==NULL) { LM_ERR("cannot add ruid xavp to root list\n"); xavp_destroy_list(xavp); } } return 0; }
sr_xavp_t *xbuff_new(str *name) { sr_xavp_t *xbuffs_root; sr_xavp_t *xbuff; sr_xval_t xbuff_val; memset((void*)&xbuff_val,0,sizeof(sr_xval_t)); xbuff_val.type = SR_XTYPE_NULL; xbuffs_root = xavp_get_xbuffs(); if(!xbuffs_root) { xbuff = xavp_add_xavp_value(&xbuff_list,name,&xbuff_val,xavp_get_crt_list()); } xbuff=xavp_get_child(&xbuff_list, name); if (!xbuff) { xbuff_val.type = SR_XTYPE_NULL; xbuff_val.v.xavp = NULL; xbuff=xavp_add_value(name,&xbuff_val,&xbuffs_root->val.v.xavp); } return xbuff; }
/*! \brief * Allocate a memory buffer and print Contact * header fields into it */ int build_contact(sip_msg_t *msg, ucontact_t* c, str *host) { char *p, *cp; char *a; int fl, len; str user; str inst; unsigned int ahash; unsigned short digit; int mode; sr_xavp_t *xavp=NULL; sr_xavp_t *list=NULL; str xname = {"ruid", 4}; sr_xval_t xval; if(msg!=NULL && parse_supported(msg)==0 && (get_supported(msg) & F_OPTION_TAG_GRUU)) mode = 1; else mode = 0; contact.data_len = calc_buf_len(c, host, mode); if (!contact.data_len) return 0; if (!contact.buf || (contact.buf_len < contact.data_len)) { if (contact.buf) pkg_free(contact.buf); contact.buf = (char*)pkg_malloc(contact.data_len); if (!contact.buf) { contact.data_len = 0; contact.buf_len = 0; LM_ERR("no pkg memory left\n"); return -1; } else { contact.buf_len = contact.data_len; } } p = contact.buf; memcpy(p, CONTACT_BEGIN, CONTACT_BEGIN_LEN); p += CONTACT_BEGIN_LEN; /* add xavp with details of the record (ruid, ...) */ if(reg_xavp_rcd.s!=NULL) { list = xavp_get(®_xavp_rcd, NULL); xavp = list; } fl = 0; while(c) { if (VALID_CONTACT(c, act_time)) { if (fl) { memcpy(p, CONTACT_SEP, CONTACT_SEP_LEN); p += CONTACT_SEP_LEN; } else { fl = 1; } *p++ = '<'; memcpy(p, c->c.s, c->c.len); p += c->c.len; *p++ = '>'; len = len_q(c->q); if (len) { memcpy(p, Q_PARAM, Q_PARAM_LEN); p += Q_PARAM_LEN; memcpy(p, q2str(c->q, 0), len); p += len; } memcpy(p, EXPIRES_PARAM, EXPIRES_PARAM_LEN); p += EXPIRES_PARAM_LEN; cp = int2str((int)(c->expires - act_time), &len); memcpy(p, cp, len); p += len; if (rcv_param.len>0 && c->received.s) { *p++ = ';'; memcpy(p, rcv_param.s, rcv_param.len); p += rcv_param.len; *p++ = '='; *p++ = '\"'; memcpy(p, c->received.s, c->received.len); p += c->received.len; *p++ = '\"'; } if (reg_gruu_enabled==1 && c->instance.len>0 && mode==1) { user.s = c->aor->s; a = memchr(c->aor->s, '@', c->aor->len); if(a!=NULL) { user.len = a - user.s; } else { user.len = c->aor->len; } /* pub-gruu */ memcpy(p, PUB_GRUU_PARAM, PUB_GRUU_PARAM_LEN); p += PUB_GRUU_PARAM_LEN; *p++ = '\"'; memcpy(p, "sip:", 4); p += 4; if(a!=NULL) { memcpy(p, c->aor->s, c->aor->len); p += c->aor->len; } else { memcpy(p, user.s, user.len); p += user.len; *p++ = '@'; memcpy(p, host->s, host->len); p += host->len; } memcpy(p, GR_PARAM, GR_PARAM_LEN); p += GR_PARAM_LEN; inst = c->instance; if(inst.s[0]=='<' && inst.s[inst.len-1]=='>') { inst.s++; inst.len -= 2; } memcpy(p, inst.s, inst.len); p += inst.len; *p++ = '\"'; /* temp-gruu */ memcpy(p, TMP_GRUU_PARAM, TMP_GRUU_PARAM_LEN); p += TMP_GRUU_PARAM_LEN; *p++ = '\"'; memcpy(p, "sip:", 4); p += 4; memcpy(p, c->ruid.s, c->ruid.len); p += c->ruid.len; *p++ = '-'; ahash = ul.get_aorhash(c->aor); while(ahash!=0) { digit = ahash & 0x0f; *p++ = (digit >= 10) ? digit + 'a' - 10 : digit + '0'; ahash >>= 4; } *p++ = '@'; memcpy(p, host->s, host->len); p += host->len; memcpy(p, GR_PARAM, GR_PARAM_LEN); p += GR_PARAM_LEN - 1; *p++ = '\"'; } if (c->instance.len>0) { /* +sip-instance */ memcpy(p, SIP_INSTANCE_PARAM, SIP_INSTANCE_PARAM_LEN); p += SIP_INSTANCE_PARAM_LEN; *p++ = '\"'; memcpy(p, c->instance.s, c->instance.len); p += c->instance.len; *p++ = '\"'; } if (c->reg_id>0) { /* reg-id */ memcpy(p, REG_ID_PARAM, REG_ID_PARAM_LEN); p += REG_ID_PARAM_LEN; cp = int2str(c->reg_id, &len); memcpy(p, cp, len); p += len; } if(reg_xavp_rcd.s!=NULL) { memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_STR; xval.v.s = c->ruid; if(xavp_add_value(&xname, &xval, &xavp)==NULL) { LM_ERR("cannot add ruid value to xavp\n"); } } } c = c->next; }
/** * $xavp(name1[idx1]=>name2[idx2]) */ int pv_set_xavp(struct sip_msg* msg, pv_param_t *param, int op, pv_value_t *val) { pv_xavp_name_t *xname=NULL; sr_xavp_t *avp=NULL; sr_xavp_t *list=NULL; sr_xval_t xval; int idxf = 0; int idx = 0; int idxf1 = 0; int idx1 = 0; int count; if(param==NULL) { LM_ERR("bad parameters\n"); return -1; } xname = (pv_xavp_name_t*)param->pvn.u.dname; if(xname->index.type==PVT_EXTRA) { /* get the index */ if(pv_get_spec_index(msg, &xname->index.pvp, &idx, &idxf)!=0) { LM_ERR("invalid index\n"); return -1; } } if((val==NULL) || (val->flags&PV_VAL_NULL)) { if(xname->next==NULL) { if(xname->index.type==PVT_EXTRA) { if(idxf==PV_IDX_ALL) { xavp_rm_by_name(&xname->name, 1, NULL); return 0; } } if(idx==0) { xavp_rm_by_name(&xname->name, 0, NULL); return 0; } /* fix the index */ if(idx<0) { count = xavp_count(&xname->name, NULL); idx = count + idx + 1; } xavp_rm_by_index(&xname->name, idx, NULL); return 0; } if(xname->next->index.type==PVT_EXTRA) { /* get the index */ if(pv_get_spec_index(msg,&xname->next->index.pvp,&idx1,&idxf1)!=0) { LM_ERR("invalid index!\n"); return -1; } } if(idxf==PV_IDX_ALL) { /* iterate */ avp = xavp_get(&xname->name, NULL); while(avp) { if(avp->val.type==SR_XTYPE_XAVP) { if(xname->next->index.type==PVT_EXTRA) { if(idxf1==PV_IDX_ALL) { xavp_rm_by_name(&xname->next->name, 1, &avp->val.v.xavp); } else { /* fix the index */ idx = idx1; if(idx<0) { count = xavp_count(&xname->next->name, &avp->val.v.xavp); idx = count + idx1 + 1; } xavp_rm_by_index(&xname->next->name, idx, &avp->val.v.xavp); } } else { xavp_rm_by_name(&xname->next->name, 0, &avp->val.v.xavp); } } avp = xavp_get_next(avp); } return 0; } if(idx==0) { avp = xavp_get(&xname->name, NULL); } else { /* fix the index */ if(idx<0) { count = xavp_count(&xname->name, NULL); idx = count + idx + 1; } avp = xavp_get_by_index(&xname->name, idx, NULL); } if(avp) { if(avp->val.type==SR_XTYPE_XAVP) { if(xname->next->index.type==PVT_EXTRA) { if(idxf1==PV_IDX_ALL) { xavp_rm_by_name(&xname->next->name, 1, &avp->val.v.xavp); } else { /* fix the index */ idx = idx1; if(idx<0) { count = xavp_count(&xname->next->name, &avp->val.v.xavp); idx = count + idx1 + 1; } xavp_rm_by_index(&xname->next->name, idx, &avp->val.v.xavp); } } else { xavp_rm_by_name(&xname->next->name, 0, &avp->val.v.xavp); } } } return 0; } /* NULL assignment */ /* build xavp value */ memset(&xval, 0, sizeof(sr_xval_t)); if(val->flags&PV_TYPE_INT) { xval.type = SR_XTYPE_INT; xval.v.i = val->ri; } else { xval.type = SR_XTYPE_STR; xval.v.s = val->rs; } /* where to add */ if(xname->next==NULL) { /* xavp with single value */ if(xname->index.type==PVT_EXTRA) { if(idxf==PV_IDX_ALL) { /* ignore: should iterate and set same value to all xavps * with same name?!?! */ return -1; } /* fix the index */ if(idx<0) { count = xavp_count(&xname->name, NULL); idx = count + idx + 1; } /* set the value */ if(xavp_set_value(&xname->name, idx, &xval, NULL)==NULL) return -1; return 0; } /* add new value */ if(xavp_add_value(&xname->name, &xval, NULL)==NULL) return -1; return 0; } /* xavp with xavp list value */ if(xname->next->index.type==PVT_EXTRA) { /* get the index */ if(pv_get_spec_index(msg,&xname->next->index.pvp,&idx1,&idxf1)!=0) { LM_ERR("invalid index!\n"); return -1; } } if(xname->index.type==PVT_EXTRA) { /* set the value */ if(idxf==PV_IDX_ALL) { /* ignore: should iterate and set same value to all xavps * with same name?!?! */ return 0; } if(idx==0) { avp = xavp_get(&xname->name, NULL); } else { /* fix the index */ if(idx<0) { count = xavp_count(&xname->name, NULL); idx = count + idx + 1; } avp = xavp_get_by_index(&xname->name, idx, NULL); } if(avp==NULL) return 0; if(avp->val.type!=SR_XTYPE_XAVP) return -1; if(xname->next->index.type==PVT_EXTRA) { if(idxf1==PV_IDX_ALL) { /* ignore: should iterate and set same value to all xavps * with same name?!?! */ return 0; } /* fix the index */ idx = idx1; if(idx<0) { count = xavp_count(&xname->next->name, &avp->val.v.xavp); idx = count + idx1 + 1; } /* set value */ xavp_set_value(&xname->next->name, idx, &xval, &avp->val.v.xavp); return 0; } /* add new value in sublist */ if(xavp_add_value(&xname->next->name, &xval, &avp->val.v.xavp)==NULL) return -1; return 0; } /* add new xavp with xavp list */ if(xavp_add_value(&xname->next->name, &xval, &list)==NULL) return -1; /* build xavp value */ memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_XAVP; xval.v.xavp = list; xavp_add_value(&xname->name, &xval, NULL); return 0; }
int sql_exec_xquery(struct sip_msg *msg, sql_con_t *con, str *query, str *xavp) { db1_res_t* db_res = NULL; sr_xavp_t *row = NULL; sr_xval_t val; int i, j; if(msg==NULL || query==NULL || xavp==NULL) { LM_ERR("bad parameters\n"); return -1; } if(con->dbf.raw_query(con->dbh, query, &db_res)!=0) { LM_ERR("cannot do the query\n"); return -1; } if(db_res==NULL || RES_ROW_N(db_res)<=0 || RES_COL_N(db_res)<=0) { LM_DBG("no result after query\n"); con->dbf.free_result(con->dbh, db_res); return 2; } for(i=RES_ROW_N(db_res)-1; i>=0; i--) { row = NULL; for(j=RES_COL_N(db_res)-1; j>=0; j--) { if(RES_ROWS(db_res)[i].values[j].nul) { val.type = SR_XTYPE_NULL; } else { switch(RES_ROWS(db_res)[i].values[j].type) { case DB1_STRING: val.type = SR_XTYPE_STR; val.v.s.s= (char*)RES_ROWS(db_res)[i].values[j].val.string_val; val.v.s.len=strlen(val.v.s.s); break; case DB1_STR: val.type = SR_XTYPE_STR; val.v.s.len= RES_ROWS(db_res)[i].values[j].val.str_val.len; val.v.s.s= (char*)RES_ROWS(db_res)[i].values[j].val.str_val.s; break; case DB1_BLOB: val.type = SR_XTYPE_STR; val.v.s.len= RES_ROWS(db_res)[i].values[j].val.blob_val.len; val.v.s.s= (char*)RES_ROWS(db_res)[i].values[j].val.blob_val.s; break; case DB1_INT: val.type = SR_XTYPE_INT; val.v.i = (int)RES_ROWS(db_res)[i].values[j].val.int_val; break; case DB1_DATETIME: val.type = SR_XTYPE_INT; val.v.i = (int)RES_ROWS(db_res)[i].values[j].val.time_val; break; case DB1_BITMAP: val.type = SR_XTYPE_INT; val.v.i = (int)RES_ROWS(db_res)[i].values[j].val.bitmap_val; break; case DB1_BIGINT: val.type = SR_XTYPE_LLONG; val.v.ll = RES_ROWS(db_res)[i].values[j].val.ll_val; break; default: val.type = SR_XTYPE_NULL; } } /* Add column to current row, under the column's name */ LM_DBG("Adding column: %.*s\n", RES_NAMES(db_res)[j]->len, RES_NAMES(db_res)[j]->s); xavp_add_value(RES_NAMES(db_res)[j], &val, &row); } /* Add row to result xavp */ val.type = SR_XTYPE_XAVP; val.v.xavp = row; LM_DBG("Adding row\n"); xavp_add_value(xavp, &val, NULL); } con->dbf.free_result(con->dbh, db_res); return 1; }
/*! \brief * Lookup contact in the database and rewrite Request-URI * \return: -1 : not found * -2 : found but method not allowed * -3 : error */ int lookup(struct sip_msg* _m, udomain_t* _d, str* _uri) { urecord_t* r; str aor, uri; sip_uri_t puri; ucontact_t* ptr = 0; int res; int ret; str path_dst; flag_t old_bflags; int i; str inst = {0}; unsigned int ahash = 0; sr_xavp_t *xavp=NULL; sr_xavp_t *list=NULL; str xname = {"ruid", 4}; sr_xval_t xval; ret = -1; if (_m->new_uri.s) uri = _m->new_uri; else uri = _m->first_line.u.request.uri; if (extract_aor((_uri)?_uri:&uri, &aor, &puri) < 0) { LM_ERR("failed to extract address of record\n"); return -3; } /* check if gruu */ if(puri.gr.s!=NULL) { if(puri.gr_val.len>0) { /* pub-gruu */ inst = puri.gr_val; LM_DBG("looking up pub gruu [%.*s]\n", inst.len, inst.s); } else { /* temp-gruu */ ahash = 0; inst = puri.user; for(i=inst.len-1; i>=0; i--) { if(inst.s[i]==REG_GRUU_SEP) break; ahash <<= 4; if(inst.s[i] >='0' && inst.s[i] <='9') ahash+=inst.s[i] -'0'; else if (inst.s[i] >='a' && inst.s[i] <='f') ahash+=inst.s[i] -'a'+10; else if (inst.s[i] >='A' && inst.s[i] <='F') ahash+=inst.s[i] -'A'+10; else { LM_ERR("failed to extract temp gruu - invalid hash\n"); return -3; } } if(i<0) { LM_ERR("failed to extract temp gruu - invalid format\n"); return -3; } inst.len = i; LM_DBG("looking up temp gruu [%u / %.*s]\n", ahash, inst.len, inst.s); } } get_act_time(); if(puri.gr.s==NULL || puri.gr_val.len>0) { /* aor or pub-gruu lookup */ ul.lock_udomain(_d, &aor); res = ul.get_urecord(_d, &aor, &r); if (res > 0) { LM_DBG("'%.*s' Not found in usrloc\n", aor.len, ZSW(aor.s)); ul.unlock_udomain(_d, &aor); return -1; } ptr = r->contacts; ret = -1; /* look first for an un-expired and suported contact */ while (ptr) { if(VALID_CONTACT(ptr,act_time)) { if(allowed_method(_m,ptr)) { /* match on instance, if pub-gruu */ if(inst.len>0) { if(reg_cmp_instances(&inst, &ptr->instance)==0) { /* pub-gruu - found by instance */ LM_DBG("contact for [%.*s] found by pub gruu [%.*s]\n", aor.len, ZSW(aor.s), inst.len, inst.s); break; } } else { /* no-gruu - found by address */ LM_DBG("contact for [%.*s] found by address\n", aor.len, ZSW(aor.s)); break; } } else { LM_DBG("contact for [%.*s] cannot handle the SIP method\n", aor.len, ZSW(aor.s)); ret = -2; } } ptr = ptr->next; } if (ptr==0) { /* nothing found */ LM_DBG("'%.*s' has no valid contact in usrloc\n", aor.len, ZSW(aor.s)); goto done; } } else { /* temp-gruu lookup */ res = ul.get_urecord_by_ruid(_d, ahash, &inst, &r, &ptr); if(res<0) { LM_DBG("temp gruu '%.*s' not found in usrloc\n", aor.len, ZSW(aor.s)); return -1; } aor = *ptr->aor; /* test if un-expired and suported contact */ if( (ptr) && !(VALID_CONTACT(ptr,act_time) && (ret=-2) && allowed_method(_m,ptr))) goto done; LM_DBG("contact for [%.*s] found by temp gruu [%.*s / %u]\n", aor.len, ZSW(aor.s), inst.len, inst.s, ahash); } ret = 1; if (ptr) { if (rewrite_uri(_m, &ptr->c) < 0) { LM_ERR("unable to rewrite Request-URI\n"); ret = -3; goto done; } /* reset next hop address */ reset_dst_uri(_m); /* add xavp with details of the record (ruid, ...) */ if(reg_xavp_rcd.s!=NULL) { list = xavp_get(®_xavp_rcd, NULL); xavp = list; memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_STR; xval.v.s = ptr->ruid; xavp_add_value(&xname, &xval, &xavp); if(list==NULL) { /* no reg_xavp_rcd xavp in root list - add it */ xval.type = SR_XTYPE_XAVP; xval.v.xavp = xavp; xavp_add_value(®_xavp_rcd, &xval, NULL); } } /* If a Path is present, use first path-uri in favour of * received-uri because in that case the last hop towards the uac * has to handle NAT. - agranig */ if (ptr->path.s && ptr->path.len) { if (get_path_dst_uri(&ptr->path, &path_dst) < 0) { LM_ERR("failed to get dst_uri for Path\n"); ret = -3; goto done; } if (set_path_vector(_m, &ptr->path) < 0) { LM_ERR("failed to set path vector\n"); ret = -3; goto done; } if (set_dst_uri(_m, &path_dst) < 0) { LM_ERR("failed to set dst_uri of Path\n"); ret = -3; goto done; } } else if (ptr->received.s && ptr->received.len) { if (set_dst_uri(_m, &ptr->received) < 0) { ret = -3; goto done; } } if (ptr->instance.len) { if (set_instance(_m, &(ptr->instance)) < 0) { ret = -3; goto done; } } _m->reg_id = ptr->reg_id; if (ptr->ruid.len) { if (set_ruid(_m, &(ptr->ruid)) < 0) { ret = -3; goto done; } } if (ptr->user_agent.len) { if (set_ua(_m, &(ptr->user_agent)) < 0) { ret = -3; goto done; } } set_ruri_q(ptr->q); old_bflags = 0; getbflagsval(0, &old_bflags); setbflagsval(0, old_bflags|ptr->cflags); if (ptr->sock) set_force_socket(_m, ptr->sock); if(ptr->xavp!=NULL) { xavp = xavp_clone_level_nodata(ptr->xavp); if(xavp_add(xavp, NULL)<0) { ret = -3; goto done; } } ptr = ptr->next; } /* if was gruu, no more branches */ if(inst.len>0) goto done; /* Append branches if enabled */ if (!cfg_get(registrar, registrar_cfg, append_branches)) goto done; for( ; ptr ; ptr = ptr->next ) { if (VALID_CONTACT(ptr, act_time) && allowed_method(_m, ptr)) { path_dst.len = 0; if(ptr->path.s && ptr->path.len && get_path_dst_uri(&ptr->path, &path_dst) < 0) { LM_ERR("failed to get dst_uri for Path\n"); continue; } /* The same as for the first contact applies for branches * regarding path vs. received. */ LM_DBG("instance is %.*s\n", ptr->instance.len, ptr->instance.s); if (append_branch(_m, &ptr->c, path_dst.len?&path_dst:&ptr->received, &ptr->path, ptr->q, ptr->cflags, ptr->sock, ptr->instance.len?&(ptr->instance):0, ptr->instance.len?ptr->reg_id:0, &ptr->ruid, &ptr->user_agent) == -1) { LM_ERR("failed to append a branch\n"); /* Also give a chance to the next branches*/ continue; } if(ptr->xavp!=NULL) { xavp = xavp_clone_level_nodata(ptr->xavp); if(xavp_insert(xavp, nr_branches, NULL)<0) { ret = -3; goto done; } } } } done: ul.release_urecord(r); ul.unlock_udomain(_d, &aor); return ret; }
int rtjson_init_routes(sip_msg_t *msg, str *rdoc) { srjson_Hooks jhooks; srjson_doc_t *tdoc = NULL; sr_data_t *xdata = NULL; rtjson_data_t *rdata = NULL; sr_xavp_t *xavp=NULL; str xname; sr_xval_t xval; memset(&jhooks, 0, sizeof(srjson_Hooks)); jhooks.malloc_fn = rtjson_malloc; jhooks.free_fn = rtjson_free; tdoc = srjson_NewDoc(&jhooks); if(tdoc==NULL) { LM_ERR("no more shm\n"); return -1; } tdoc->root = srjson_Parse(tdoc, rdoc->s); if(tdoc->root == NULL) { LM_ERR("invalid json doc [[%s]]\n", rdoc->s); srjson_DeleteDoc(tdoc); return -1; } xdata = shm_malloc(sizeof(sr_data_t)); if(xdata==NULL) { LM_ERR("no more shm\n"); srjson_DeleteDoc(tdoc); return -1; } memset(xdata, 0, sizeof(sr_data_t)); rdata = shm_malloc(sizeof(rtjson_data_t)); if(rdata==NULL) { LM_ERR("no more shm\n"); srjson_DeleteDoc(tdoc); shm_free(xdata); return -1; } memset(rdata, 0, sizeof(rtjson_data_t)); rdata->jdoc = tdoc; xdata->p = rdata; xdata->pfree = rtjson_data_free; memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_STR; xval.v.s = *rdoc; xname.s = "json"; xname.len = 4; if(xavp_add_value(&xname, &xval, &xavp)==NULL) { goto error; } memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_DATA; xval.v.data = xdata; xname.s = "data"; xname.len = 4; if(xavp_add_value(&xname, &xval, &xavp)==NULL) { goto error; } /* reset pointers - they are linked inside xavp now */ tdoc = NULL; xdata = NULL; rdata = NULL; memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_XAVP; xval.v.xavp = xavp; if(xavp_add_value(&_rtjson_xavp_name, &xval, NULL)==NULL) { goto error; } return 0; error: if(xavp) xavp_destroy_list(&xavp); if(rdata) shm_free(rdata); if(xdata) shm_free(xdata); if(tdoc) srjson_DeleteDoc(tdoc); return -1; }