Esempio n. 1
0
/*! \brief
 * Calculate contact q value as follows:
 * 1) If xavp_cfg q has been defined, use it
 * 2) If q parameter exists in contact, use it
 * 3) If the parameter doesn't exist in contact, use the default value
 */
int calc_contact_q(param_t* _q, qvalue_t* _r)
{
	sr_xavp_t *vavp = NULL;
	str xqname = str_init("q");

	if (reg_xavp_cfg.s != NULL)
		vavp = xavp_get_child_with_ival(&reg_xavp_cfg, &xqname);

	if (vavp != NULL) {
		if ((vavp->val.v.i >= 0) && (vavp->val.v.i <= 1000)) {
			*_r = vavp->val.v.i;
			return 0;
		} else {
			rerrno = R_INV_Q; /* Invalid q parameter */
			LM_ERR("invalid q parameter\n");
			return -1;
		}
	}

	if (!_q || (_q->body.len == 0)) {
		*_r = cfg_get(registrar, registrar_cfg, default_q);
	} else {
		if (str2q(_r, _q->body.s, _q->body.len) < 0) {
			rerrno = R_INV_Q; /* Invalid q parameter */
			LM_ERR("invalid q parameter\n");
			return -1;
		}
	}

	return 0;
}
Esempio n. 2
0
/**
 * append new branches with generic parameters
 */
int corex_append_branch(sip_msg_t *msg, gparam_t *pu, gparam_t *pq)
{
	str uri = {0};
	str qv = {0};
	int ret = 0;

	qvalue_t q = Q_UNSPECIFIED;
	flag_t branch_flags = 0;

	if (pu!=NULL)
	{
		if(fixup_get_svalue(msg, pu, &uri)!=0)
		{
			LM_ERR("cannot get the URI parameter\n");
			return -1;
		}
	}

	if (pq!=NULL)
	{
		if(fixup_get_svalue(msg, pq, &qv)!=0)
		{
			LM_ERR("cannot get the Q parameter\n");
			return -1;
		}
		if(qv.len>0 && str2q(&q, qv.s, qv.len)<0)
		{
			LM_ERR("cannot parse the Q parameter\n");
			return -1;
		}
	}


	getbflagsval(0, &branch_flags);
	ret = append_branch(msg, (uri.len>0)?&uri:0, &msg->dst_uri,
			    &msg->path_vec, q, branch_flags,
			    msg->force_send_socket, 0, 0, 0, 0);


	if(uri.len<=0)
	{
		/* reset all branch attributes if r-uri was shifted to branch */
		reset_force_socket(msg);
		setbflagsval(0, 0);
		if(msg->dst_uri.s!=0)
			pkg_free(msg->dst_uri.s);
		msg->dst_uri.s = 0;
		msg->dst_uri.len = 0;

		/* if this is a cloned message, don't free the path vector as it was copied into shm memory and will be freed as contiguous block*/
		if (!(msg->msg_flags&FL_SHM_CLONE)) {
			if(msg->path_vec.s!=0)
				pkg_free(msg->path_vec.s);
			msg->path_vec.s = 0;
			msg->path_vec.len = 0;
		}
	}

	return ret;
}
Esempio n. 3
0
/* returns the number of contacts put in the sorted array */
static int sort_contacts(hdr_field_t *chdr, contact_t **ct_array,
														qvalue_t *q_array)
{
	param_t *q_para;
	qvalue_t q;
	int n;
	int i,j;
	char backup;
	contact_t *ct_list;
	hdr_field_t *hdr;

	n = 0; /* number of sorted contacts */

	for(hdr=chdr; hdr; hdr=hdr->next) {
		if(hdr->type != HDR_CONTACT_T) continue;
		ct_list = ((contact_body_t*)hdr->parsed)->contacts;
		for( ; ct_list ; ct_list = ct_list->next ) {
			/* check the filters first */
			backup = ct_list->uri.s[ct_list->uri.len];
			ct_list->uri.s[ct_list->uri.len] = 0;
			if ( run_filters( ct_list->uri.s )==-1 ){
				ct_list->uri.s[ct_list->uri.len] = backup;
				continue;
			}
			ct_list->uri.s[ct_list->uri.len] = backup;
			/* does the contact has a q val? */
			q_para = ct_list->q;
			if (q_para==0 || q_para->body.len==0) {
				q = DEFAULT_Q_VALUE;
			} else {
				if (str2q( &q, q_para->body.s, q_para->body.len)!=0) {
					LM_ERR("invalid q param\n");
					/* skip this contact */
					continue;
				}
			}
			LM_DBG("sort_contacts: <%.*s> q=%d\n",
					ct_list->uri.len,ct_list->uri.s,q);
			/*insert the contact into the sorted array */
			for(i=0;i<n;i++) {
				/* keep in mind that the contact list is reversed */
				if (q_array[i]<=q)
					continue;
				break;
			}
			if (i!=MAX_CONTACTS_PER_REPLY) {
				/* insert the contact at this position */
				for( j=n-1-1*(n==MAX_CONTACTS_PER_REPLY) ; j>=i ; j-- ) {
					ct_array[j+1] = ct_array[j];
					q_array[j+1] = q_array[j];
				}
				ct_array[j+1] = ct_list;
				q_array[j+1] = q;
				if (n!=MAX_CONTACTS_PER_REPLY)
					n++;
			}
		}
	}
	return n;
}
Esempio n. 4
0
/*
 * Read in a literal real number and add it to the table of constant numbers,
 * creating a new entry if necessary.  The incoming number is a string
 * value which must have a correct format.
 * Returns the index of the number in the constant table.
 *
 * given:
 *	str		string representation of number
 */
long
addnumber(char *str)
{
	NUMBER *q;

	q = str2q(str);
	return addqconstant(q);
}
Esempio n. 5
0
/**
 * append new branches with generic parameters
 */
int corex_append_branch(sip_msg_t *msg, gparam_t *pu, gparam_t *pq)
{
	str uri = {0};
	str qv = {0};
	int ret = 0;

	qvalue_t q = Q_UNSPECIFIED;
	flag_t branch_flags = 0;

	if (pu!=NULL)
	{
		if(fixup_get_svalue(msg, pu, &uri)!=0)
		{
			LM_ERR("cannot get the URI parameter\n");
			return -1;
		}
	}

	if (pq!=NULL)
	{
		if(fixup_get_svalue(msg, pq, &qv)!=0)
		{
			LM_ERR("cannot get the Q parameter\n");
			return -1;
		}
		if(qv.len>0 && str2q(&q, qv.s, qv.len)<0)
		{
			LM_ERR("cannot parse the Q parameter\n");
			return -1;
		}
	}


	getbflagsval(0, &branch_flags);
	ret = append_branch(msg, (uri.len>0)?&uri:0, &msg->dst_uri,
			    &msg->path_vec, q, branch_flags,
			    msg->force_send_socket, 0, 0);


	if(uri.len<=0)
	{
		/* reset all branch attributes if r-uri was shifted to branch */
		reset_force_socket(msg);
		setbflagsval(0, 0);
		if(msg->dst_uri.s!=0)
			pkg_free(msg->dst_uri.s);
		msg->dst_uri.s = 0;
		msg->dst_uri.len = 0;
		if(msg->path_vec.s!=0)
			pkg_free(msg->path_vec.s);
		msg->path_vec.s = 0;
		msg->path_vec.len = 0;
	}

	return ret;
}
Esempio n. 6
0
int regapi_set_q_override(sip_msg_t *msg, str *new_q)
{
	int _q;
	if (str2q(&_q, new_q->s, new_q->len) < 0)
	{
		LM_ERR("invalid q parameter\n");
		return -1;
	}
	return set_q_override(msg, _q);
}
Esempio n. 7
0
/* returns the number of contacts put in the sorted array */
static int sort_contacts(contact_t *ct_list, contact_t **ct_array)
{
	static qvalue_t q_array[MAX_CONTACTS_PER_REPLY];
	param_t *q_para;
	qvalue_t q;
	int n;
	int i,j;
	char backup;

	n = 0; /* number of sorted contacts */

	for( ; ct_list ; ct_list = ct_list->next ) {
		/* check the filters first */
		backup = ct_list->uri.s[ct_list->uri.len];
		ct_list->uri.s[ct_list->uri.len] = 0;
		if ( run_filters( ct_list->uri.s )==-1 ){
			ct_list->uri.s[ct_list->uri.len] = backup;
			continue;
		}
		ct_list->uri.s[ct_list->uri.len] = backup;
		/* does the contact has a q val? */
		q_para = ct_list->q;
		if (q_para==0 || q_para->body.len==0) {
			q = DEFAULT_Q_VALUE;
		} else {
			if (str2q( &q, q_para->body.s, q_para->body.len)!=0) {
				LOG(L_ERR, "ERROR:uac_redirect:sort_contacts: "
					"invalid q param\n");
				/* skip this contact */
				continue;
			}
		}
		DBG("DEBUG:uac_redirect:sort_contacts: <%.*s> q=%d\n",
				ct_list->uri.len,ct_list->uri.s,q);
		/*insert the contact into the sorted array */
		for(i=0;i<n;i++) {
			/* keep in mind that the contact list is reversts */
			if (q_array[i]<q)
				continue;
			break;
		}
		if (i!=MAX_CONTACTS_PER_REPLY) {
			/* insert the contact at this position */
			for( j=n-1-1*(n==MAX_CONTACTS_PER_REPLY) ; j>=i ; j-- ) {
				ct_array[j+1] = ct_array[j];
				q_array[j+1] = q_array[j];
			}
			ct_array[j+1] = ct_list;
			q_array[j+1] = q;
			if (n!=MAX_CONTACTS_PER_REPLY)
				n++;
		}
	}
	return n;
}
Esempio n. 8
0
/*! \brief
 * Calculate contact q value as follows:
 * 1) If q parameter exists, use it
 * 2) If the parameter doesn't exist, use the default value
 */
