Пример #1
0
/* Adds a new separate partition and loads all rules from database in shm */
dp_connection_list_p dp_add_connection(dp_head_p head)
{
	dp_connection_list_t *el;

	if ((el = dp_get_connection(&head->partition)) != NULL){
		return el;
	}

	el = shm_malloc(sizeof(dp_connection_list_t));

	if (!el) {
		LM_ERR("No more shm mem\n");
		return NULL;
	}

	memset(el, 0, sizeof(dp_connection_list_t));

	/* create & init lock */
	if((el->ref_lock = lock_init_rw()) == NULL) {
		LM_ERR("Failed to init lock\n");
		shm_free(el);
		return NULL;
	}

	/*Set table name*/
	el->table_name = head->dp_table_name;

	/*Set partition*/
	el->partition = head->partition;

	/*Set db_url*/
	el->db_url = head->dp_db_url;

	el->dp_db_handle = pkg_malloc(sizeof(db_con_t*));
	if (!el->dp_db_handle) {
		LM_ERR("No more shm mem\n");
		return NULL;
	}

	*el->dp_db_handle = 0;

	/* *el->dp_db_handle is set to null at the end of test_db;
	 * no need to do it again here */
	if (test_db(el) != 0) {
		LM_ERR("Unable to test db\n");
		shm_free(el);
		return NULL;
	}

	el->next = dp_conns;
	dp_conns = el;

	LM_DBG("Added dialplan partition [%.*s] table [%.*s].\n",
		 head->partition.len, head->partition.s,
				head->dp_table_name.len, head->dp_table_name.s);

	return el;
}
Пример #2
0
static struct mi_root * mi_show_partition(struct mi_root *cmd_tree, void *param)
{
	struct mi_node *node = NULL;
	struct mi_root *rpl_tree = NULL;
	struct mi_node* root= NULL;
	struct mi_attr* attr;
	dp_connection_list_t *el;


	rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
	if (rpl_tree==NULL) return NULL;

	if (cmd_tree) node = cmd_tree->node.kids;
	if (node == NULL) {
		el = dp_get_connections();
		root = &rpl_tree->node;
		while (el) {
			node = add_mi_node_child(root, 0, "Partition", 9, el->partition.s, el->partition.len);
			if( node == NULL) goto error;
			attr = add_mi_attr(node, 0, "table", 5, el->table_name.s, el->table_name.len);
			if(attr == NULL) goto error;
			db_get_url(&el->db_url);
			if(database_url.len == 0) goto error;
			attr = add_mi_attr(node, MI_DUP_VALUE, "db_url", 6, database_url.s, database_url.len);
			if(attr == NULL) goto error;
			el = el->next;
		}
	} else {
		el = dp_get_connection(&node->value);
		if (!el) goto error;
		root = &rpl_tree->node;
		node = add_mi_node_child(root, 0, "Partition", 9, el->partition.s, el->partition.len);
		if( node == NULL) goto error;
		attr = add_mi_attr(node, 0, "table", 5, el->table_name.s, el->table_name.len);
		if(attr == NULL) goto error;
		db_get_url(&el->db_url);
		if(database_url.len == 0) goto error;
		attr = add_mi_attr(node, MI_DUP_VALUE, "db_url", 6, database_url.s, database_url.len);
		if(attr == NULL) goto error;
	}

	return rpl_tree;

error:
	if(rpl_tree) free_mi_tree(rpl_tree);
	return NULL;
}
Пример #3
0
static struct mi_root * mi_reload_rules(struct mi_root *cmd_tree, void *param)
{
	struct mi_node *node = NULL;
	struct mi_root *rpl_tree = NULL;
	dp_connection_list_t *el;


	if (cmd_tree)
		node = cmd_tree->node.kids;

	if (node == NULL) {
			/* Reload rules from all partitions */
			if(dp_load_all_db() != 0){
					LM_ERR("failed to reload database\n");
					return 0;
			}
	} else if (node->value.s == NULL || node->value.len == 0) {
			return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
	} else {
			el = dp_get_connection(&node->value);
			if (!el)
					return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
			/* Reload rules from specified  partition */
			LM_DBG("Reloading rules from table %.*s\n", node->value.len, node->value.s);
			if(dp_load_db(el) != 0){
					LM_ERR("failed to reload database data\n");
					return 0;
			}
	}

	rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
	if (rpl_tree==0)
		return 0;

	return rpl_tree;
}
Пример #4
0
/* first param: DPID: type: INT, AVP, SVAR
 * second param: SRC/DST type: RURI, RURI_USERNAME, AVP, SVAR
 * default value for the second param: $ru.user/$ru.user
 */
static int dp_trans_fixup(void ** param, int param_no){

	int dpid;
	dp_param_p dp_par= NULL;
	char *p, *s = NULL;
	str lstr, partition_name;
	dp_connection_list_t *list = NULL;

	if (param_no < 1 || param_no > 3)
		return 0;

	p = (char*)*param;
	if(!p || (*p == '\0')){
		LM_DBG("null param %i\n", param_no);
		return E_CFG;
	}

	dp_par = (dp_param_p)pkg_malloc(sizeof(dp_param_t));
	if(dp_par == NULL){
		LM_ERR("no more pkg memory\n");
		return E_OUT_OF_MEM;
	}
	memset(dp_par, 0, sizeof(dp_param_t));

	switch (param_no) {
	case 1:
		p = parse_dp_command(p, -1, &partition_name);

		if (p == NULL) {
			LM_ERR("Invalid dp command\n");
			return E_CFG;
		}

		if (!partition_name.s && !partition_name.len) {
			partition_name.s = DEFAULT_PARTITION;
			partition_name.len = sizeof(DEFAULT_PARTITION) - 1;
		}

		if (*partition_name.s != PV_MARKER) {
			list = dp_get_connection(&partition_name);

			if(!list){
				LM_ERR("Partition with name [%.*s] is not defined\n",
						partition_name.len, partition_name.s );
				return -1;
			}
			dp_par->type = DP_VAL_STR;

		} else {
			dp_par->type = DP_VAL_SPEC;
		}

		if (*p != PV_MARKER) {
			lstr.s = p; lstr.len = strlen(p);
			if(str2sint(&lstr, &dpid) != 0) {
				LM_ERR("bad number <%s>\n",(char *)(*param));
				pkg_free(dp_par);
				return E_CFG;
			}

			if(dp_par->type == DP_VAL_SPEC){
				/*int dpid and pv partition_name*/
				dp_par->type = DP_VAL_INT;
				dp_par->v.pv_id.id = dpid;
				if( !pv_parse_spec( &partition_name,
						&dp_par->v.pv_id.partition))
					goto error;
			} else {
				/*DP_VAL_STR remains DP_VAL_STR
					   ( int dpid and str partition_name)*/
				dp_par->v.id = dpid;
			}
		} else {
			if (dp_par->type == DP_VAL_STR) {
				/*pv dpid and str partition_name*/
				dp_par->type = DP_VAL_STR_SPEC;
			} else {
				/*DP_VAL_SPEC remains DP_VAL_SPEC
					    ( pv dpid and pv partition_name) */
				if( !pv_parse_spec( &partition_name,
							 &dp_par->v.sp[1]))
					goto error;
			}

			lstr.s = p; lstr.len = strlen(p);
			if (pv_parse_spec( &lstr, &dp_par->v.sp[0])==NULL)
				goto error;

			verify_par_type(dp_par->v.sp[0]);
		}

		dp_par->hash = list;
		break;

	case 2:
		if( ((s = strchr(p, '/')) == 0) ||( *(s+1)=='\0'))
				goto error;
		*s = '\0'; s++;

		lstr.s = p; lstr.len = strlen(p);
		if(pv_parse_spec( &lstr, &dp_par->v.sp[0])==NULL)
			goto error;

		verify_par_type(dp_par->v.sp[0]);

		lstr.s = s; lstr.len = strlen(s);
		if (pv_parse_spec( &lstr, &dp_par->v.sp[1] )==NULL)
			goto error;

		verify_par_type(dp_par->v.sp[1]);
		if (dp_par->v.sp[1].setf==NULL) {
			LM_ERR("the output PV is read-only!!\n");
			return E_CFG;
		}

		dp_par->type = DP_VAL_SPEC;
		break;

	case 3:
		return fixup_pvar(param);
	}

	*param = (void *)dp_par;

	return 0;

error:
	LM_ERR("failed to parse param %i\n", param_no);
	return E_INVALID_PARAMS;
}
Пример #5
0
static int dp_translate_f(struct sip_msg *msg, char *str1, char *str2,
                          char *attr_spec)
{

	int dpid;
	str input, output;
	dpl_id_p idp;
	dp_param_p id_par, repl_par;
	str attrs, *attrs_par;
	dp_connection_list_p connection;
	pv_value_t pval;
	str partition_name;

	if (!msg)
		return -1;

	/* verify first param's value */
	id_par = (dp_param_p) str1;

	if (dp_get_ivalue(msg, id_par, &dpid) != 0){
		LM_ERR("no dpid value\n");
		return -1;
	}

	switch( id_par->type ) {
		case DP_VAL_INT :
			if (dp_get_svalue(msg, id_par->v.pv_id.partition,
							    &partition_name)) {
				LM_ERR("invalid partition\n");
				return -1;
			}
			goto GET_CONN;
		case DP_VAL_SPEC :
			if (dp_get_svalue(msg, id_par->v.sp[1],
							    &partition_name)) {
				LM_ERR("invalid partition\n");
				return -1;
			}
		GET_CONN:
			if (!(id_par->hash = dp_get_connection(&partition_name))) {
				LM_ERR("invalid partition\n");
				return -1;
			}

			break;
		default :
			break;
	}

	LM_DBG("dpid is %i partition is %.*s\n", dpid,
			id_par->hash->partition.len, id_par->hash->partition.s);

	repl_par = (str2!=NULL) ? ((dp_param_p)str2) : default_par2;
	if (dp_get_svalue(msg, repl_par->v.sp[0], &input)!=0){
		LM_ERR("invalid param 2\n");
		return -1;
	}

	LM_DBG("input is %.*s\n", input.len, input.s);
	connection = id_par->hash;

	/* ref the data for reading */
	lock_start_read( connection->ref_lock );

	if ((idp = select_dpid(connection, dpid, connection->crt_index)) == 0) {
		LM_DBG("no information available for dpid %i\n", dpid);
		goto error;
	}

	LM_DBG("Checking with dpid %i\n", idp->dp_id);

	attrs_par =  attr_spec ? &attrs : NULL;
	if (translate(msg, input, &output, idp, attrs_par) != 0) {
		LM_DBG("could not translate %.*s "
			"with dpid %i\n", input.len, input.s, idp->dp_id);
		goto error;
	}

	LM_DBG("input %.*s with dpid %i => output %.*s\n",
			input.len, input.s, idp->dp_id, output.len, output.s);

	/* set the output */
	if (dp_update(msg, &repl_par->v.sp[0], &repl_par->v.sp[1], &output) != 0) {
		LM_ERR("cannot set the output\n");
		goto error;
	}

	/* we are done reading -> unref the data */
	lock_stop_read( connection->ref_lock );

	if (attr_spec) {
		pval.flags = PV_VAL_STR;
		pval.rs = attrs;

		if (pv_set_value(msg, (pv_spec_p)attr_spec, 0, &pval) != 0) {
			LM_ERR("failed to set value '%.*s' for the attr pvar!\n",
			        attrs.len, attrs.s);
			goto error;
		}
	}

	return 1;

error:
	/* we are done reading -> unref the data */
	lock_stop_read( connection->ref_lock );

	return -1;
}
Пример #6
0
static struct mi_root * mi_translate(struct mi_root *cmd, void *param)
{
	struct mi_root* rpl= NULL;
	struct mi_node* root, *node;
	char *p;
	dpl_id_p idp;
	str dpid_str, partition_str;
	str input;
	int dpid;
	str attrs;
	str output= {0, 0};
	dp_connection_list_p connection = NULL;

