浏览代码

core: fix selects in optimized rvalue expressions

- do not attempt to resolve_select() twice the same select. This
  happened when a rve containing only a select was optimized,
  the select moved out of the rve and fix_expr() tried to "fix"
  the already resolved select later.
- changed BUG() messages for failed resolve_select() into ERR().
Andrei Pelinescu-Onciul 15 年之前
父节点
当前提交
2f34ba7d8d
共有 3 个文件被更改,包括 18 次插入9 次删除
  1. 14 6
      route.c
  2. 3 2
      route_struct.h
  3. 1 1
      rvalue.c

+ 14 - 6
route.c

@@ -588,7 +588,9 @@ int fix_expr(struct expr* exp)
 					exp->r.re=re;
 					exp->r_type=RE_ST;
 				}else if (exp->r_type!=RE_ST && exp->r_type != AVP_ST
-						&& exp->r_type != SELECT_ST && exp->r_type!= RVE_ST
+						&& exp->r_type != SELECT_ST &&
+						exp->r_type != SELECT_UNFIXED_ST &&
+						exp->r_type!= RVE_ST
 						&& exp->r_type != PVAR_ST){
 					LOG(L_CRIT, "BUG: fix_expr : invalid type for match\n");
 					return E_BUG;
@@ -601,19 +603,21 @@ int fix_expr(struct expr* exp)
 					return ret;
 				}
 			}
-			if (exp->l_type==SELECT_O) {
+			if (exp->l_type==SELECT_UNFIXED_O) {
 				if ((ret=resolve_select(exp->l.select)) < 0) {
-					BUG("Unable to resolve select\n");
+					ERR("Unable to resolve select\n");
 					print_select(exp->l.select);
 					return ret;
 				}
+				exp->l_type=SELECT_O;
 			}
-			if ((exp->r_type==SELECT_O)||(exp->r_type==SELECT_ST)) {
+			if (exp->r_type==SELECT_UNFIXED_ST) {
 				if ((ret=resolve_select(exp->r.select)) < 0) {
-					BUG("Unable to resolve select\n");
-					print_select(exp->l.select);
+					ERR("Unable to resolve select\n");
+					print_select(exp->r.select);
 					return ret;
 				}
+				exp->r_type=SELECT_ST;
 			}
 			/* PVAR don't need fixing */
 			ret=0;
@@ -1895,6 +1899,10 @@ inline static int eval_elem(struct run_act_ctx* h, struct expr* e,
 	case PVAR_O:
 		ret=comp_pvar(e->op, e->l.param, e->r_type, &e->r, msg, h);
 		break;
+
+	case SELECT_UNFIXED_O:
+		BUG("unexpected unfixed select operand %d\n", e->l_type);
+		break;
 /*
 	default:
 		LOG(L_CRIT, "BUG: eval_elem: invalid operand %d\n",

+ 3 - 2
route_struct.h

@@ -76,7 +76,7 @@ enum _expr_l_type{
 	   METHOD_O=51, URI_O, FROM_URI_O, TO_URI_O, SRCIP_O, SRCPORT_O,
 	   DSTIP_O, DSTPORT_O, PROTO_O, AF_O, MSGLEN_O, ACTION_O,
 	   NUMBER_O, AVP_O, SNDIP_O, SNDPORT_O, TOIP_O, TOPORT_O, SNDPROTO_O,
-	   SNDAF_O, RETCODE_O, SELECT_O, PVAR_O, RVEXP_O};
+	   SNDAF_O, RETCODE_O, SELECT_O, PVAR_O, RVEXP_O, SELECT_UNFIXED_O};
 /* action types */
 enum action_type{
 		FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
@@ -121,7 +121,8 @@ enum _operand_subtype{
 		SELECT_ST, PVAR_ST,
 		LVAL_ST,  RVE_ST,
 		RETCODE_ST, CASE_ST,
-		BLOCK_ST, JUMPTABLE_ST, CONDTABLE_ST, MATCH_CONDTABLE_ST
+		BLOCK_ST, JUMPTABLE_ST, CONDTABLE_ST, MATCH_CONDTABLE_ST,
+		SELECT_UNFIXED_ST
 };
 
 typedef enum _expr_l_type expr_l_type;

+ 1 - 1
rvalue.c

@@ -2768,7 +2768,7 @@ static int fix_rval(struct rvalue* rv)
 			return fix_actions(rv->v.action);
 		case RV_SEL:
 			if (resolve_select(&rv->v.sel)<0){
-				BUG("Unable to resolve select\n");
+				ERR("Unable to resolve select\n");
 				print_select(&rv->v.sel);
 			}
 			return 0;