瀏覽代碼

Allow to compare the snd_ip and to_ip with the AVP value. (Was allowed for ports, not ips.)
For performance purist: I did not measure which code is faster; whether finding the AVP in the list or using DNS name resolution. Using AVP (track and) domain prefix makes the search faster, when AVP is in fallback domains, e.g. for global AVP.

Following code now allowed:
onsend_route{
if (isflagset(GATEWAY)) {
if (to_ip!=$g.gw_ip) {
log(1,"Bad gateway IP");
drop;
}
}
}

Michal Matyska 18 年之前
父節點
當前提交
a1f3d3fe75
共有 2 個文件被更改,包括 26 次插入6 次删除
  1. 8 0
      cfg.y
  2. 18 6
      route.c

+ 8 - 0
cfg.y

@@ -1358,6 +1358,10 @@ exp_elem:
 		onsend_check("snd_ip");
 		onsend_check("snd_ip");
 		$$=mk_elem($2, SNDIP_O, 0, STRING_ST, $3);
 		$$=mk_elem($2, SNDIP_O, 0, STRING_ST, $3);
 	}
 	}
+	| SNDIP equalop attr_id_val	{
+		onsend_check("snd_ip");
+	    $$=mk_elem($2, SNDIP_O, 0, AVP_ST, (void*)$3 ); 
+	}
 	| SNDIP equalop MYSELF  {
 	| SNDIP equalop MYSELF  {
 		onsend_check("snd_ip");
 		onsend_check("snd_ip");
 		$$=mk_elem($2, SNDIP_O, 0, MYSELF_ST, 0);
 		$$=mk_elem($2, SNDIP_O, 0, MYSELF_ST, 0);
@@ -1385,6 +1389,10 @@ exp_elem:
 		onsend_check("to_ip");
 		onsend_check("to_ip");
 		$$=mk_elem($2, TOIP_O, 0, STRING_ST, $3);
 		$$=mk_elem($2, TOIP_O, 0, STRING_ST, $3);
 	}
 	}
+	| TOIP equalop attr_id_val	{
+		onsend_check("to_ip");
+	    $$=mk_elem($2, TOIP_O, 0, AVP_ST, (void*)$3 ); 
+	}
 	| TOIP equalop MYSELF  {
 	| TOIP equalop MYSELF  {
 		onsend_check("to_ip");
 		onsend_check("to_ip");
 		$$=mk_elem($2, TOIP_O, 0, MYSELF_ST, 0);
 		$$=mk_elem($2, TOIP_O, 0, MYSELF_ST, 0);

+ 18 - 6
route.c

@@ -703,24 +703,35 @@ error:
 inline static int comp_string(int op, char* left, int rtype, union exp_op* r)
 inline static int comp_string(int op, char* left, int rtype, union exp_op* r)
 {
 {
 	int ret;
 	int ret;
+	int_str val;
+	avp_t* avp;
+	char* right;
 
 
 	ret=-1;
 	ret=-1;
+	if (rtype == AVP_ST) {
+		avp = search_avp_by_index(r->attr->type, r->attr->name, &val, r->attr->index);
+		if (avp && (avp->flags & AVP_VAL_STR)) right = val.s.s;
+		else return 0; /* Always fail */
+	} else if (rtype == STRING_ST) {
+		right = r->str.s;
+	}
+
 	switch(op){
 	switch(op){
 		case EQUAL_OP:
 		case EQUAL_OP:
-			if (rtype!=STRING_ST){
+			if (rtype!=STRING_ST && rtype!=AVP_ST){
 				LOG(L_CRIT, "BUG: comp_string: bad type %d, "
 				LOG(L_CRIT, "BUG: comp_string: bad type %d, "
-						"string expected\n", rtype);
+						"string or attr expected\n", rtype);
 				goto error;
 				goto error;
 			}
 			}
-			ret=(strcasecmp(left, r->str.s)==0);
+			ret=(strcasecmp(left, right)==0);
 			break;
 			break;
 		case DIFF_OP:
 		case DIFF_OP:
-			if (rtype!=STRING_ST){
+			if (rtype!=STRING_ST && rtype!=AVP_ST){
 				LOG(L_CRIT, "BUG: comp_string: bad type %d, "
 				LOG(L_CRIT, "BUG: comp_string: bad type %d, "
-						"string expected\n", rtype);
+						"string or attr expected\n", rtype);
 				goto error;
 				goto error;
 			}
 			}
-			ret=(strcasecmp(left, r->str.s)!=0);
+			ret=(strcasecmp(left, right)!=0);
 			break;
 			break;
 		case MATCH_OP:
 		case MATCH_OP:
 			if (rtype!=RE_ST){
 			if (rtype!=RE_ST){
@@ -874,6 +885,7 @@ inline static int comp_ip(int op, struct ip_addr* ip, int rtype, union exp_op* r
 					goto error_op;
 					goto error_op;
 			}
 			}
 			break;
 			break;
+		case AVP_ST:
 		case STRING_ST:
 		case STRING_ST:
 		case RE_ST:
 		case RE_ST:
 			switch(op){
 			switch(op){