Example #1
0
/*compile the expressions, and if ok, build the rule */
dpl_node_t * build_rule(db_val_t * values)
{
	tmrec_t *parsed_timerec;
	pcre * match_comp, *subst_comp;
	struct subst_expr * repl_comp;
	dpl_node_t * new_rule;
	str match_exp, subst_exp, repl_exp, attrs, timerec;
	int matchop;
	int namecount;

	matchop = VAL_INT(values+2);

	if((matchop != REGEX_OP) && (matchop!=EQUAL_OP)){
		LM_ERR("invalid value for match operator\n");
		return NULL;
	}

	parsed_timerec = 0;
	match_comp = subst_comp = 0;
	repl_comp = 0;
	new_rule = 0;

	GET_STR_VALUE(match_exp, values, 3);
	if(matchop == REGEX_OP){

		LM_DBG("Compiling %.*s expression with flag: %d\n",
				match_exp.len, match_exp.s, VAL_INT(values+4));

		match_comp = wrap_pcre_compile(match_exp.s, VAL_INT(values+4));

		if(!match_comp){
			LM_ERR("failed to compile match expression %.*s\n",
				match_exp.len, match_exp.s);
			goto err;
		}
	}

	LM_DBG("building subst rule\n");
	GET_STR_VALUE(subst_exp, values, 5);
	if(subst_exp.s && subst_exp.len){
		/* subst regexp */
		subst_comp = wrap_pcre_compile(subst_exp.s, VAL_INT(values+4));
		if(subst_comp == NULL){
			LM_ERR("failed to compile subst expression\n");
			goto err;
		}
	}

	/* replace exp */
	GET_STR_VALUE(repl_exp, values, 6);
	if(repl_exp.len && repl_exp.s){
		repl_comp = repl_exp_parse(repl_exp);
		if(!repl_comp){
			LM_ERR("failed to compile replacing expression %.*s\n",
				repl_exp.len, repl_exp.s);
			goto err;
		}
	}

	pcre_fullinfo(
		subst_comp, /* the compiled pattern */
		NULL, /* no extra data - we didn't study the pattern */
		PCRE_INFO_CAPTURECOUNT, /* number of named substrings */
		&namecount); /* where to put the answer */

	LM_DBG("references:%d , max:%d\n",namecount,
		repl_comp?repl_comp->max_pmatch:0);

	if ( (repl_comp!=NULL) && (namecount<repl_comp->max_pmatch) &&
	(repl_comp->max_pmatch!=0) ){
		LM_ERR("repl_exp uses a non existing subexpression\n");
			goto err;
	}

	new_rule = (dpl_node_t *)shm_malloc(sizeof(dpl_node_t));
	if(!new_rule){
		LM_ERR("out of shm memory(new_rule)\n");
		goto err;
	}
	memset(new_rule, 0, sizeof(dpl_node_t));

	if(str_to_shm(match_exp, &new_rule->match_exp)!=0)
		goto err;

	if (subst_comp)
		if(str_to_shm(subst_exp, &new_rule->subst_exp)!=0)
			goto err;
	if (repl_comp)
		if(str_to_shm(repl_exp, &new_rule->repl_exp)!=0)
			goto err;

	/*set the rest of the rule fields*/
	new_rule->dpid          =	VAL_INT(values);
	new_rule->pr            =	VAL_INT(values+1);
	new_rule->match_flags   =	VAL_INT(values+4);
	new_rule->matchop       =	matchop;
	GET_STR_VALUE(attrs, values, 7);
	if(str_to_shm(attrs, &new_rule->attrs)!=0)
		goto err;

	LM_DBG("attrs are %.*s\n",
		new_rule->attrs.len, new_rule->attrs.s);

	/* Retrieve and Parse Timerec Matching Pattern */
	GET_STR_VALUE(timerec, values, 8);
	if(timerec.len && timerec.s) {
		parsed_timerec = parse_time_def(timerec.s);
		if(!parsed_timerec) {
			LM_ERR("failed to parse timerec pattern %.*s\n",
				timerec.len, timerec.s);
			goto err;
		}

		if(str_to_shm(timerec, &new_rule->timerec) != 0)
			goto err;

		new_rule->parsed_timerec = parsed_timerec;
	
		LM_DBG("timerecs are %.*s\n", 
			new_rule->timerec.len, new_rule->timerec.s);
	}

	if (match_comp)
		new_rule->match_comp = match_comp;

	if (subst_comp)
		new_rule->subst_comp = subst_comp;

	if (repl_comp)
		new_rule->repl_comp  = repl_comp;

	return new_rule;

err:
	if(parsed_timerec)	shm_free(parsed_timerec);
	if(match_comp)		wrap_pcre_free(match_comp);
	if(subst_comp)		wrap_pcre_free(subst_comp);
	if(repl_comp)		repl_expr_free(repl_comp);
	if(new_rule)		destroy_rule(new_rule);
	return NULL;
}
Example #2
0
/*compile the expressions, and if ok, build the rule */
dpl_node_t * build_rule(db_val_t * values)
{
	pcre *match_comp, *subst_comp;
	struct subst_expr *repl_comp;
	dpl_node_t * new_rule;
	str match_exp, subst_exp, repl_exp, attrs;
	int matchop;
	int cap_cnt=0;
	unsigned int tflags=0;

	matchop = VAL_INT(values+2);

	if((matchop != DP_REGEX_OP) && (matchop!=DP_EQUAL_OP)
			&& (matchop!=DP_FNMATCH_OP)){
		LM_ERR("invalid value for match operator\n");
		return NULL;
	}

	match_comp = subst_comp = 0;
	repl_comp = 0;
	new_rule = 0;

	GET_STR_VALUE(match_exp, values, 3);
	if(matchop == DP_REGEX_OP){
		if(unlikely(dp_match_dynamic==1)) {
			if(dpl_check_pv(&match_exp)==0) {
				tflags |= DP_TFLAGS_PV_MATCH;
			}
		}
		if(!(tflags&DP_TFLAGS_PV_MATCH)) {
			match_comp = reg_ex_comp(match_exp.s, &cap_cnt, 0);
			if(!match_comp){
				LM_ERR("failed to compile match expression %.*s\n",
						match_exp.len, match_exp.s);
				goto err;
			}
		}
	}

	GET_STR_VALUE(repl_exp, values, 6);
	if(repl_exp.len && repl_exp.s){
		repl_comp = repl_exp_parse(repl_exp);
		if(!repl_comp){
			LM_ERR("failed to compile replacing expression %.*s\n",
					repl_exp.len, repl_exp.s);
			goto err;
		}
	}

	cap_cnt = 0;
	GET_STR_VALUE(subst_exp, values, 5);
	if(subst_exp.s && subst_exp.len){
		if(unlikely(dp_match_dynamic==1)) {
			if(dpl_check_pv(&subst_exp)==0) {
				tflags |= DP_TFLAGS_PV_SUBST;
			}
		}
		if(!(tflags&DP_TFLAGS_PV_SUBST)) {
			subst_comp = reg_ex_comp(subst_exp.s, &cap_cnt, 0);
			if(!subst_comp){
				LM_ERR("failed to compile subst expression %.*s\n",
						subst_exp.len, subst_exp.s);
				goto err;
			}
			if (cap_cnt > MAX_REPLACE_WITH) {
				LM_ERR("subst expression %.*s has too many sub-expressions\n",
						subst_exp.len, subst_exp.s);
				goto err;
			}
		}
	}

	LM_DBG("building rule for [%d:%.*s/%.*s/%.*s]\n", matchop,
			match_exp.len, ZSW(match_exp.s), subst_exp.len, ZSW(subst_exp.s),
			repl_exp.len, ZSW(repl_exp.s));
	if (!(tflags&(DP_TFLAGS_PV_SUBST|DP_TFLAGS_PV_MATCH)) &&
		repl_comp && (cap_cnt < repl_comp->max_pmatch) &&
		(repl_comp->max_pmatch != 0))
	{
		LM_ERR("repl_exp %.*s refers to %d sub-expressions, but "
				"subst_exp %.*s has only %d\n",
				repl_exp.len, repl_exp.s, repl_comp->max_pmatch,
				subst_exp.len, subst_exp.s, cap_cnt);
		goto err;
	}

	new_rule = (dpl_node_t *)shm_malloc(sizeof(dpl_node_t));
	if(!new_rule){
		LM_ERR("out of shm memory(new_rule)\n");
		goto err;
	}
	memset(new_rule, 0, sizeof(dpl_node_t));

	if(dpl_str_to_shm(match_exp, &new_rule->match_exp,
				tflags&DP_TFLAGS_PV_MATCH)!=0)
		goto err;

	if(dpl_str_to_shm(subst_exp, &new_rule->subst_exp,
				tflags&DP_TFLAGS_PV_SUBST)!=0)
		goto err;

	if(dpl_str_to_shm(repl_exp, &new_rule->repl_exp, 0)!=0)
		goto err;

	/*set the rest of the rule fields*/
	new_rule->dpid		=	VAL_INT(values);
	new_rule->pr		=	VAL_INT(values+1);
	new_rule->matchlen	= 	VAL_INT(values+4);
	new_rule->matchop	=	matchop;
	GET_STR_VALUE(attrs, values, 7);
	if(dpl_str_to_shm(attrs, &new_rule->attrs, 0)!=0)
		goto err;

	LM_DBG("attrs are: '%.*s'\n", new_rule->attrs.len, new_rule->attrs.s);

	new_rule->match_comp = match_comp;
	new_rule->subst_comp = subst_comp;
	new_rule->repl_comp  = repl_comp;
	new_rule->tflags     = tflags;

	return new_rule;

err:
	if(match_comp) shm_free(match_comp);
	if(subst_comp) shm_free(subst_comp);
	if(repl_comp) repl_expr_free(repl_comp);
	if(new_rule) destroy_rule(new_rule);
	return NULL;
}
Example #3
0
/*load rules from DB*/
int dp_load_db(dp_connection_list_p dp_conn)
{
	int i, nr_rows;
	db_res_t * res = 0;
	db_val_t * values;
	db_row_t * rows;
	db_key_t query_cols[DP_TABLE_COL_NO] = {
		&dpid_column,		&pr_column,
		&match_op_column,	&match_exp_column,	&match_flags_column,
		&subst_exp_column,	&repl_exp_column,	&attrs_column,	&timerec_column };
	db_key_t order = &pr_column;
	/* disabled condition */
	db_key_t cond_cols[1] = { &disabled_column };
	db_val_t cond_val[1];

	dpl_node_t *rule;
	int no_rows = 10;


	lock_start_write( dp_conn->ref_lock );

	if( dp_conn->crt_index != dp_conn->next_index){
		LM_WARN("a load command already generated, aborting reload...\n");
		lock_stop_write( dp_conn->ref_lock );
		return 0;
	}

	dp_conn->next_index = dp_conn->crt_index == 0 ? 1 : 0;

	lock_stop_write( dp_conn->ref_lock );

	if (dp_conn->dp_dbf.use_table(*dp_conn->dp_db_handle, &dp_conn->table_name) < 0){
		LM_ERR("error in use_table\n");
		goto err1;
	}

	VAL_TYPE(cond_val) = DB_INT;
	VAL_NULL(cond_val) = 0;
	VAL_INT(cond_val) = 0;

	if (DB_CAPABILITY(dp_conn->dp_dbf, DB_CAP_FETCH)) {
		if(dp_conn->dp_dbf.query(*dp_conn->dp_db_handle,cond_cols,
				0,cond_val,query_cols,1,
					DP_TABLE_COL_NO, order, 0) < 0){
			LM_ERR("failed to query database!\n");

			goto err1;
		}
		no_rows = estimate_available_rows( 4+4+4+64+4+64+64+128,
			DP_TABLE_COL_NO);
		if (no_rows==0) no_rows = 10;
		if(dp_conn->dp_dbf.fetch_result(*dp_conn->dp_db_handle, 
						&res, no_rows)<0) {
			LM_ERR("failed to fetch\n");
			if (res)
				dp_conn->dp_dbf.free_result(*dp_conn->dp_db_handle, res);

			goto err1;
		}
	} else {
		/*select the whole table and all the columns*/
		if(dp_conn->dp_dbf.query(*dp_conn->dp_db_handle,
				cond_cols,0,cond_val,query_cols,1,
			DP_TABLE_COL_NO, order, &res) < 0){
				LM_ERR("failed to query database\n");

			goto err1;
		}
	}

	nr_rows = RES_ROW_N(res);



	if(nr_rows == 0){
		LM_WARN("no data in the db\n");
		goto end;
	}

	do {
		for(i=0; i<RES_ROW_N(res); i++){
			rows = RES_ROWS(res);
			values = ROW_VALUES(rows+i);

			if ((rule = build_rule(values)) == NULL) {
				LM_WARN(" failed to build rule -> skipping\n");
				continue;
			}

			rule->table_id = i;

			if(add_rule2hash(rule , dp_conn, dp_conn->next_index) != 0) {
				LM_ERR("add_rule2hash failed\n");
				goto err2;
			}
		}


		if (DB_CAPABILITY(dp_conn->dp_dbf, DB_CAP_FETCH)) {
			if(dp_conn->dp_dbf.fetch_result(*dp_conn->dp_db_handle, 
							&res, no_rows)<0) {
				LM_ERR("failure while fetching!\n");
				if (res)
					dp_conn->dp_dbf.free_result(*dp_conn->dp_db_handle, res);
				goto err1;
			}
		} else {
			break;
		}
	}  while(RES_ROW_N(res)>0);


end:


	/*update data*/
	lock_start_write( dp_conn->ref_lock );

	destroy_hash(&dp_conn->hash[dp_conn->crt_index]);

	dp_conn->crt_index = dp_conn->next_index;

	lock_stop_write( dp_conn->ref_lock );

	list_hash(dp_conn->hash[dp_conn->crt_index], dp_conn->ref_lock);

	dp_conn->dp_dbf.free_result(*dp_conn->dp_db_handle, res);
	return 0;

err1:

	lock_start_write( dp_conn->ref_lock );

	dp_conn->next_index = dp_conn->crt_index;

	lock_stop_write( dp_conn->ref_lock );

	return -1;

err2:
	if(rule)	destroy_rule(rule);
	destroy_hash(&dp_conn->hash[dp_conn->next_index]);
	dp_conn->dp_dbf.free_result(*dp_conn->dp_db_handle, res);

	lock_start_write( dp_conn->ref_lock );

	dp_conn->next_index = dp_conn->crt_index;
	/* if lock defined - release the exclusive writing access */

	lock_stop_write( dp_conn->ref_lock );
	return -1;
}
Example #4
0
/*load rules from DB*/
int dp_load_db(void)
{
	int i, nr_rows;
	db1_res_t * res = 0;
	db_val_t * values;
	db_row_t * rows;
	db_key_t query_cols[DP_TABLE_COL_NO] = {
		&dpid_column,	&pr_column,
		&match_op_column,	&match_exp_column,	&match_len_column,
		&subst_exp_column,	&repl_exp_column,	&attrs_column };

	db_key_t order = &pr_column;

	dpl_node_t *rule;

	LM_DBG("init\n");
	if( (*crt_idx) != (*next_idx)){
		LM_WARN("a load command already generated, aborting reload...\n");
		return 0;
	}

	if (dp_dbf.use_table(dp_db_handle, &dp_table_name) < 0){
		LM_ERR("error in use_table %.*s\n", dp_table_name.len, dp_table_name.s);
		return -1;
	}

	if (DB_CAPABILITY(dp_dbf, DB_CAP_FETCH)) {
		if(dp_dbf.query(dp_db_handle,0,0,0,query_cols, 0, 
					DP_TABLE_COL_NO, order, 0) < 0){
			LM_ERR("failed to query database!\n");
			return -1;
		}
		if(dp_dbf.fetch_result(dp_db_handle, &res, dp_fetch_rows)<0) {
			LM_ERR("failed to fetch\n");
			if (res)
				dp_dbf.free_result(dp_db_handle, res);
			return -1;
		}
	} else {
		/*select the whole table and all the columns*/
		if(dp_dbf.query(dp_db_handle,0,0,0,query_cols, 0, 
					DP_TABLE_COL_NO, order, &res) < 0){
			LM_ERR("failed to query database\n");
			return -1;
		}
	}

	nr_rows = RES_ROW_N(res);

	*next_idx = ((*crt_idx) == 0)? 1:0;
	destroy_hash(*next_idx);

	if(nr_rows == 0){
		LM_WARN("no data in the db\n");
		goto end;
	}

	do {
		for(i=0; i<RES_ROW_N(res); i++){
			rows 	= RES_ROWS(res);

			values = ROW_VALUES(rows+i);

			if((rule = build_rule(values)) ==0 )
				goto err2;

			if(add_rule2hash(rule , *next_idx) != 0)
				goto err2;

		}
		if (DB_CAPABILITY(dp_dbf, DB_CAP_FETCH)) {
			if(dp_dbf.fetch_result(dp_db_handle, &res, dp_fetch_rows)<0) {
				LM_ERR("failure while fetching!\n");
				if (res)
					dp_dbf.free_result(dp_db_handle, res);
				return -1;
			}
		} else {
			break;
		}
	}  while(RES_ROW_N(res)>0);


end:
	/*update data*/
	*crt_idx = *next_idx;
	list_hash(*crt_idx);
	dp_dbf.free_result(dp_db_handle, res);
	return 0;

err2:
	if(rule)	destroy_rule(rule);
	destroy_hash(*next_idx);
	dp_dbf.free_result(dp_db_handle, res);
	*next_idx = *crt_idx; 
	return -1;
}