	node = cmd->node.kids;
	if(node == NULL)
		return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);

	/* Get the id parameter */
	dpid_str = node->value;
	if(dpid_str.s == NULL || dpid_str.len== 0)	{
		LM_ERR( "empty idp parameter\n");
		return init_mi_tree(404, "Empty id parameter", 18);
	}

	p = parse_dp_command(dpid_str.s, dpid_str.len, &partition_str);

	if (p == NULL) {
		LM_ERR("Invalid dp command\n");
		return init_mi_tree(404, "Invalid dp command", 18);
	}

	if (partition_str.s == NULL || partition_str.len == 0) {
		partition_str.s = DEFAULT_PARTITION;
		partition_str.len = sizeof(DEFAULT_PARTITION) - 1;
	}

	connection = dp_get_connection(&partition_str);

	dpid_str.len -= (p - dpid_str.s);
	dpid_str.s = p;

	if (!connection) {
		LM_ERR("Unable to get connection\n");
		return init_mi_tree(400, "Wrong db connection parameter", 24);
	}

	if(str2sint(&dpid_str, &dpid) != 0)	{
		LM_ERR("Wrong id parameter - should be an integer\n");
		return init_mi_tree(404, "Wrong id parameter", 18);
	}
	node = node->next;
	if(node == NULL)
		return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);

	if(node->next!= NULL)
		return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);

	input = node->value;
	if(input.s == NULL || input.len== 0)	{
		LM_ERR( "empty input parameter\n");
		return init_mi_tree(404, "Empty input parameter", 21);
	}

	/* ref the data for reading */
	lock_start_read( connection->ref_lock );

	if ((idp = select_dpid(connection, dpid, connection->crt_index)) ==0 ){
		LM_ERR("no information available for dpid %i\n", dpid);
		lock_stop_read( connection->ref_lock );
		return init_mi_tree(404, "No information available for dpid", 33);
	}

	if (translate(NULL, input, &output, idp, &attrs)!=0){
		LM_DBG("could not translate %.*s with dpid %i\n",
			input.len, input.s, idp->dp_id);
		lock_stop_read( connection->ref_lock );
		return init_mi_tree(404, "No translation", 14);
	}
	/* we are done reading -> unref the data */
	lock_stop_read( connection->ref_lock );

	LM_DBG("input %.*s with dpid %i => output %.*s\n",
			input.len, input.s, idp->dp_id, output.len, output.s);

	rpl = init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
	if (rpl==0)
		goto error;

	root= &rpl->node;

	node = add_mi_node_child(root, 0, "Output", 6, output.s, output.len );
	if( node == NULL)
		goto error;

	node = add_mi_node_child(root, 0, "ATTRIBUTES", 10, attrs.s, attrs.len);
	if( node == NULL)
		goto error;

	return rpl;

