示例#1
0
文件: dp_repl.c 项目: Danfx/opensips
int translate(struct sip_msg *msg, str input, str * output, dpl_id_p idp, str * attrs) {

	dpl_node_p rulep, rrulep;
	int string_res = -1, regexp_res = -1, bucket;

	if(!input.s || !input.len) {
		LM_ERR("invalid input string\n");
		return -1;
	}

	bucket = core_case_hash(&input, NULL, DP_INDEX_HASH_SIZE);

	/* try to match the input in the corresponding string bucket */
	for (rulep = idp->rule_hash[bucket].first_rule; rulep; rulep=rulep->next) {

		LM_DBG("Equal operator testing\n");

		if(rulep->match_exp.len != input.len)
			continue;

		LM_DBG("Comparing (input %.*s) with (rule %.*s) [%d] and timerec %.*s\n",
				input.len, input.s, rulep->match_exp.len, rulep->match_exp.s,
				rulep->match_flags, rulep->timerec.len, rulep->timerec.s);

		// Check for Time Period if Set
		if(rulep->parsed_timerec) {
			LM_DBG("Timerec exists for rule checking: %.*s\n", rulep->timerec.len, rulep->timerec.s);
			// Doesn't matches time period continue with next rule
			if(!check_time(rulep->parsed_timerec)) {
				LM_DBG("Time rule doesn't match: skip next!\n");
				continue;
			}
		}

		if (rulep->match_flags & DP_CASE_INSENSITIVE) {
			string_res = strncasecmp(rulep->match_exp.s,input.s,input.len);
		} else {
			string_res = strncmp(rulep->match_exp.s,input.s,input.len);
		}

		if (string_res == 0) {
			break;
		}
	}

	/* try to match the input in the regexp bucket */
	for (rrulep = idp->rule_hash[DP_INDEX_HASH_SIZE].first_rule; rrulep; rrulep=rrulep->next) {

		// Check for Time Period if Set
		if(rrulep->parsed_timerec) {
			LM_DBG("Timerec exists for rule checking: %.*s\n", rrulep->timerec.len, rrulep->timerec.s);
			// Doesn't matches time period continue with next rule
			if(!check_time(rrulep->parsed_timerec)) {
				LM_DBG("Time rule doesn't match: skip next!\n");
				continue;
			}
		}

		regexp_res = (test_match(input, rrulep->match_comp, matches, MAX_MATCHES)
					>= 0 ? 0 : -1);

		LM_DBG("Regex operator testing. Got result: %d\n", regexp_res);

		if (regexp_res == 0) {
			break;
		}
	}

	if (string_res != 0 && regexp_res != 0) {
		LM_DBG("No matching rule for input %.*s\n", input.len, input.s);
		return -1;
	}

	/* pick the rule with lowest table index if both match and prio are equal */
	if (string_res == 0 && regexp_res == 0) {
		if (rrulep->pr < rulep->pr) {
			rulep = rrulep;
		} else if (rrulep->pr == rulep->pr &&
		           rrulep->table_id < rulep->table_id) {
			rulep = rrulep;
		}
	}

	if (!rulep)
		rulep = rrulep;

	LM_DBG("Found a matching rule %p: pr %i, match_exp %.*s\n",
		rulep, rulep->pr, rulep->match_exp.len, rulep->match_exp.s);

	if(attrs){
		attrs->len = 0;
		attrs->s = 0;
		if(rulep->attrs.len>0) {
			LM_DBG("the rule's attrs are %.*s\n",
				rulep->attrs.len, rulep->attrs.s);
			if(rulep->attrs.len >= DP_MAX_ATTRS_LEN) {
				LM_ERR("EXCEEDED Max attribute length.\n");
				return -1;
			}
			attrs->s = dp_attrs_buf;
			memcpy(attrs->s, rulep->attrs.s, rulep->attrs.len*sizeof(char));
			attrs->len = rulep->attrs.len;
			attrs->s[attrs->len] = '\0';

			LM_DBG("the copied attributes are: %.*s\n",
				attrs->len, attrs->s);
		}
	}

	if(rule_translate(msg, input, rulep, output)!=0){
		LM_ERR("could not build the output\n");
		return -1;
	}

	return 0;
}
示例#2
0
int translate(struct sip_msg *msg, str input, str *output, dpl_id_p idp,
		str *attrs)
{
	dpl_node_p rulep;
	dpl_index_p indexp;
	int user_len, rez;
	char b;

	if(!input.s || !input.len) {
		LM_ERR("invalid input string\n");
		return -1;
	}

	user_len = input.len;
	for(indexp = idp->first_index; indexp!=NULL; indexp = indexp->next)
		if(!indexp->len || (indexp->len!=0 && indexp->len == user_len) )
			break;

	if(!indexp || (indexp!= NULL && !indexp->first_rule)){
		LM_DBG("no rule for len %i\n", input.len);
		return -1;
	}

search_rule:
	for(rulep=indexp->first_rule; rulep!=NULL; rulep= rulep->next) {
		switch(rulep->matchop) {

			case DP_REGEX_OP:
				LM_DBG("regex operator testing\n");
				rez = pcre_exec(rulep->match_comp, NULL, input.s, input.len,
						0, 0, NULL, 0);
				break;

			case DP_EQUAL_OP:
				LM_DBG("equal operator testing\n");
				if(rulep->match_exp.len != input.len) {
					rez = -1;
				} else {
					rez = strncmp(rulep->match_exp.s,input.s,input.len);
					rez = (rez==0)?0:-1;
				}
				break;

			case DP_FNMATCH_OP:
				LM_DBG("fnmatch operator testing\n");
				b = input.s[input.len];
				input.s[input.len] = '\0';
				rez = fnmatch(rulep->match_exp.s, input.s, 0);
				input.s[input.len] = b;
				rez = (rez==0)?0:-1;
				break;

			default:
				LM_ERR("bogus match operator code %i\n", rulep->matchop);
				return -1;
		}
		if(rez >= 0)
			goto repl;
	}
	/*test the rules with len 0*/
	if(indexp->len){
		for(indexp = indexp->next; indexp!=NULL; indexp = indexp->next)
			if(!indexp->len)
				break;
		if(indexp)
			goto search_rule;
	}

	LM_DBG("no matching rule\n");
	return -1;

repl:
	LM_DBG("found a matching rule %p: pr %i, match_exp %.*s\n",
			rulep, rulep->pr, rulep->match_exp.len, rulep->match_exp.s);

	if(attrs) {
		attrs->len = 0;
		attrs->s = 0;
		if(rulep->attrs.len>0) {
			LM_DBG("the rule's attrs are %.*s\n",
					rulep->attrs.len, rulep->attrs.s);
			if(rulep->attrs.len >= DP_MAX_ATTRS_LEN) {
				LM_ERR("out of memory for attributes\n");
				return -1;
			}
			attrs->s = dp_attrs_buf;
			memcpy(attrs->s, rulep->attrs.s, rulep->attrs.len*sizeof(char));
			attrs->len = rulep->attrs.len;
			attrs->s[attrs->len] = '\0';

			LM_DBG("the copied attributes are: %.*s\n",
					attrs->len, attrs->s);
		}
	}

	if(rule_translate(msg, input, rulep, output)!=0){
		LM_ERR("could not build the output\n");
		return -1;
	}

	return 0;
}