int calc_contact_q(param_t* _q, qvalue_t* _r) {
	if (!_q || (_q->body.len == 0)) {
		*_r = cfg_get(registrar, registrar_cfg, default_q);
	} else {
		if (str2q(_r, _q->body.s, _q->body.len) < 0) {
			rerrno = R_INV_Q; /* Invalid q parameter */
			LM_ERR("invalid q parameter\n");
			return -1;
		}
	}
	return 0;
}
Esempio n. 9
0
/* returns the number of contacts put in the sorted array */
static void sort_contacts(contact_t *ct_list, str *ct_array,
													qvalue_t *q_array, int *n)
{
	param_t *q_para;
	qvalue_t q;
	int i, j, rc;
	char backup;

	for( ; ct_list ; ct_list = ct_list->next ) {
		/* check the filters first */
		backup = ct_list->uri.s[ct_list->uri.len];
		ct_list->uri.s[ct_list->uri.len] = 0;
		if ( run_filters( ct_list->uri.s )==-1 ){
			ct_list->uri.s[ct_list->uri.len] = backup;
			continue;
		}
		ct_list->uri.s[ct_list->uri.len] = backup;
		/* does the contact has a q val? */
		q_para = ct_list->q;
		if (q_para==0 || q_para->body.len==0) {
			q = DEFAULT_Q_VALUE;
		} else {
			rc = str2q( &q, q_para->body.s, q_para->body.len);
			if (rc != 0) {
				LM_ERR("invalid qvalue (%.*s): %s\n",
						q_para->body.len, q_para->body.s, qverr2str(rc));
				/* skip this contact */
				continue;
			}
		}
		LM_DBG("sort_contacts: <%.*s> q=%d\n",
				ct_list->uri.len,ct_list->uri.s,q);
		/*insert the contact into the sorted array */
		for(i=0;i<*n;i++) {
			/* keep in mind that the contact list is reversts */
			if (q_array[i]<=q)
				continue;
			break;
		}
		if (i!=MAX_CONTACTS_PER_REPLY) {
			/* insert the contact at this position */
			for( j=(*n)-1-1*((*n)==MAX_CONTACTS_PER_REPLY) ; j>=i ; j-- ) {
				ct_array[j+1] = ct_array[j];
				q_array[j+1] = q_array[j];
			}
			ct_array[j+1] = ct_list->uri;
			q_array[j+1] = q;
			if ((*n)!=MAX_CONTACTS_PER_REPLY)
				(*n)++;
		}
	}
}
Esempio n. 10
0
/*
 * Calculate contact q value as follows:
 * 1) If q parameter exists, use it
 * 2) If the parameter doesn't exist, use the default value
 */