error:
	if(rpl)
		free_mi_tree(rpl);
	return 0;
}
Пример #7
0
/* Adds a new separate partition and loads all rules from database in shm */
dp_connection_list_p dp_add_connection(dp_head_p head)
{
	dp_connection_list_t *el;

	if ((el = dp_get_connection(&head->partition)) != NULL){
		return el;
	}

	int all_size = sizeof(dp_connection_list_t) +head->dp_table_name.len
				+ head->partition.len + head->dp_db_url.len; 
	el = shm_malloc(all_size);
	
	if(!el)
		LM_ERR("No more shm\n");

	if (!el) {
		LM_ERR("No more shm mem\n");
		return NULL;
	}

	/* create & init lock */
	if((el->ref_lock = lock_init_rw()) == NULL) {
		LM_ERR("Failed to init lock\n");
		shm_free(el);
		return NULL;
	}


	/*Set table name*/
	el->table_name.s = (char*)el + sizeof(*el);
	el->table_name.len = head->dp_table_name.len;
	memcpy(el->table_name.s, head->dp_table_name.s, head->dp_table_name.len);


	/*Set partition*/
	el->partition.s = el->table_name.s + el->table_name.len;
	el->partition.len = head->partition.len;
	memcpy(el->partition.s, head->partition.s, head->partition.len);

	/*Set db_url*/
	el->db_url.s = el->partition.s + el->partition.len;
	el->db_url.len = head->dp_db_url.len;
	memcpy(el->db_url.s, head->dp_db_url.s, head->dp_db_url.len);

	el->dp_db_handle = pkg_malloc(sizeof(db_con_t*));
	if (!el->dp_db_handle) {
		LM_ERR("No more shm mem\n");
		return NULL;
	}

	*el->dp_db_handle = 0;

	if (test_db(el) != 0) {
		LM_ERR("Unable to test db\n");
		shm_free(el);
		return NULL;
	}

	*el->dp_db_handle = 0;

	el->next = dp_conns;
	dp_conns = el;

	LM_DBG("Added dialplan partition [%.*s] table [%.*s].\n",
		 head->partition.len, head->partition.s, 
				head->dp_table_name.len, head->dp_table_name.s);

	return el;
}