# HG changeset patch # User Igor Sysoev # Date 1235484100 0 # Node ID a472d954c5347afd0a9fd1fa3ea91cad08b20952 # Parent a6d6d762c55424f3a1778080309f048ae8a3b0e3 prepare ngx_ptocidr() for IPv6 diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c --- a/src/core/ngx_inet.c +++ b/src/core/ngx_inet.c @@ -226,26 +226,25 @@ ngx_inet6_ntop(u_char *p, u_char *text, /* AF_INET only */ 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; - ngx_int_t shift; - ngx_inet_cidr_t *in_cidr; + u_char *addr, *mask, *last; + ngx_int_t shift; - in_cidr = cidr; addr = text->data; last = addr + text->len; 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; } if (mask == NULL) { - in_cidr->mask = 0xffffffff; + cidr->family = AF_INET; + cidr->u.in.mask = 0xffffffff; return NGX_OK; } @@ -256,26 +255,28 @@ ngx_ptocidr(ngx_str_t *text, void *cidr) return NGX_ERROR; } + cidr->family = AF_INET; + if (shift == 0) { /* 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_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; } - in_cidr->addr &= in_cidr->mask; + cidr->u.in.addr &= cidr->u.in.mask; return NGX_DONE; } diff --git a/src/core/ngx_inet.h b/src/core/ngx_inet.h --- a/src/core/ngx_inet.h +++ b/src/core/ngx_inet.h @@ -35,50 +35,71 @@ typedef struct { - in_addr_t addr; - in_addr_t mask; -} ngx_inet_cidr_t; + struct in6_addr addr; + struct in6_addr mask; +} ngx_in6_cidr_t; + + +#if (NGX_HAVE_INET6) + +typedef struct { + in_addr_t addr; + in_addr_t mask; +} 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 { - in_addr_t in_addr; + in_addr_t in_addr; } ngx_url_addr_t; typedef struct { - struct sockaddr *sockaddr; - socklen_t socklen; - ngx_str_t name; + struct sockaddr *sockaddr; + socklen_t socklen; + ngx_str_t name; } ngx_peer_addr_t; typedef struct { - ngx_str_t url; - ngx_str_t host; - ngx_str_t port_text; - ngx_str_t uri; + ngx_str_t url; + ngx_str_t host; + ngx_str_t port_text; + ngx_str_t uri; - in_port_t port; - in_port_t default_port; - int family; + in_port_t port; + in_port_t default_port; + int family; - unsigned listen:1; - unsigned uri_part:1; - unsigned no_resolve:1; - unsigned one_addr:1; + unsigned listen:1; + unsigned uri_part:1; + unsigned no_resolve:1; + unsigned one_addr:1; - unsigned no_port:1; - unsigned wildcard:1; + unsigned no_port:1; + unsigned wildcard:1; - ngx_url_addr_t addr; + ngx_url_addr_t addr; - socklen_t socklen; - u_char sockaddr[NGX_SOCKADDRLEN]; + socklen_t socklen; + u_char sockaddr[NGX_SOCKADDRLEN]; - ngx_peer_addr_t *addrs; - ngx_uint_t naddrs; + ngx_peer_addr_t *addrs; + ngx_uint_t naddrs; - char *err; + char *err; } ngx_url_t; @@ -86,7 +107,7 @@ in_addr_t ngx_inet_addr(u_char *text, si size_t ngx_sock_ntop(struct sockaddr *sa, 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, 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_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u); diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -1040,18 +1040,16 @@ ngx_event_debug_connection(ngx_conf_t *c ngx_str_t *value; ngx_event_debug_t *dc; struct hostent *h; - ngx_inet_cidr_t in_cidr; + ngx_cidr_t cidr; value = cf->args->elts; - /* AF_INET only */ - dc = ngx_array_push(&ecf->debug_connection); if (dc == NULL) { return NGX_CONF_ERROR; } - rc = ngx_ptocidr(&value[1], &in_cidr); + rc = ngx_ptocidr(&value[1], &cidr); if (rc == NGX_DONE) { ngx_conf_log_error(NGX_LOG_WARN, cf, 0, @@ -1060,8 +1058,18 @@ ngx_event_debug_connection(ngx_conf_t *c } 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; } diff --git a/src/http/modules/ngx_http_access_module.c b/src/http/modules/ngx_http_access_module.c --- a/src/http/modules/ngx_http_access_module.c +++ b/src/http/modules/ngx_http_access_module.c @@ -141,7 +141,7 @@ ngx_http_access_rule(ngx_conf_t *cf, ngx ngx_int_t rc; ngx_str_t *value; - ngx_inet_cidr_t in_cidr; + ngx_cidr_t cidr; ngx_http_access_rule_t *rule; if (alcf->rules == NULL) { @@ -168,7 +168,7 @@ ngx_http_access_rule(ngx_conf_t *cf, ngx return NGX_CONF_OK; } - rc = ngx_ptocidr(&value[1], &in_cidr); + rc = ngx_ptocidr(&value[1], &cidr); if (rc == NGX_ERROR) { 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 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) { ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "low address bits of %V are meaningless", &value[1]); } - rule->mask = in_cidr.mask; - rule->addr = in_cidr.addr; + rule->mask = cidr.u.in.mask; + rule->addr = cidr.u.in.addr; return NGX_CONF_OK; } diff --git a/src/http/modules/ngx_http_geo_module.c b/src/http/modules/ngx_http_geo_module.c --- a/src/http/modules/ngx_http_geo_module.c +++ b/src/http/modules/ngx_http_geo_module.c @@ -778,7 +778,7 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_ht ngx_int_t rc, del; ngx_str_t *net; ngx_uint_t i; - ngx_inet_cidr_t cidrin; + ngx_cidr_t cidr; ngx_http_variable_value_t *val, *old; if (ctx->tree == NULL) { @@ -789,8 +789,8 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_ht } if (ngx_strcmp(value[0].data, "default") == 0) { - cidrin.addr = 0; - cidrin.mask = 0; + cidr.u.in.addr = 0; + cidr.u.in.mask = 0; net = &value[0]; } else { @@ -804,11 +804,11 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_ht } if (ngx_strcmp(net->data, "255.255.255.255") == 0) { - cidrin.addr = 0xffffffff; - cidrin.mask = 0xffffffff; + cidr.u.in.addr = 0xffffffff; + cidr.u.in.mask = 0xffffffff; } else { - rc = ngx_ptocidr(net, &cidrin); + rc = ngx_ptocidr(net, &cidr); if (rc == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, @@ -816,18 +816,25 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_ht 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) { ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "low address bits of %V are meaningless", net); } - cidrin.addr = ntohl(cidrin.addr); - cidrin.mask = ntohl(cidrin.mask); + cidr.u.in.addr = ntohl(cidr.u.in.addr); + cidr.u.in.mask = ntohl(cidr.u.in.mask); } 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_conf_log_error(NGX_LOG_WARN, cf, 0, @@ -845,7 +852,7 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_ht } 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); if (rc == NGX_OK) { return NGX_CONF_OK; @@ -858,13 +865,13 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_ht /* rc == NGX_BUSY */ 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, "duplicate network \"%V\", value: \"%v\", old value: \"%v\"", 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) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree"); diff --git a/src/http/modules/ngx_http_realip_module.c b/src/http/modules/ngx_http_realip_module.c --- a/src/http/modules/ngx_http_realip_module.c +++ b/src/http/modules/ngx_http_realip_module.c @@ -282,7 +282,7 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx ngx_int_t rc; ngx_str_t *value; - ngx_inet_cidr_t in_cidr; + ngx_cidr_t cidr; ngx_http_realip_from_t *from; if (rlcf->from == NULL) { @@ -300,7 +300,7 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx value = cf->args->elts; - rc = ngx_ptocidr(&value[1], &in_cidr); + rc = ngx_ptocidr(&value[1], &cidr); if (rc == NGX_ERROR) { 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 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) { ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "low address bits of %V are meaningless", &value[1]); } - from->mask = in_cidr.mask; - from->addr = in_cidr.addr; + from->mask = cidr.u.in.mask; + from->addr = cidr.u.in.addr; return NGX_CONF_OK; }