int calc_contact_q(param_t* _q, qvalue_t* _r)
{
	if (!_q || (_q->body.len == 0)) {
		*_r = default_q;
	} else {
		if (str2q(_r, _q->body.s, _q->body.len) < 0) {
			rerrno = R_INV_Q; /* Invalid q parameter */
			LOG(L_ERR, "calc_contact_q(): Invalid q parameter\n");
			return -1;
		}
	}
	return 0;
}
Esempio n. 11
0
/*!
 * \brief Add a new contact for an address of record
 * \param cmd mi_root containing the parameter
 * \param param not used
 * \note Expects 7 nodes: table name, AOR, contact, expires, Q,
 * useless - backward compatible, flags, cflags, methods
 * \return mi_root with the result
 */
struct mi_root* mi_usrloc_add(struct mi_root *cmd, void *param)
{
	ucontact_info_t ci;
	urecord_t* r;
	ucontact_t* c;
	struct mi_node *node;
	udomain_t *dom;
	str *aor, *contact;
	unsigned int ui_val;
	int n;

	for( n=0,node = cmd->node.kids; n<9 && node ; n++,node=node->next );
	if (n!=9 || node!=0)
		return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);

	node = cmd->node.kids;

	/* look for table (param 1) */
	dom = mi_find_domain( &node->value );
	if (dom==NULL)
		return init_mi_tree( 404, "Table not found", 15);

	/* process the aor (param 2) */
	node = node->next;
	aor = &node->value;
	if ( mi_fix_aor(aor)!=0 )
		return init_mi_tree( 400, "Domain missing in AOR", 21);

	/* contact (param 3) */
	node = node->next;
	contact = &node->value;

	memset( &ci, 0, sizeof(ucontact_info_t));

	/* expire (param 4) */
	node = node->next;
	if (str2int( &node->value, &ui_val) < 0)
		goto bad_syntax;
	ci.expires = ui_val;

	/* q value (param 5) */
	node = node->next;
	if (str2q( &ci.q, node->value.s, node->value.len) < 0)
		goto bad_syntax;

	/* unused value (param 6) FIXME */
	node = node->next;

	/* flags value (param 7) */
	node = node->next;
	if (str2int( &node->value, (unsigned int*)&ci.flags) < 0)
		goto bad_syntax;

	/* branch flags value (param 8) */
	node = node->next;
	if (str2int( &node->value, (unsigned int*)&ci.cflags) < 0)
		goto bad_syntax;

	/* methods value (param 9) */
	node = node->next;
	if (str2int( &node->value, (unsigned int*)&ci.methods) < 0)
		goto bad_syntax;

	if(sruid_next(&_ul_sruid)<0)
		goto error;
	ci.ruid = _ul_sruid.uid;

	lock_udomain( dom, aor);

	n = get_urecord( dom, aor, &r);
	if ( n==1) {
		if (insert_urecord( dom, aor, &r) < 0)
			goto lock_error;
		c = 0;
	} else {
		if (get_ucontact( r, contact, &mi_ul_cid, &mi_ul_path, MI_UL_CSEQ+1, &c) < 0)
			goto lock_error;
	}

	get_act_time();

	ci.callid = &mi_ul_cid;
	ci.user_agent = &mi_ul_ua;
	ci.cseq = MI_UL_CSEQ;
	/* 0 expires means permanent contact */
	if (ci.expires!=0)
		ci.expires += act_time;

	if (c) {
		if (update_ucontact( r, c, &ci) < 0)
			goto release_error;
	} else {
		if ( insert_ucontact( r, contact, &ci, &c) < 0 )
			goto release_error;
	}

	release_urecord(r);

	unlock_udomain( dom, aor);

	return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
bad_syntax:
	return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
release_error:
	release_urecord(r);
lock_error:
	unlock_udomain( dom, aor);
