mirror of
https://github.com/nginx/nginx.git
synced 2025-06-07 17:52:38 +08:00
prepare ngx_ptocidr() for IPv6
This commit is contained in:
parent
1f4220ee86
commit
36860101ec
@ -226,26 +226,25 @@ ngx_inet6_ntop(u_char *p, u_char *text, size_t len)
|
|||||||
/* AF_INET only */
|
/* AF_INET only */
|
||||||
|
|
||||||
ngx_int_t
|
ngx_int_t
|
||||||
ngx_ptocidr(ngx_str_t *text, void *cidr)
|
ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr)
|
||||||
{
|
{
|
||||||
u_char *addr, *mask, *last;
|
u_char *addr, *mask, *last;
|
||||||
ngx_int_t shift;
|
ngx_int_t shift;
|
||||||
ngx_inet_cidr_t *in_cidr;
|
|
||||||
|
|
||||||
in_cidr = cidr;
|
|
||||||
addr = text->data;
|
addr = text->data;
|
||||||
last = addr + text->len;
|
last = addr + text->len;
|
||||||
|
|
||||||
mask = ngx_strlchr(addr, last, '/');
|
mask = ngx_strlchr(addr, last, '/');
|
||||||
|
|
||||||
in_cidr->addr = ngx_inet_addr(addr, (mask ? mask : last) - addr);
|
cidr->u.in.addr = ngx_inet_addr(addr, (mask ? mask : last) - addr);
|
||||||
|
|
||||||
if (in_cidr->addr == INADDR_NONE) {
|
if (cidr->u.in.addr == INADDR_NONE) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask == NULL) {
|
if (mask == NULL) {
|
||||||
in_cidr->mask = 0xffffffff;
|
cidr->family = AF_INET;
|
||||||
|
cidr->u.in.mask = 0xffffffff;
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,26 +255,28 @@ ngx_ptocidr(ngx_str_t *text, void *cidr)
|
|||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cidr->family = AF_INET;
|
||||||
|
|
||||||
if (shift == 0) {
|
if (shift == 0) {
|
||||||
|
|
||||||
/* the x86 compilers use the shl instruction that shifts by modulo 32 */
|
/* the x86 compilers use the shl instruction that shifts by modulo 32 */
|
||||||
|
|
||||||
in_cidr->mask = 0;
|
cidr->u.in.mask = 0;
|
||||||
|
|
||||||
if (in_cidr->addr == 0) {
|
if (cidr->u.in.addr == 0) {
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NGX_DONE;
|
return NGX_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
in_cidr->mask = htonl((ngx_uint_t) (0 - (1 << (32 - shift))));
|
cidr->u.in.mask = htonl((ngx_uint_t) (0 - (1 << (32 - shift))));
|
||||||
|
|
||||||
if (in_cidr->addr == (in_cidr->addr & in_cidr->mask)) {
|
if (cidr->u.in.addr == (cidr->u.in.addr & cidr->u.in.mask)) {
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
in_cidr->addr &= in_cidr->mask;
|
cidr->u.in.addr &= cidr->u.in.mask;
|
||||||
|
|
||||||
return NGX_DONE;
|
return NGX_DONE;
|
||||||
}
|
}
|
||||||
|
@ -34,10 +34,31 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct in6_addr addr;
|
||||||
|
struct in6_addr mask;
|
||||||
|
} ngx_in6_cidr_t;
|
||||||
|
|
||||||
|
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
in_addr_t addr;
|
in_addr_t addr;
|
||||||
in_addr_t mask;
|
in_addr_t mask;
|
||||||
} ngx_inet_cidr_t;
|
} ngx_in_cidr_t;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ngx_uint_t family;
|
||||||
|
union {
|
||||||
|
ngx_in_cidr_t in;
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
ngx_in6_cidr_t in6;
|
||||||
|
#endif
|
||||||
|
} u;
|
||||||
|
} ngx_cidr_t;
|
||||||
|
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
@ -86,7 +107,7 @@ in_addr_t ngx_inet_addr(u_char *text, size_t len);
|
|||||||
size_t ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len,
|
size_t ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len,
|
||||||
ngx_uint_t port);
|
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, void *cidr);
|
ngx_int_t ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr);
|
||||||
ngx_int_t ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u);
|
ngx_int_t ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u);
|
||||||
ngx_int_t ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u);
|
ngx_int_t ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u);
|
||||||
|
|
||||||
|
@ -1040,18 +1040,16 @@ ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
ngx_str_t *value;
|
ngx_str_t *value;
|
||||||
ngx_event_debug_t *dc;
|
ngx_event_debug_t *dc;
|
||||||
struct hostent *h;
|
struct hostent *h;
|
||||||
ngx_inet_cidr_t in_cidr;
|
ngx_cidr_t cidr;
|
||||||
|
|
||||||
value = cf->args->elts;
|
value = cf->args->elts;
|
||||||
|
|
||||||
/* AF_INET only */
|
|
||||||
|
|
||||||
dc = ngx_array_push(&ecf->debug_connection);
|
dc = ngx_array_push(&ecf->debug_connection);
|
||||||
if (dc == NULL) {
|
if (dc == NULL) {
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ngx_ptocidr(&value[1], &in_cidr);
|
rc = ngx_ptocidr(&value[1], &cidr);
|
||||||
|
|
||||||
if (rc == NGX_DONE) {
|
if (rc == NGX_DONE) {
|
||||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||||
@ -1060,8 +1058,18 @@ ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rc == NGX_OK) {
|
if (rc == NGX_OK) {
|
||||||
dc->mask = in_cidr.mask;
|
|
||||||
dc->addr = in_cidr.addr;
|
/* AF_INET only */
|
||||||
|
|
||||||
|
if (cidr.family != AF_INET) {
|
||||||
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
|
"\"debug_connection\" supports IPv4 only");
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
dc->mask = cidr.u.in.mask;
|
||||||
|
dc->addr = cidr.u.in.addr;
|
||||||
|
|
||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ ngx_http_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
|
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
ngx_str_t *value;
|
ngx_str_t *value;
|
||||||
ngx_inet_cidr_t in_cidr;
|
ngx_cidr_t cidr;
|
||||||
ngx_http_access_rule_t *rule;
|
ngx_http_access_rule_t *rule;
|
||||||
|
|
||||||
if (alcf->rules == NULL) {
|
if (alcf->rules == NULL) {
|
||||||
@ -168,7 +168,7 @@ ngx_http_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ngx_ptocidr(&value[1], &in_cidr);
|
rc = ngx_ptocidr(&value[1], &cidr);
|
||||||
|
|
||||||
if (rc == NGX_ERROR) {
|
if (rc == NGX_ERROR) {
|
||||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
|
||||||
@ -176,13 +176,19 @@ ngx_http_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cidr.family != AF_INET) {
|
||||||
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
|
"\"allow\" supports IPv4 only");
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (rc == NGX_DONE) {
|
if (rc == NGX_DONE) {
|
||||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||||
"low address bits of %V are meaningless", &value[1]);
|
"low address bits of %V are meaningless", &value[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
rule->mask = in_cidr.mask;
|
rule->mask = cidr.u.in.mask;
|
||||||
rule->addr = in_cidr.addr;
|
rule->addr = cidr.u.in.addr;
|
||||||
|
|
||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
}
|
}
|
||||||
|
@ -778,7 +778,7 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
|
|||||||
ngx_int_t rc, del;
|
ngx_int_t rc, del;
|
||||||
ngx_str_t *net;
|
ngx_str_t *net;
|
||||||
ngx_uint_t i;
|
ngx_uint_t i;
|
||||||
ngx_inet_cidr_t cidrin;
|
ngx_cidr_t cidr;
|
||||||
ngx_http_variable_value_t *val, *old;
|
ngx_http_variable_value_t *val, *old;
|
||||||
|
|
||||||
if (ctx->tree == NULL) {
|
if (ctx->tree == NULL) {
|
||||||
@ -789,8 +789,8 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_strcmp(value[0].data, "default") == 0) {
|
if (ngx_strcmp(value[0].data, "default") == 0) {
|
||||||
cidrin.addr = 0;
|
cidr.u.in.addr = 0;
|
||||||
cidrin.mask = 0;
|
cidr.u.in.mask = 0;
|
||||||
net = &value[0];
|
net = &value[0];
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -804,11 +804,11 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_strcmp(net->data, "255.255.255.255") == 0) {
|
if (ngx_strcmp(net->data, "255.255.255.255") == 0) {
|
||||||
cidrin.addr = 0xffffffff;
|
cidr.u.in.addr = 0xffffffff;
|
||||||
cidrin.mask = 0xffffffff;
|
cidr.u.in.mask = 0xffffffff;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
rc = ngx_ptocidr(net, &cidrin);
|
rc = ngx_ptocidr(net, &cidr);
|
||||||
|
|
||||||
if (rc == NGX_ERROR) {
|
if (rc == NGX_ERROR) {
|
||||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
@ -816,18 +816,25 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
|
|||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cidr.family != AF_INET) {
|
||||||
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
|
"\"geo\" supports IPv4 only");
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (rc == NGX_DONE) {
|
if (rc == NGX_DONE) {
|
||||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||||
"low address bits of %V are meaningless",
|
"low address bits of %V are meaningless",
|
||||||
net);
|
net);
|
||||||
}
|
}
|
||||||
|
|
||||||
cidrin.addr = ntohl(cidrin.addr);
|
cidr.u.in.addr = ntohl(cidr.u.in.addr);
|
||||||
cidrin.mask = ntohl(cidrin.mask);
|
cidr.u.in.mask = ntohl(cidr.u.in.mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (del) {
|
if (del) {
|
||||||
if (ngx_radix32tree_delete(ctx->tree, cidrin.addr, cidrin.mask)
|
if (ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr,
|
||||||
|
cidr.u.in.mask)
|
||||||
!= NGX_OK)
|
!= NGX_OK)
|
||||||
{
|
{
|
||||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||||
@ -845,7 +852,7 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 2; i; i--) {
|
for (i = 2; i; i--) {
|
||||||
rc = ngx_radix32tree_insert(ctx->tree, cidrin.addr, cidrin.mask,
|
rc = ngx_radix32tree_insert(ctx->tree, cidr.u.in.addr, cidr.u.in.mask,
|
||||||
(uintptr_t) val);
|
(uintptr_t) val);
|
||||||
if (rc == NGX_OK) {
|
if (rc == NGX_OK) {
|
||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
@ -858,13 +865,13 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
|
|||||||
/* rc == NGX_BUSY */
|
/* rc == NGX_BUSY */
|
||||||
|
|
||||||
old = (ngx_http_variable_value_t *)
|
old = (ngx_http_variable_value_t *)
|
||||||
ngx_radix32tree_find(ctx->tree, cidrin.addr & cidrin.mask);
|
ngx_radix32tree_find(ctx->tree, cidr.u.in.addr & cidr.u.in.mask);
|
||||||
|
|
||||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||||
"duplicate network \"%V\", value: \"%v\", old value: \"%v\"",
|
"duplicate network \"%V\", value: \"%v\", old value: \"%v\"",
|
||||||
net, val, old);
|
net, val, old);
|
||||||
|
|
||||||
rc = ngx_radix32tree_delete(ctx->tree, cidrin.addr, cidrin.mask);
|
rc = ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr, cidr.u.in.mask);
|
||||||
|
|
||||||
if (rc == NGX_ERROR) {
|
if (rc == NGX_ERROR) {
|
||||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree");
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree");
|
||||||
|
@ -282,7 +282,7 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
|
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
ngx_str_t *value;
|
ngx_str_t *value;
|
||||||
ngx_inet_cidr_t in_cidr;
|
ngx_cidr_t cidr;
|
||||||
ngx_http_realip_from_t *from;
|
ngx_http_realip_from_t *from;
|
||||||
|
|
||||||
if (rlcf->from == NULL) {
|
if (rlcf->from == NULL) {
|
||||||
@ -300,7 +300,7 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
|
|
||||||
value = cf->args->elts;
|
value = cf->args->elts;
|
||||||
|
|
||||||
rc = ngx_ptocidr(&value[1], &in_cidr);
|
rc = ngx_ptocidr(&value[1], &cidr);
|
||||||
|
|
||||||
if (rc == NGX_ERROR) {
|
if (rc == NGX_ERROR) {
|
||||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
|
||||||
@ -308,13 +308,19 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cidr.family != AF_INET) {
|
||||||
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
|
"\"realip_from\" supports IPv4 only");
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (rc == NGX_DONE) {
|
if (rc == NGX_DONE) {
|
||||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||||
"low address bits of %V are meaningless", &value[1]);
|
"low address bits of %V are meaningless", &value[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
from->mask = in_cidr.mask;
|
from->mask = cidr.u.in.mask;
|
||||||
from->addr = in_cidr.addr;
|
from->addr = cidr.u.in.addr;
|
||||||
|
|
||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user