diff --git a/src/acl.c b/src/acl.c index 3ea2470f2..c23e5c31c 100644 --- a/src/acl.c +++ b/src/acl.c @@ -832,10 +832,10 @@ int acl_match_ip(struct acl_test *test, struct acl_pattern *pattern) { struct in_addr *s; - if (test->i != AF_INET) + if (temp_pattern.type != PATTERN_TYPE_IP) return ACL_PAT_FAIL; - s = (void *)test->ptr; + s = &temp_pattern.data.ip; if (((s->s_addr ^ pattern->val.ipv4.addr.s_addr) & pattern->val.ipv4.mask.s_addr) == 0) return ACL_PAT_PASS; return ACL_PAT_FAIL; @@ -848,11 +848,10 @@ void *acl_lookup_ip(struct acl_test *test, struct acl_expr *expr) { struct in_addr *s; - if (test->i != AF_INET) + if (temp_pattern.type != PATTERN_TYPE_IP) return ACL_PAT_FAIL; - s = (void *)test->ptr; - + s = &temp_pattern.data.ip; return ebmb_lookup_longest(&expr->pattern_tree, &s->s_addr); } diff --git a/src/proto_http.c b/src/proto_http.c index 133d9160b..b60048e15 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -7967,8 +7967,10 @@ acl_fetch_url_ip(struct proxy *px, struct session *l4, void *l7, int dir, /* Parse HTTP request */ url2sa(txn->req.sol + txn->req.sl.rq.u, txn->req.sl.rq.u_l, &l4->req->cons->addr.to); - test->ptr = (void *)&((struct sockaddr_in *)&l4->req->cons->addr.to)->sin_addr; - test->i = AF_INET; + if (((struct sockaddr_in *)&l4->req->cons->addr.to)->sin_family != AF_INET) + return 0; + temp_pattern.type = PATTERN_TYPE_IP; + temp_pattern.data.ip = ((struct sockaddr_in *)&l4->req->cons->addr.to)->sin_addr; /* * If we are parsing url in frontend space, we prepare backend stage @@ -7977,7 +7979,7 @@ acl_fetch_url_ip(struct proxy *px, struct session *l4, void *l7, int dir, if (px->options & PR_O_HTTP_PROXY) l4->flags |= SN_ADDR_SET; - test->flags = ACL_TEST_F_READ_ONLY; + test->flags = 0; return 1; } @@ -8215,15 +8217,14 @@ acl_fetch_hdr_ip(struct proxy *px, struct session *l4, void *l7, char *sol, /* search for header from the beginning */ ctx->idx = 0; - if (http_find_header2(expr->arg.str, expr->arg_len, sol, idx, ctx)) { + while (http_find_header2(expr->arg.str, expr->arg_len, sol, idx, ctx)) { test->flags |= ACL_TEST_F_FETCH_MORE; test->flags |= ACL_TEST_F_VOL_HDR; /* Same optimization as url_ip */ - memset(&((struct sockaddr_in *)&l4->req->cons->addr.to)->sin_addr, 0, sizeof(((struct sockaddr_in *)&l4->req->cons->addr.to)->sin_addr)); - url2ipv4((char *)ctx->line + ctx->val, &((struct sockaddr_in *)&l4->req->cons->addr.to)->sin_addr); - test->ptr = (void *)&((struct sockaddr_in *)&l4->req->cons->addr.to)->sin_addr; - test->i = AF_INET; - return 1; + temp_pattern.type = PATTERN_TYPE_IP; + if (url2ipv4((char *)ctx->line + ctx->val, &temp_pattern.data.ip)) + return 1; + /* Dods not look like an IP address, let's fetch next one */ } test->flags &= ~ACL_TEST_F_FETCH_MORE; diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 9331fdc19..207fec094 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -1245,20 +1245,25 @@ static int tcp_parse_tcp_req(char **args, int section_type, struct proxy *curpx, /* All supported ACL keywords must be declared here. */ /************************************************************************/ -/* set test->ptr to point to the source IPv4/IPv6 address and test->i to the family */ +/* copy the source IPv4/v6 address into temp_pattern */ static int acl_fetch_src(struct proxy *px, struct session *l4, void *l7, int dir, struct acl_expr *expr, struct acl_test *test) { - test->i = l4->si[0].addr.from.ss_family; - if (test->i == AF_INET) - test->ptr = (char *)&((struct sockaddr_in *)&l4->si[0].addr.from)->sin_addr; - else if (test->i == AF_INET6) - test->ptr = (char *)&((struct sockaddr_in6 *)(&l4->si[0].addr.from))->sin6_addr; - else + switch (l4->si[0].addr.from.ss_family) { + case AF_INET: + temp_pattern.data.ip = ((struct sockaddr_in *)&l4->si[0].addr.from)->sin_addr; + temp_pattern.type = PATTERN_TYPE_IP; + break; + case AF_INET6: + temp_pattern.data.ipv6 = ((struct sockaddr_in6 *)(&l4->si[0].addr.from))->sin6_addr; + temp_pattern.type = PATTERN_TYPE_IPV6; + break; + default: return 0; + } - test->flags = ACL_TEST_F_READ_ONLY; + test->flags = 0; return 1; } @@ -1307,15 +1312,20 @@ acl_fetch_dst(struct proxy *px, struct session *l4, void *l7, int dir, if (!(l4->flags & SN_FRT_ADDR_SET)) get_frt_addr(l4); - test->i = l4->si[0].addr.to.ss_family; - if (test->i == AF_INET) - test->ptr = (char *)&((struct sockaddr_in *)&l4->si[0].addr.to)->sin_addr; - else if (test->i == AF_INET6) - test->ptr = (char *)&((struct sockaddr_in6 *)(&l4->si[0].addr.to))->sin6_addr; - else + switch (l4->si[0].addr.to.ss_family) { + case AF_INET: + temp_pattern.data.ip = ((struct sockaddr_in *)&l4->si[0].addr.to)->sin_addr; + temp_pattern.type = PATTERN_TYPE_IP; + break; + case AF_INET6: + temp_pattern.data.ipv6 = ((struct sockaddr_in6 *)(&l4->si[0].addr.to))->sin6_addr; + temp_pattern.type = PATTERN_TYPE_IPV6; + break; + default: return 0; + } - test->flags = ACL_TEST_F_READ_ONLY; + test->flags = 0; return 1; }