error:
	return init_mi_tree( 500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN);
}
Esempio n. 12
0
static int ul_add(FILE* pipe, char* response_file)
{
	char table_s[MAX_TABLE];
	char user_s[MAX_USER];
	char contact_s[MAX_CONTACT_LEN];
	char expires_s[MAX_EXPIRES_LEN];
	char q_s[MAX_Q_LEN];
	char rep_s[MAX_REPLICATE_LEN];
	char flags_s[MAX_FLAGS_LEN];
	udomain_t* d;
	int exp_i, flags_i;
	char* at;
	qvalue_t qval;

	str table, user, contact, expires, q, rep, flags;

	if (!read_line(table_s, MAX_TABLE, pipe, &table.len) || table.len == 0) {
		fifo_reply(response_file,
			   "400 ul_add: table name expected\n");
		LOG(L_ERR, "ERROR: ul_add: table name expected\n");
		return 1;
	}
	
	if (!read_line(user_s, MAX_USER, pipe, &user.len) || user.len  == 0) {
		fifo_reply(response_file,
			   "400 ul_add: aor name expected\n");
		LOG(L_ERR, "ERROR: ul_add: aor expected\n");
		return 1;
	}

	at = memchr(user_s, '@', user.len);

	if (use_domain) {
		if (!at) {
			fifo_reply(response_file,
				   "400 ul_add: username@domain expected\n");
			LOG(L_ERR, "ERROR: ul_add: Domain missing\n");
			return 1;
		}
	} else {
		if (at) {
			user.len = at - user_s;
		}
	}

	if (!read_line(contact_s, MAX_CONTACT_LEN, pipe, &contact.len) || contact.len == 0) {
		fifo_reply(response_file,
			   "400 ul_add: contact expected\n");
		LOG(L_ERR, "ERROR: ul_add: contact expected\n");
		return 1;
	}
	
	if (!read_line(expires_s, MAX_EXPIRES_LEN, pipe, &expires.len) || expires.len == 0) {
		fifo_reply(response_file,
			   "400 ul_add: expires expected\n");
		LOG(L_ERR, "ERROR: ul_add: expires expected\n");
		return 1;
	}
	
	if (!read_line(q_s, MAX_Q, pipe, &q.len) || q.len == 0) {
		fifo_reply(response_file,
			   "400 ul_add: q expected\n");
		LOG(L_ERR, "ERROR: ul_add: q expected\n");
		return 1;
	}

	     /* Kept for backwards compatibility */
	if (!read_line(rep_s, MAX_REPLICATE_LEN, pipe, &rep.len) || rep.len == 0) {
		fifo_reply(response_file,
			   "400 ul_add: replicate expected\n");
		LOG(L_ERR, "ERROR: ul_add: replicate expected\n");
		return 1;
	}

	if (!read_line(flags_s, MAX_FLAGS_LEN, pipe, &flags.len) || flags.len == 0) {
		fifo_reply(response_file,
			   "400 ul_add: flags expected\n");
		LOG(L_ERR, "ERROR: ul_add: flags expected\n");
		return 1;
	}
	
	table.s = table_s;
	user.s = user_s;
	strlower(&user);

	contact.s = contact_s;
	expires.s = expires_s;
	q.s = q_s;
	flags.s = flags_s;
	
	fifo_find_domain(&table, &d);
	
	if (d) {
		if (str2int(&expires, (unsigned int*)&exp_i) < 0) {
			fifo_reply(response_file, "400 Invalid expires format\n");
			return 1;
		}

		if (str2q(&qval, q.s, q.len) < 0) {
			fifo_reply(response_file, "400 Invalid q value\n");
			return 1;
		}

		if (str2int(&flags, (unsigned int*)&flags_i) < 0) {
			fifo_reply(response_file, "400 Invalid flags format\n");
			return 1;
		}
		
		lock_udomain(d);
		
		if (add_contact(d, &user, &contact, exp_i, qval, flags_i) < 0) {
			unlock_udomain(d);
			LOG(L_ERR, "ul_add(): Error while adding contact ('%.*s','%.*s') in table '%.*s'\n",
			    user.len, ZSW(user.s), contact.len, ZSW(contact.s), table.len, ZSW(table.s));
			fifo_reply(response_file, "500 Error while adding contact\n"
				   " ('%.*s','%.*s') in table '%.*s'\n",
				   user.len, ZSW(user.s), contact.len, ZSW(contact.s), table.len, ZSW(table.s));
			return 1;
		}
		unlock_udomain(d);
		
		fifo_reply(response_file, "200 Added to table\n"
				"('%.*s','%.*s') to '%.*s'\n",
			   user.len, ZSW(user.s), contact.len, ZSW(contact.s), table.len, ZSW(table.s));
		return 1;
	} else {
		fifo_reply(response_file, "400 Table '%.*s' not found in memory, use save(\"%.*s\") or lookup(\"%.*s\") in the configuration script first\n", 
			table.len, ZSW(table.s), table.len, ZSW(table.s), table.len, ZSW(table.s));
		return 1;
	}
}