Core: introduced ngx_cidr_match() function.
This commit is contained in:
parent
d7df0f5ff3
commit
6377f87d38
3 changed files with 118 additions and 104 deletions
|
@ -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_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text, size_t len)
|
||||
{
|
||||
|
|
|
@ -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 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_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,
|
||||
size_t len);
|
||||
ngx_int_t ngx_parse_addr_port(ngx_pool_t *pool, ngx_addr_t *addr,
|
||||
|
|
|
@ -2823,120 +2823,46 @@ static ngx_int_t
|
|||
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 *p;
|
||||
in_addr_t inaddr;
|
||||
ngx_int_t rc;
|
||||
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
|
||||
u_char *p;
|
||||
ngx_int_t rc;
|
||||
ngx_addr_t paddr;
|
||||
|
||||
#if (NGX_SUPPRESS_WARN)
|
||||
inaddr = 0;
|
||||
#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_cidr_match(addr->sockaddr, proxies) != NGX_OK) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
#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);
|
||||
for (p = xff + xfflen - 1; p > xff; p--, xfflen--) {
|
||||
if (*p != ' ' && *p != ',') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#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;
|
||||
}
|
||||
for ( /* void */ ; p > xff; p--) {
|
||||
if (*p == ' ' || *p == ',') {
|
||||
p++;
|
||||
break;
|
||||
}
|
||||
|
||||
for (p = xff + xfflen - 1; p > xff; p--, xfflen--) {
|
||||
if (*p != ' ' && *p != ',') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for ( /* void */ ; p > xff; p--) {
|
||||
if (*p == ' ' || *p == ',') {
|
||||
p++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ngx_parse_addr_port(r->pool, &paddr, p, xfflen - (p - xff))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
*addr = paddr;
|
||||
|
||||
if (recursive && p > xff) {
|
||||
rc = ngx_http_get_forwarded_addr_internal(r, addr, xff, p - 1 - xff,
|
||||
proxies, 1);
|
||||
|
||||
if (rc == NGX_DECLINED) {
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
/* rc == NGX_OK || rc == NGX_DONE */
|
||||
return rc;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
|
||||
next:
|
||||
continue;
|
||||
}
|
||||
|
||||
return NGX_DECLINED;
|
||||
if (ngx_parse_addr_port(r->pool, &paddr, p, xfflen - (p - xff)) != NGX_OK) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
*addr = paddr;
|
||||
|
||||
if (recursive && p > xff) {
|
||||
rc = ngx_http_get_forwarded_addr_internal(r, addr, xff, p - 1 - xff,
|
||||
proxies, 1);
|
||||
|
||||
if (rc == NGX_DECLINED) {
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
/* rc == NGX_OK || rc == NGX_DONE */
|
||||
return rc;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue