diff options
Diffstat (limited to 'src/http/modules/ngx_http_geo_module.c')
-rw-r--r-- | src/http/modules/ngx_http_geo_module.c | 204 |
1 files changed, 120 insertions, 84 deletions
diff --git a/src/http/modules/ngx_http_geo_module.c b/src/http/modules/ngx_http_geo_module.c index 4bad08d4f..a927ab798 100644 --- a/src/http/modules/ngx_http_geo_module.c +++ b/src/http/modules/ngx_http_geo_module.c @@ -93,6 +93,8 @@ static ngx_uint_t ngx_http_geo_delete_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end); static char *ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *value); +static char *ngx_http_geo_cidr_add(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, + ngx_cidr_t *cidr, ngx_str_t *value, ngx_str_t *net); static ngx_http_variable_value_t *ngx_http_geo_value(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *value); static char *ngx_http_geo_add_proxy(ngx_conf_t *cf, @@ -1014,11 +1016,10 @@ static char * ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *value) { - ngx_int_t rc, del; - ngx_str_t *net; - ngx_uint_t i; - ngx_cidr_t cidr; - ngx_http_variable_value_t *val, *old; + char *rv; + ngx_int_t rc, del; + ngx_str_t *net; + ngx_cidr_t cidr; if (ctx->tree == NULL) { ctx->tree = ngx_radix_tree_create(ctx->pool, -1); @@ -1040,133 +1041,168 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, cidr.family = AF_INET; cidr.u.in.addr = 0; cidr.u.in.mask = 0; - net = &value[0]; - } else { - if (ngx_strcmp(value[0].data, "delete") == 0) { - net = &value[1]; - del = 1; + rv = ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]); - } else { - net = &value[0]; - del = 0; + if (rv != NGX_CONF_OK) { + return rv; } - if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) { - return NGX_CONF_ERROR; - } +#if (NGX_HAVE_INET6) + cidr.family = AF_INET6; + ngx_memzero(&cidr.u.in6, sizeof(ngx_in6_cidr_t)); + + rv = ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]); - if (cidr.family == AF_INET) { - cidr.u.in.addr = ntohl(cidr.u.in.addr); - cidr.u.in.mask = ntohl(cidr.u.in.mask); + if (rv != NGX_CONF_OK) { + return rv; } +#endif + + return NGX_CONF_OK; + } - if (del) { - switch (cidr.family) { + if (ngx_strcmp(value[0].data, "delete") == 0) { + net = &value[1]; + del = 1; + + } else { + net = &value[0]; + del = 0; + } + + if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) { + return NGX_CONF_ERROR; + } + + if (cidr.family == AF_INET) { + cidr.u.in.addr = ntohl(cidr.u.in.addr); + cidr.u.in.mask = ntohl(cidr.u.in.mask); + } + + if (del) { + switch (cidr.family) { #if (NGX_HAVE_INET6) - case AF_INET6: - rc = ngx_radix128tree_delete(ctx->tree6, - cidr.u.in6.addr.s6_addr, - cidr.u.in6.mask.s6_addr); - break; + case AF_INET6: + rc = ngx_radix128tree_delete(ctx->tree6, + cidr.u.in6.addr.s6_addr, + cidr.u.in6.mask.s6_addr); + break; #endif - default: /* AF_INET */ - rc = ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr, - cidr.u.in.mask); - break; - } - - if (rc != NGX_OK) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "no network \"%V\" to delete", net); - } + default: /* AF_INET */ + rc = ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr, + cidr.u.in.mask); + break; + } - return NGX_CONF_OK; + if (rc != NGX_OK) { + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "no network \"%V\" to delete", net); } + + return NGX_CONF_OK; } - val = ngx_http_geo_value(cf, ctx, &value[1]); + return ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], net); +} + + +static char * +ngx_http_geo_cidr_add(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, + ngx_cidr_t *cidr, ngx_str_t *value, ngx_str_t *net) +{ + ngx_int_t rc; + ngx_http_variable_value_t *val, *old; + + val = ngx_http_geo_value(cf, ctx, value); if (val == NULL) { return NGX_CONF_ERROR; } - switch (cidr.family) { + switch (cidr->family) { #if (NGX_HAVE_INET6) case AF_INET6: - for (i = 2; i; i--) { - rc = ngx_radix128tree_insert(ctx->tree6, cidr.u.in6.addr.s6_addr, - cidr.u.in6.mask.s6_addr, - (uintptr_t) val); + rc = ngx_radix128tree_insert(ctx->tree6, cidr->u.in6.addr.s6_addr, + cidr->u.in6.mask.s6_addr, + (uintptr_t) val); - if (rc == NGX_OK) { - return NGX_CONF_OK; - } + if (rc == NGX_OK) { + return NGX_CONF_OK; + } - if (rc == NGX_ERROR) { - return NGX_CONF_ERROR; - } + if (rc == NGX_ERROR) { + return NGX_CONF_ERROR; + } - /* rc == NGX_BUSY */ + /* rc == NGX_BUSY */ - old = (ngx_http_variable_value_t *) - ngx_radix128tree_find(ctx->tree6, - cidr.u.in6.addr.s6_addr); + old = (ngx_http_variable_value_t *) + ngx_radix128tree_find(ctx->tree6, + cidr->u.in6.addr.s6_addr); - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "duplicate network \"%V\", value: \"%v\", old value: \"%v\"", - net, val, old); + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "duplicate network \"%V\", value: \"%v\", old value: \"%v\"", + net, val, old); - rc = ngx_radix128tree_delete(ctx->tree6, - cidr.u.in6.addr.s6_addr, - cidr.u.in6.mask.s6_addr); + rc = ngx_radix128tree_delete(ctx->tree6, + cidr->u.in6.addr.s6_addr, + cidr->u.in6.mask.s6_addr); - if (rc == NGX_ERROR) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree"); - return NGX_CONF_ERROR; - } + if (rc == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree"); + return NGX_CONF_ERROR; } + rc = ngx_radix128tree_insert(ctx->tree6, cidr->u.in6.addr.s6_addr, + cidr->u.in6.mask.s6_addr, + (uintptr_t) val); + break; #endif default: /* AF_INET */ - for (i = 2; i; i--) { - rc = ngx_radix32tree_insert(ctx->tree, cidr.u.in.addr, - cidr.u.in.mask, (uintptr_t) val); + 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; - } + if (rc == NGX_OK) { + return NGX_CONF_OK; + } - if (rc == NGX_ERROR) { - return NGX_CONF_ERROR; - } + if (rc == NGX_ERROR) { + return NGX_CONF_ERROR; + } - /* rc == NGX_BUSY */ + /* rc == NGX_BUSY */ - old = (ngx_http_variable_value_t *) - ngx_radix32tree_find(ctx->tree, cidr.u.in.addr); + old = (ngx_http_variable_value_t *) + ngx_radix32tree_find(ctx->tree, cidr->u.in.addr); - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "duplicate network \"%V\", value: \"%v\", old value: \"%v\"", - net, val, old); + 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, - cidr.u.in.addr, cidr.u.in.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"); - return NGX_CONF_ERROR; - } + if (rc == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree"); + return NGX_CONF_ERROR; } + rc = ngx_radix32tree_insert(ctx->tree, cidr->u.in.addr, + cidr->u.in.mask, (uintptr_t) val); + break; } + if (rc == NGX_OK) { + return NGX_CONF_OK; + } + return NGX_CONF_ERROR; } |