Module: sip-router Branch: master Commit: e535756d2bee95d01d7b5f2b0ec53d9c43214613 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=e535756d...
Author: Andrei Pelinescu-Onciul andrei@iptel.org Committer: Andrei Pelinescu-Onciul andrei@iptel.org Date: Fri Jun 18 23:04:24 2010 +0200
core: MATCH op fix for ip comparisons with RVEs
Commit e085834 broke regular expression support in ip comparisons with rval expressions (e.g. $re="127..*"; if (src_ip=~$re) ...).
---
route.c | 44 +++++++++++++++++++++++++++++++++++++------- 1 files changed, 37 insertions(+), 7 deletions(-)
diff --git a/route.c b/route.c index 0e07556..4f86912 100644 --- a/route.c +++ b/route.c @@ -1272,6 +1272,8 @@ inline static int comp_str(int op, str* left, int rtype, case SELECT_ST: case RVE_ST: case PVAR_ST: + case STRING_ST: + case STR_ST: /* we need to compile the RE on the fly */ re=(regex_t*)pkg_malloc(sizeof(regex_t)); if (re==0){ @@ -1293,7 +1295,6 @@ inline static int comp_str(int op, str* left, int rtype, case RE_ST: ret=(regexec(r->re, left->s, 0, 0, 0)==0); break; - case STRING_ST: default: LOG(L_CRIT, "BUG: comp_str: Bad operator type %d, " "for ~= \n", rtype); @@ -1630,17 +1631,46 @@ inline static int comp_ip(int op, struct ip_addr* ip, int rtype, r_expop.str=*right; switch(op){ case EQUAL_OP: - case MATCH_OP: /* 0: try if ip or network (ip/mask) */ if (mk_net_str(&net, right) == 0) { ret=(matchnet(ip, &net)==1); break; } - /* 1: compare with ip2str*/ - /* - ret=comp_string(op, ip_addr2a(ip), STR_ST, &r_expop, msg, ctx); - if (likely(ret==1)) break; - */ + /* 2: resolve (name) & compare w/ all the ips */ + he=resolvehost(right->s); + if (he==0){ + DBG("comp_ip: could not resolve %s\n", r->str.s); + }else if (he->h_addrtype==ip->af){ + for(h=he->h_addr_list;(ret!=1)&& (*h); h++){ + ret=(memcmp(ip->u.addr, *h, ip->len)==0); + } + if (ret==1) break; + } + /* 3: (slow) rev dns the address + * and compare with all the aliases + * !!??!! review: remove this? */ + if (unlikely((received_dns & DO_REV_DNS) && + ((he=rev_resolvehost(ip))!=0) )){ + /* compare with primary host name */ + ret=comp_string(op, he->h_name, STR_ST, &r_expop, msg, ctx); + /* compare with all the aliases */ + for(h=he->h_aliases; (ret!=1) && (*h); h++){ + ret=comp_string(op, *h, STR_ST, &r_expop, msg, ctx); + } + }else{ + ret=0; + } + break; + case MATCH_OP: + /* 0: try if ip or network (ip/mask) + (one should not use MATCH for that, but try to be nice)*/ + if (mk_net_str(&net, right) == 0) { + ret=(matchnet(ip, &net)==1); + break; + } + /* 1: compare with ip2str (but only for =~)*/ + ret=comp_string(op, ip_addr2a(ip), STR_ST, &r_expop, msg, ctx); + if (likely(ret==1)) break; /* 2: resolve (name) & compare w/ all the ips */ he=resolvehost(right->s); if (he==0){