Beispiel #1
0
int reg_get_crt_max_contacts(void)
{
	int n;
	sr_xavp_t *ravp=NULL;
	sr_xavp_t *vavp=NULL;
	str vname = {"max_contacts", 12};

	n = 0;

	if(reg_xavp_cfg.s!=NULL)
	{
		ravp = xavp_get(&reg_xavp_cfg, NULL);
		if(ravp!=NULL && ravp->val.type==SR_XTYPE_XAVP)
		{
			vavp = xavp_get(&vname, ravp->val.v.xavp);
			if(vavp!=NULL && vavp->val.type==SR_XTYPE_INT)
			{
				n = vavp->val.v.i;
				LM_ERR("using max contacts value from xavp: %d\n", n);
			} else {
				ravp = NULL;
			}
		} else {
			ravp = NULL;
		}
	}

	if(ravp==NULL)
	{
		n = cfg_get(registrar, registrar_cfg, max_contacts);
	}

	return n;
}
Beispiel #2
0
/**
 * return child node of an xavp
 * - $xavp(rname=>cname)
 */
sr_xavp_t* xavp_get_child(str *rname, str *cname)
{
	sr_xavp_t *ravp=NULL;

	ravp = xavp_get(rname, NULL);
	if(ravp==NULL || ravp->val.type!=SR_XTYPE_XAVP)
		return NULL;

	return xavp_get(cname, ravp->val.v.xavp);
}
Beispiel #3
0
sr_xavp_t *xavp_get_xbuffs()
{
	sr_xavp_t *list;
	list = xavp_get(&xbuff_list,NULL);

	if(!list) counter = 0;

	return list;
}
Beispiel #4
0
int xavp_serialize_fields(str *rname, char *obuf, int olen)
{
	sr_xavp_t *ravp = NULL;
	sr_xavp_t *avp = NULL;
	str ostr;
	int rlen;

	ravp = xavp_get(rname, NULL);
	if(ravp==NULL || ravp->val.type!=SR_XTYPE_XAVP) {
		/* not found or not holding subfields */
		return 0;
	}

	rlen = 0;
	ostr.s = obuf;
	avp = ravp->val.v.xavp;
	while(avp) {
		switch(avp->val.type) {
			case SR_XTYPE_INT:
				LM_DBG("     XAVP int value: %d\n", avp->val.v.i);
				ostr.len = snprintf(ostr.s, olen-rlen, "%.*s=%u;",
						avp->name.len, avp->name.s, (unsigned int)avp->val.v.i);
				if(ostr.len<=0 || ostr.len>=olen-rlen) {
					LM_ERR("failed to serialize int value (%d/%d\n",
							ostr.len, olen-rlen);
					return -1;
				}
			break;
			case SR_XTYPE_STR:
				LM_DBG("     XAVP str value: %s\n", avp->val.v.s.s);
				ostr.len = snprintf(ostr.s, olen-rlen, "%.*s=%.*s;",
						avp->name.len, avp->name.s,
						avp->val.v.s.len, avp->val.v.s.s);
				if(ostr.len<=0 || ostr.len>=olen-rlen) {
					LM_ERR("failed to serialize int value (%d/%d\n",
							ostr.len, olen-rlen);
					return -1;
				}
			break;
			default:
				LM_DBG("skipping value type: %d\n", avp->val.type);
				ostr.len = 0;
		}
		if(ostr.len>0) {
			ostr.s += ostr.len;
			rlen += ostr.len;
		}
		avp = avp->next;
	}
	return rlen;
}
Beispiel #5
0
/*! \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(&reg_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(&reg_xavp_rcd, &xval, NULL)==NULL) {
			LM_ERR("cannot add ruid xavp to root list\n");
			xavp_destroy_list(xavp);
		}
	}
	return 0;
}
Beispiel #6
0
/*! \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(&reg_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;
	}
Beispiel #7
0
/**
 * $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;
}
Beispiel #8
0
/*! \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(&reg_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(&reg_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;
}
Beispiel #9
0
int k_sd_journal_send_xavp(str *rname)
{
	struct _sr_xavp *rxavp, *nxavp;
	int cnt, buflen, i, ret;
	struct iovec *logv;

	rxavp = xavp_get(rname, NULL);

	if (!rxavp || rxavp->val.type != SR_XTYPE_XAVP) {
		LM_ERR("not a valid xavp: %.*s?\n", rname->len, rname->s);
	}

	/* first, count xavp nodes */
	for (nxavp = rxavp->val.v.xavp, cnt = 0;
			nxavp;
			nxavp = nxavp->next, cnt++);

	if (cnt == 0) {
		/* nothing to log? */
		LM_NOTICE("empty xavp: %.*s?, no log event was sent to journald\n",
				rname->len,
				rname->s);
		return 1;
	}

	logv = pkg_malloc(cnt * sizeof (struct iovec));

	if (!logv) {
		LM_ERR("failed to allocate pkg memory\n");
		return -1;
	}

	ret = -1;

	for (nxavp = rxavp->val.v.xavp, cnt = 0;
			nxavp;
			nxavp = nxavp->next, cnt++)
	{
		if (nxavp->val.type == SR_XTYPE_INT) {
			buflen = snprintf(NULL, 0,
					"%.*s=%d",
					nxavp->name.len, nxavp->name.s,
					nxavp->val.v.i);
			logv[cnt].iov_base = pkg_malloc(buflen + 1/*snprintf's trailing \0*/);
			if (!logv[cnt].iov_base ) {
				LM_ERR("failed to allocate pkg memory\n");
				goto free;
			}
			logv[cnt].iov_len = buflen;

			snprintf(logv[cnt].iov_base, buflen + 1,
					"%.*s=%d",
					nxavp->name.len, nxavp->name.s,
					nxavp->val.v.i);
		} else if (nxavp->val.type == SR_XTYPE_STR) {
			buflen = nxavp->name.len + 1 + nxavp->val.v.s.len;
			logv[cnt].iov_base = pkg_malloc(buflen);
			if (!logv[cnt].iov_base) {
				LM_ERR("failed to allocate pkg memory\n");
				goto free;
			}
			logv[cnt].iov_len = buflen;

			memcpy(logv[cnt].iov_base, nxavp->name.s, nxavp->name.len);
			((char*)logv[cnt].iov_base)[nxavp->name.len] = '=';
			memcpy(((char*)(logv[cnt].iov_base)) + nxavp->name.len + 1,
					nxavp->val.v.s.s,
					nxavp->val.v.s.len);
		} else {
			LM_NOTICE("unsupported type %d for field %.*s, skipped...\n",
					nxavp->val.type,
					nxavp->name.len, nxavp->name.s);
			logv[cnt].iov_len = 0;
			logv[cnt].iov_base = NULL;
		}
		LM_DBG("added io slice %d: %.*s\n", cnt, (int)logv[cnt].iov_len, (char*)logv[cnt].iov_base);
	}

	if (sd_journal_sendv(logv, cnt) != 0) {
		LM_ERR("sd_journal_sendv() failed\n");
	} else {
		ret = 1;
	}

free:
	for (i = 0 ; i < cnt ; i++) {
		if (logv[i].iov_base) pkg_free(logv[i].iov_base);
	}
	pkg_free(logv);
	return ret;
}