Core: introduced ngx_cidr_match() function.

This commit is contained in:
Dmitry Volyntsev 2016-09-07 13:56:53 +03:00
parent d7df0f5ff3
commit 6377f87d38
3 changed files with 118 additions and 104 deletions

View file

@ -465,6 +465,93 @@ ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr)
} }
ngx_int_t
ngx_cidr_match(struct sockaddr *sa, ngx_array_t *cidrs)
{
#if (NGX_HAVE_INET6)
u_char *p;
#endif
in_addr_t inaddr;
ngx_cidr_t *cidr;
ngx_uint_t family, i;
#if (NGX_HAVE_INET6)
ngx_uint_t n;
struct in6_addr *inaddr6;
#endif
#if (NGX_SUPPRESS_WARN)
inaddr = 0;
#if (NGX_HAVE_INET6)
inaddr6 = NULL;
#endif
#endif
family = sa->sa_family;
if (family == AF_INET) {
inaddr = ((struct sockaddr_in *) sa)->sin_addr.s_addr;
}
#if (NGX_HAVE_INET6)
else if (family == AF_INET6) {
inaddr6 = &((struct sockaddr_in6 *) sa)->sin6_addr;
if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
family = AF_INET;
p = inaddr6->s6_addr;
inaddr = p[12] << 24;
inaddr += p[13] << 16;
inaddr += p[14] << 8;
inaddr += p[15];
inaddr = htonl(inaddr);
}
}
#endif
for (cidr = cidrs->elts, i = 0; i < cidrs->nelts; i++) {
if (cidr[i].family != family) {
goto next;
}
switch (family) {
#if (NGX_HAVE_INET6)
case AF_INET6:
for (n = 0; n < 16; n++) {
if ((inaddr6->s6_addr[n] & cidr[i].u.in6.mask.s6_addr[n])
!= cidr[i].u.in6.addr.s6_addr[n])
{
goto next;
}
}
break;
#endif
#if (NGX_HAVE_UNIX_DOMAIN)
case AF_UNIX:
break;
#endif
default: /* AF_INET */
if ((inaddr & cidr[i].u.in.mask) != cidr[i].u.in.addr) {
goto next;
}
break;
}
return NGX_OK;
next:
continue;
}
return NGX_DECLINED;
}
ngx_int_t ngx_int_t
ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text, size_t len) ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text, size_t len)
{ {

View file

@ -113,6 +113,7 @@ size_t ngx_sock_ntop(struct sockaddr *sa, socklen_t socklen, u_char *text,
size_t len, ngx_uint_t port); size_t len, ngx_uint_t port);
size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len); size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len);
ngx_int_t ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr); ngx_int_t ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr);
ngx_int_t ngx_cidr_match(struct sockaddr *sa, ngx_array_t *cidrs);
ngx_int_t ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text, ngx_int_t ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text,
size_t len); size_t len);
ngx_int_t ngx_parse_addr_port(ngx_pool_t *pool, ngx_addr_t *addr, ngx_int_t ngx_parse_addr_port(ngx_pool_t *pool, ngx_addr_t *addr,

View file

@ -2824,77 +2824,11 @@ ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r, ngx_addr_t *addr,
u_char *xff, size_t xfflen, ngx_array_t *proxies, int recursive) u_char *xff, size_t xfflen, ngx_array_t *proxies, int recursive)
{ {
u_char *p; u_char *p;
in_addr_t inaddr;
ngx_int_t rc; ngx_int_t rc;
ngx_addr_t paddr; ngx_addr_t paddr;
ngx_cidr_t *cidr;
ngx_uint_t family, i;
#if (NGX_HAVE_INET6)
ngx_uint_t n;
struct in6_addr *inaddr6;
#endif
#if (NGX_SUPPRESS_WARN) if (ngx_cidr_match(addr->sockaddr, proxies) != NGX_OK) {
inaddr = 0; return NGX_DECLINED;
#if (NGX_HAVE_INET6)
inaddr6 = NULL;
#endif
#endif
family = addr->sockaddr->sa_family;
if (family == AF_INET) {
inaddr = ((struct sockaddr_in *) addr->sockaddr)->sin_addr.s_addr;
}
#if (NGX_HAVE_INET6)
else if (family == AF_INET6) {
inaddr6 = &((struct sockaddr_in6 *) addr->sockaddr)->sin6_addr;
if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
family = AF_INET;
p = inaddr6->s6_addr;
inaddr = p[12] << 24;
inaddr += p[13] << 16;
inaddr += p[14] << 8;
inaddr += p[15];
inaddr = htonl(inaddr);
}
}
#endif
for (cidr = proxies->elts, i = 0; i < proxies->nelts; i++) {
if (cidr[i].family != family) {
goto next;
}
switch (family) {
#if (NGX_HAVE_INET6)
case AF_INET6:
for (n = 0; n < 16; n++) {
if ((inaddr6->s6_addr[n] & cidr[i].u.in6.mask.s6_addr[n])
!= cidr[i].u.in6.addr.s6_addr[n])
{
goto next;
}
}
break;
#endif
#if (NGX_HAVE_UNIX_DOMAIN)
case AF_UNIX:
break;
#endif
default: /* AF_INET */
if ((inaddr & cidr[i].u.in.mask) != cidr[i].u.in.addr) {
goto next;
}
break;
} }
for (p = xff + xfflen - 1; p > xff; p--, xfflen--) { for (p = xff + xfflen - 1; p > xff; p--, xfflen--) {
@ -2910,9 +2844,7 @@ ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r, ngx_addr_t *addr,
} }
} }
if (ngx_parse_addr_port(r->pool, &paddr, p, xfflen - (p - xff)) if (ngx_parse_addr_port(r->pool, &paddr, p, xfflen - (p - xff)) != NGX_OK) {
!= NGX_OK)
{
return NGX_DECLINED; return NGX_DECLINED;
} }
@ -2931,12 +2863,6 @@ ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r, ngx_addr_t *addr,
} }
return NGX_OK; return NGX_OK;
next:
continue;
}
return NGX_DECLINED;
} }