prepare ngx_ptocidr() for IPv6
diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c
index 497d84a..a5b137d 100644
--- a/src/core/ngx_inet.c
+++ b/src/core/ngx_inet.c
@@ -226,26 +226,25 @@
/* 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 @@
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
index 20d9844..482b0e4 100644
--- 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 @@
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
index 39d3f50..1f2516a 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -1040,18 +1040,16 @@
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 @@
}
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
index 8cd2e0e..78b8a6a 100644
--- a/src/http/modules/ngx_http_access_module.c
+++ b/src/http/modules/ngx_http_access_module.c
@@ -141,7 +141,7 @@
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 @@
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 @@
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
index a8f2685..a389856 100644
--- a/src/http/modules/ngx_http_geo_module.c
+++ b/src/http/modules/ngx_http_geo_module.c
@@ -778,7 +778,7 @@
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 @@
}
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 @@
}
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 @@
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 @@
}
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 @@
/* 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
index 58bdeeb..b069a1e 100644
--- a/src/http/modules/ngx_http_realip_module.c
+++ b/src/http/modules/ngx_http_realip_module.c
@@ -282,7 +282,7 @@
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 @@
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 @@
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;
}