# HG changeset patch # User Vladimir Homutov # Date 1467292370 -10800 # Node ID 80875b75d27eb2e2c9a67b45559ec4107d1ce250 # Parent 558db057adaa7680d3803686c7396f9e085ab618 Stream: geo module. diff --git a/auto/modules b/auto/modules --- a/auto/modules +++ b/auto/modules @@ -1024,6 +1024,16 @@ if [ $STREAM != NO ]; then . auto/module fi + if [ $STREAM_GEO = YES ]; then + ngx_module_name=ngx_stream_geo_module + ngx_module_deps= + ngx_module_srcs=src/stream/ngx_stream_geo_module.c + ngx_module_libs= + ngx_module_link=$STREAM_GEO + + . auto/module + fi + if [ $STREAM_GEOIP != NO ]; then ngx_module_name=ngx_stream_geoip_module ngx_module_deps= diff --git a/auto/options b/auto/options --- a/auto/options +++ b/auto/options @@ -117,6 +117,7 @@ STREAM=NO STREAM_SSL=NO STREAM_LIMIT_CONN=YES STREAM_ACCESS=YES +STREAM_GEO=YES STREAM_GEOIP=NO STREAM_MAP=YES STREAM_RETURN=YES @@ -300,6 +301,7 @@ use the \"--with-mail_ssl_module\" optio --without-stream_limit_conn_module) STREAM_LIMIT_CONN=NO ;; --without-stream_access_module) STREAM_ACCESS=NO ;; + --without-stream_geo_module) STREAM_GEO=NO ;; --without-stream_map_module) STREAM_MAP=NO ;; --without-stream_return_module) STREAM_RETURN=NO ;; --without-stream_upstream_hash_module) @@ -502,6 +504,7 @@ cat << END --with-stream_geoip_module=dynamic enable dynamic ngx_stream_geoip_module --without-stream_limit_conn_module disable ngx_stream_limit_conn_module --without-stream_access_module disable ngx_stream_access_module + --without-stream_geo_module disable ngx_stream_geo_module --without-stream_map_module disable ngx_stream_map_module --without-stream_return_module disable ngx_stream_return_module --without-stream_upstream_hash_module diff --git a/src/http/modules/ngx_http_geo_module.c b/src/stream/ngx_stream_geo_module.c copy from src/http/modules/ngx_http_geo_module.c copy to src/stream/ngx_stream_geo_module.c --- a/src/http/modules/ngx_http_geo_module.c +++ b/src/stream/ngx_stream_geo_module.c @@ -7,115 +7,109 @@ #include #include -#include +#include typedef struct { - ngx_http_variable_value_t *value; - u_short start; - u_short end; -} ngx_http_geo_range_t; + ngx_stream_variable_value_t *value; + u_short start; + u_short end; +} ngx_stream_geo_range_t; typedef struct { - ngx_radix_tree_t *tree; + ngx_radix_tree_t *tree; #if (NGX_HAVE_INET6) - ngx_radix_tree_t *tree6; + ngx_radix_tree_t *tree6; #endif -} ngx_http_geo_trees_t; +} ngx_stream_geo_trees_t; typedef struct { - ngx_http_geo_range_t **low; - ngx_http_variable_value_t *default_value; -} ngx_http_geo_high_ranges_t; + ngx_stream_geo_range_t **low; + ngx_stream_variable_value_t *default_value; +} ngx_stream_geo_high_ranges_t; typedef struct { - ngx_str_node_t sn; - ngx_http_variable_value_t *value; - size_t offset; -} ngx_http_geo_variable_value_node_t; + ngx_str_node_t sn; + ngx_stream_variable_value_t *value; + size_t offset; +} ngx_stream_geo_variable_value_node_t; typedef struct { - ngx_http_variable_value_t *value; - ngx_str_t *net; - ngx_http_geo_high_ranges_t high; - ngx_radix_tree_t *tree; + ngx_stream_variable_value_t *value; + ngx_str_t *net; + ngx_stream_geo_high_ranges_t high; + ngx_radix_tree_t *tree; #if (NGX_HAVE_INET6) - ngx_radix_tree_t *tree6; + ngx_radix_tree_t *tree6; #endif - ngx_rbtree_t rbtree; - ngx_rbtree_node_t sentinel; - ngx_array_t *proxies; - ngx_pool_t *pool; - ngx_pool_t *temp_pool; + ngx_rbtree_t rbtree; + ngx_rbtree_node_t sentinel; + ngx_pool_t *pool; + ngx_pool_t *temp_pool; - size_t data_size; + size_t data_size; - ngx_str_t include_name; - ngx_uint_t includes; - ngx_uint_t entries; + ngx_str_t include_name; + ngx_uint_t includes; + ngx_uint_t entries; - unsigned ranges:1; - unsigned outside_entries:1; - unsigned allow_binary_include:1; - unsigned binary_include:1; - unsigned proxy_recursive:1; -} ngx_http_geo_conf_ctx_t; + unsigned ranges:1; + unsigned outside_entries:1; + unsigned allow_binary_include:1; + unsigned binary_include:1; +} ngx_stream_geo_conf_ctx_t; typedef struct { union { - ngx_http_geo_trees_t trees; - ngx_http_geo_high_ranges_t high; + ngx_stream_geo_trees_t trees; + ngx_stream_geo_high_ranges_t high; } u; - ngx_array_t *proxies; - unsigned proxy_recursive:1; - - ngx_int_t index; -} ngx_http_geo_ctx_t; + ngx_int_t index; +} ngx_stream_geo_ctx_t; -static ngx_int_t ngx_http_geo_addr(ngx_http_request_t *r, - ngx_http_geo_ctx_t *ctx, ngx_addr_t *addr); -static ngx_int_t ngx_http_geo_real_addr(ngx_http_request_t *r, - ngx_http_geo_ctx_t *ctx, ngx_addr_t *addr); -static char *ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -static char *ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf); -static char *ngx_http_geo_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, - ngx_str_t *value); -static char *ngx_http_geo_add_range(ngx_conf_t *cf, - ngx_http_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end); -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, - ngx_http_geo_conf_ctx_t *ctx, ngx_cidr_t *cidr); -static ngx_int_t ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, +static ngx_int_t ngx_stream_geo_addr(ngx_stream_session_t *s, + ngx_stream_geo_ctx_t *ctx, ngx_addr_t *addr); + +static char *ngx_stream_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); +static char *ngx_stream_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf); +static char *ngx_stream_geo_range(ngx_conf_t *cf, + ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *value); +static char *ngx_stream_geo_add_range(ngx_conf_t *cf, + ngx_stream_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end); +static ngx_uint_t ngx_stream_geo_delete_range(ngx_conf_t *cf, + ngx_stream_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end); +static char *ngx_stream_geo_cidr(ngx_conf_t *cf, + ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *value); +static char *ngx_stream_geo_cidr_add(ngx_conf_t *cf, + ngx_stream_geo_conf_ctx_t *ctx, ngx_cidr_t *cidr, ngx_str_t *value, + ngx_str_t *net); +static ngx_stream_variable_value_t *ngx_stream_geo_value(ngx_conf_t *cf, + ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *value); +static ngx_int_t ngx_stream_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr); -static char *ngx_http_geo_include(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, - ngx_str_t *name); -static ngx_int_t ngx_http_geo_include_binary_base(ngx_conf_t *cf, - ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *name); -static void ngx_http_geo_create_binary_base(ngx_http_geo_conf_ctx_t *ctx); -static u_char *ngx_http_geo_copy_values(u_char *base, u_char *p, +static char *ngx_stream_geo_include(ngx_conf_t *cf, + ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *name); +static ngx_int_t ngx_stream_geo_include_binary_base(ngx_conf_t *cf, + ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *name); +static void ngx_stream_geo_create_binary_base(ngx_stream_geo_conf_ctx_t *ctx); +static u_char *ngx_stream_geo_copy_values(u_char *base, u_char *p, ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel); -static ngx_command_t ngx_http_geo_commands[] = { +static ngx_command_t ngx_stream_geo_commands[] = { { ngx_string("geo"), - NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12, - ngx_http_geo_block, - NGX_HTTP_MAIN_CONF_OFFSET, + NGX_STREAM_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12, + ngx_stream_geo_block, + 0, 0, NULL }, @@ -123,7 +117,7 @@ static ngx_command_t ngx_http_geo_comma }; -static ngx_http_module_t ngx_http_geo_module_ctx = { +static ngx_stream_module_t ngx_stream_geo_module_ctx = { NULL, /* preconfiguration */ NULL, /* postconfiguration */ @@ -131,18 +125,15 @@ static ngx_http_module_t ngx_http_geo_m NULL, /* init main configuration */ NULL, /* create server configuration */ - NULL, /* merge server configuration */ - - NULL, /* create location configuration */ - NULL /* merge location configuration */ + NULL /* merge server configuration */ }; -ngx_module_t ngx_http_geo_module = { +ngx_module_t ngx_stream_geo_module = { NGX_MODULE_V1, - &ngx_http_geo_module_ctx, /* module context */ - ngx_http_geo_commands, /* module directives */ - NGX_HTTP_MODULE, /* module type */ + &ngx_stream_geo_module_ctx, /* module context */ + ngx_stream_geo_commands, /* module directives */ + NGX_STREAM_MODULE, /* module type */ NULL, /* init master */ NULL, /* init module */ NULL, /* init process */ @@ -160,10 +151,10 @@ typedef struct { u_char ptr_size; uint32_t endianness; uint32_t crc32; -} ngx_http_geo_header_t; +} ngx_stream_geo_header_t; -static ngx_http_geo_header_t ngx_http_geo_header = { +static ngx_stream_geo_header_t ngx_stream_geo_header = { { 'G', 'E', 'O', 'R', 'N', 'G' }, 0, sizeof(void *), 0x12345678, 0 }; @@ -171,22 +162,22 @@ static ngx_http_geo_header_t ngx_http_g /* geo range is AF_INET only */ static ngx_int_t -ngx_http_geo_cidr_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, - uintptr_t data) +ngx_stream_geo_cidr_variable(ngx_stream_session_t *s, + ngx_stream_variable_value_t *v, uintptr_t data) { - ngx_http_geo_ctx_t *ctx = (ngx_http_geo_ctx_t *) data; + ngx_stream_geo_ctx_t *ctx = (ngx_stream_geo_ctx_t *) data; - in_addr_t inaddr; - ngx_addr_t addr; - struct sockaddr_in *sin; - ngx_http_variable_value_t *vv; + in_addr_t inaddr; + ngx_addr_t addr; + struct sockaddr_in *sin; + ngx_stream_variable_value_t *vv; #if (NGX_HAVE_INET6) - u_char *p; - struct in6_addr *inaddr6; + u_char *p; + struct in6_addr *inaddr6; #endif - if (ngx_http_geo_addr(r, ctx, &addr) != NGX_OK) { - vv = (ngx_http_variable_value_t *) + if (ngx_stream_geo_addr(s, ctx, &addr) != NGX_OK) { + vv = (ngx_stream_variable_value_t *) ngx_radix32tree_find(ctx->u.trees.tree, INADDR_NONE); goto done; } @@ -204,11 +195,11 @@ ngx_http_geo_cidr_variable(ngx_http_requ inaddr += p[14] << 8; inaddr += p[15]; - vv = (ngx_http_variable_value_t *) + vv = (ngx_stream_variable_value_t *) ngx_radix32tree_find(ctx->u.trees.tree, inaddr); } else { - vv = (ngx_http_variable_value_t *) + vv = (ngx_stream_variable_value_t *) ngx_radix128tree_find(ctx->u.trees.tree6, p); } @@ -219,7 +210,7 @@ ngx_http_geo_cidr_variable(ngx_http_requ sin = (struct sockaddr_in *) addr.sockaddr; inaddr = ntohl(sin->sin_addr.s_addr); - vv = (ngx_http_variable_value_t *) + vv = (ngx_stream_variable_value_t *) ngx_radix32tree_find(ctx->u.trees.tree, inaddr); break; @@ -229,32 +220,32 @@ done: *v = *vv; - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http geo: %v", v); + ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, + "stream geo: %v", v); return NGX_OK; } static ngx_int_t -ngx_http_geo_range_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, - uintptr_t data) +ngx_stream_geo_range_variable(ngx_stream_session_t *s, + ngx_stream_variable_value_t *v, uintptr_t data) { - ngx_http_geo_ctx_t *ctx = (ngx_http_geo_ctx_t *) data; + ngx_stream_geo_ctx_t *ctx = (ngx_stream_geo_ctx_t *) data; - in_addr_t inaddr; - ngx_addr_t addr; - ngx_uint_t n; - struct sockaddr_in *sin; - ngx_http_geo_range_t *range; + in_addr_t inaddr; + ngx_addr_t addr; + ngx_uint_t n; + struct sockaddr_in *sin; + ngx_stream_geo_range_t *range; #if (NGX_HAVE_INET6) - u_char *p; - struct in6_addr *inaddr6; + u_char *p; + struct in6_addr *inaddr6; #endif *v = *ctx->u.high.default_value; - if (ngx_http_geo_addr(r, ctx, &addr) == NGX_OK) { + if (ngx_stream_geo_addr(s, ctx, &addr) == NGX_OK) { switch (addr.sockaddr->sa_family) { @@ -303,64 +294,43 @@ ngx_http_geo_range_variable(ngx_http_req } } - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http geo: %v", v); - - return NGX_OK; -} - - -static ngx_int_t -ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx, - ngx_addr_t *addr) -{ - ngx_array_t *xfwd; - - if (ngx_http_geo_real_addr(r, ctx, addr) != NGX_OK) { - return NGX_ERROR; - } - - xfwd = &r->headers_in.x_forwarded_for; - - if (xfwd->nelts > 0 && ctx->proxies != NULL) { - (void) ngx_http_get_forwarded_addr(r, addr, xfwd, NULL, - ctx->proxies, ctx->proxy_recursive); - } + ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, + "stream geo: %v", v); return NGX_OK; } static ngx_int_t -ngx_http_geo_real_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx, +ngx_stream_geo_addr(ngx_stream_session_t *s, ngx_stream_geo_ctx_t *ctx, ngx_addr_t *addr) { - ngx_http_variable_value_t *v; + ngx_stream_variable_value_t *v; if (ctx->index == -1) { - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http geo started: %V", &r->connection->addr_text); + ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, + "stream geo started: %V", &s->connection->addr_text); - addr->sockaddr = r->connection->sockaddr; - addr->socklen = r->connection->socklen; - /* addr->name = r->connection->addr_text; */ + addr->sockaddr = s->connection->sockaddr; + addr->socklen = s->connection->socklen; + /* addr->name = s->connection->addr_text; */ return NGX_OK; } - v = ngx_http_get_flushed_variable(r, ctx->index); + v = ngx_stream_get_flushed_variable(s, ctx->index); if (v == NULL || v->not_found) { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http geo not found"); + ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, + "stream geo not found"); return NGX_ERROR; } - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http geo started: %v", v); + ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, + "stream geo started: %v", v); - if (ngx_parse_addr(r->pool, addr, v->data, v->len) == NGX_OK) { + if (ngx_parse_addr(s->connection->pool, addr, v->data, v->len) == NGX_OK) { return NGX_OK; } @@ -369,25 +339,25 @@ ngx_http_geo_real_addr(ngx_http_request_ static char * -ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +ngx_stream_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - char *rv; - size_t len; - ngx_str_t *value, name; - ngx_uint_t i; - ngx_conf_t save; - ngx_pool_t *pool; - ngx_array_t *a; - ngx_http_variable_t *var; - ngx_http_geo_ctx_t *geo; - ngx_http_geo_conf_ctx_t ctx; + char *rv; + size_t len; + ngx_str_t *value, name; + ngx_uint_t i; + ngx_conf_t save; + ngx_pool_t *pool; + ngx_array_t *a; + ngx_stream_variable_t *var; + ngx_stream_geo_ctx_t *geo; + ngx_stream_geo_conf_ctx_t ctx; #if (NGX_HAVE_INET6) - static struct in6_addr zero; + static struct in6_addr zero; #endif value = cf->args->elts; - geo = ngx_palloc(cf->pool, sizeof(ngx_http_geo_ctx_t)); + geo = ngx_palloc(cf->pool, sizeof(ngx_stream_geo_ctx_t)); if (geo == NULL) { return NGX_CONF_ERROR; } @@ -405,7 +375,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_c if (cf->args->nelts == 3) { - geo->index = ngx_http_get_variable_index(cf, &name); + geo->index = ngx_stream_get_variable_index(cf, &name); if (geo->index == NGX_ERROR) { return NGX_CONF_ERROR; } @@ -425,7 +395,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_c geo->index = -1; } - var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE); + var = ngx_stream_add_variable(cf, &name, NGX_STREAM_VAR_CHANGEABLE); if (var == NULL) { return NGX_CONF_ERROR; } @@ -435,7 +405,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_c return NGX_CONF_ERROR; } - ngx_memzero(&ctx, sizeof(ngx_http_geo_conf_ctx_t)); + ngx_memzero(&ctx, sizeof(ngx_stream_geo_conf_ctx_t)); ctx.temp_pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, cf->log); if (ctx.temp_pool == NULL) { @@ -445,24 +415,21 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_c ngx_rbtree_init(&ctx.rbtree, &ctx.sentinel, ngx_str_rbtree_insert_value); ctx.pool = cf->pool; - ctx.data_size = sizeof(ngx_http_geo_header_t) - + sizeof(ngx_http_variable_value_t) - + 0x10000 * sizeof(ngx_http_geo_range_t *); + ctx.data_size = sizeof(ngx_stream_geo_header_t) + + sizeof(ngx_stream_variable_value_t) + + 0x10000 * sizeof(ngx_stream_geo_range_t *); ctx.allow_binary_include = 1; save = *cf; cf->pool = pool; cf->ctx = &ctx; - cf->handler = ngx_http_geo; + cf->handler = ngx_stream_geo; cf->handler_conf = conf; rv = ngx_conf_parse(cf, NULL); *cf = save; - geo->proxies = ctx.proxies; - geo->proxy_recursive = ctx.proxy_recursive; - if (ctx.ranges) { if (ctx.high.low && !ctx.binary_include) { @@ -473,7 +440,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_c continue; } - len = a->nelts * sizeof(ngx_http_geo_range_t); + len = a->nelts * sizeof(ngx_stream_geo_range_t); ctx.high.low[i] = ngx_palloc(cf->pool, len + sizeof(void *)); if (ctx.high.low[i] == NULL) { @@ -490,17 +457,17 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_c && ctx.entries > 100000 && ctx.includes == 1) { - ngx_http_geo_create_binary_base(&ctx); + ngx_stream_geo_create_binary_base(&ctx); } } if (ctx.high.default_value == NULL) { - ctx.high.default_value = &ngx_http_variable_null_value; + ctx.high.default_value = &ngx_stream_variable_null_value; } geo->u.high = ctx.high; - var->get_handler = ngx_http_geo_range_variable; + var->get_handler = ngx_stream_geo_range_variable; var->data = (uintptr_t) geo; ngx_destroy_pool(ctx.temp_pool); @@ -527,14 +494,14 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_c geo->u.trees.tree6 = ctx.tree6; #endif - var->get_handler = ngx_http_geo_cidr_variable; + var->get_handler = ngx_stream_geo_cidr_variable; var->data = (uintptr_t) geo; ngx_destroy_pool(ctx.temp_pool); ngx_destroy_pool(pool); if (ngx_radix32tree_insert(ctx.tree, 0, 0, - (uintptr_t) &ngx_http_variable_null_value) + (uintptr_t) &ngx_stream_variable_null_value) == NGX_ERROR) { return NGX_CONF_ERROR; @@ -544,7 +511,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_c #if (NGX_HAVE_INET6) if (ngx_radix128tree_insert(ctx.tree6, zero.s6_addr, zero.s6_addr, - (uintptr_t) &ngx_http_variable_null_value) + (uintptr_t) &ngx_stream_variable_null_value) == NGX_ERROR) { return NGX_CONF_ERROR; @@ -557,12 +524,11 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_c static char * -ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) +ngx_stream_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) { - char *rv; - ngx_str_t *value; - ngx_cidr_t cidr; - ngx_http_geo_conf_ctx_t *ctx; + char *rv; + ngx_str_t *value; + ngx_stream_geo_conf_ctx_t *ctx; ctx = cf->ctx; @@ -590,12 +556,6 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command goto done; } - - else if (ngx_strcmp(value[0].data, "proxy_recursive") == 0) { - ctx->proxy_recursive = 1; - rv = NGX_CONF_OK; - goto done; - } } if (cf->args->nelts != 2) { @@ -606,26 +566,16 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command if (ngx_strcmp(value[0].data, "include") == 0) { - rv = ngx_http_geo_include(cf, ctx, &value[1]); - - goto done; - - } else if (ngx_strcmp(value[0].data, "proxy") == 0) { - - if (ngx_http_geo_cidr_value(cf, &value[1], &cidr) != NGX_OK) { - goto failed; - } - - rv = ngx_http_geo_add_proxy(cf, ctx, &cidr); + rv = ngx_stream_geo_include(cf, ctx, &value[1]); goto done; } if (ctx->ranges) { - rv = ngx_http_geo_range(cf, ctx, value); + rv = ngx_stream_geo_range(cf, ctx, value); } else { - rv = ngx_http_geo_cidr(cf, ctx, value); + rv = ngx_stream_geo_cidr(cf, ctx, value); } done: @@ -643,7 +593,7 @@ failed: static char * -ngx_http_geo_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, +ngx_stream_geo_range(ngx_conf_t *cf, ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *value) { u_char *p, *last; @@ -659,7 +609,7 @@ ngx_http_geo_range(ngx_conf_t *cf, ngx_h &value[1], ctx->high.default_value); } - ctx->high.default_value = ngx_http_geo_value(cf, ctx, &value[1]); + ctx->high.default_value = ngx_stream_geo_value(cf, ctx, &value[1]); if (ctx->high.default_value == NULL) { return NGX_CONF_ERROR; } @@ -676,7 +626,7 @@ ngx_http_geo_range(ngx_conf_t *cf, ngx_h if (ctx->high.low == NULL) { ctx->high.low = ngx_pcalloc(ctx->pool, - 0x10000 * sizeof(ngx_http_geo_range_t *)); + 0x10000 * sizeof(ngx_stream_geo_range_t *)); if (ctx->high.low == NULL) { return NGX_CONF_ERROR; } @@ -725,7 +675,7 @@ ngx_http_geo_range(ngx_conf_t *cf, ngx_h } if (del) { - if (ngx_http_geo_delete_range(cf, ctx, start, end)) { + if (ngx_stream_geo_delete_range(cf, ctx, start, end)) { ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "no address range \"%V\" to delete", net); } @@ -733,7 +683,7 @@ ngx_http_geo_range(ngx_conf_t *cf, ngx_h return NGX_CONF_OK; } - ctx->value = ngx_http_geo_value(cf, ctx, &value[1]); + ctx->value = ngx_stream_geo_value(cf, ctx, &value[1]); if (ctx->value == NULL) { return NGX_CONF_ERROR; @@ -741,7 +691,7 @@ ngx_http_geo_range(ngx_conf_t *cf, ngx_h ctx->net = net; - return ngx_http_geo_add_range(cf, ctx, start, end); + return ngx_stream_geo_add_range(cf, ctx, start, end); invalid: @@ -754,13 +704,13 @@ invalid: /* the add procedure is optimized to add a growing up sequence */ static char * -ngx_http_geo_add_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, +ngx_stream_geo_add_range(ngx_conf_t *cf, ngx_stream_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end) { - in_addr_t n; - ngx_uint_t h, i, s, e; - ngx_array_t *a; - ngx_http_geo_range_t *range; + in_addr_t n; + ngx_uint_t h, i, s, e; + ngx_array_t *a; + ngx_stream_geo_range_t *range; for (n = start; n <= end; n = (n + 0x10000) & 0xffff0000) { @@ -783,12 +733,12 @@ ngx_http_geo_add_range(ngx_conf_t *cf, n if (a == NULL) { a = ngx_array_create(ctx->temp_pool, 64, - sizeof(ngx_http_geo_range_t)); + sizeof(ngx_stream_geo_range_t)); if (a == NULL) { return NGX_CONF_ERROR; } - ctx->high.low[h] = (ngx_http_geo_range_t *) a; + ctx->high.low[h] = (ngx_stream_geo_range_t *) a; } i = a->nelts; @@ -814,7 +764,7 @@ ngx_http_geo_add_range(ngx_conf_t *cf, n range = a->elts; ngx_memmove(&range[i + 2], &range[i + 1], - (a->nelts - 2 - i) * sizeof(ngx_http_geo_range_t)); + (a->nelts - 2 - i) * sizeof(ngx_stream_geo_range_t)); range[i + 1].start = (u_short) s; range[i + 1].end = (u_short) e; @@ -853,7 +803,7 @@ ngx_http_geo_add_range(ngx_conf_t *cf, n range = a->elts; ngx_memmove(&range[i + 3], &range[i + 1], - (a->nelts - 3 - i) * sizeof(ngx_http_geo_range_t)); + (a->nelts - 3 - i) * sizeof(ngx_stream_geo_range_t)); range[i + 2].start = (u_short) (e + 1); range[i + 2].end = range[i].end; @@ -881,7 +831,7 @@ ngx_http_geo_add_range(ngx_conf_t *cf, n range = a->elts; ngx_memmove(&range[i + 1], &range[i], - (a->nelts - 1 - i) * sizeof(ngx_http_geo_range_t)); + (a->nelts - 1 - i) * sizeof(ngx_stream_geo_range_t)); range[i + 1].start = (u_short) (e + 1); @@ -905,7 +855,7 @@ ngx_http_geo_add_range(ngx_conf_t *cf, n range = a->elts; ngx_memmove(&range[i + 2], &range[i + 1], - (a->nelts - 2 - i) * sizeof(ngx_http_geo_range_t)); + (a->nelts - 2 - i) * sizeof(ngx_stream_geo_range_t)); range[i + 1].start = (u_short) s; range[i + 1].end = (u_short) e; @@ -949,13 +899,13 @@ ngx_http_geo_add_range(ngx_conf_t *cf, n static ngx_uint_t -ngx_http_geo_delete_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, +ngx_stream_geo_delete_range(ngx_conf_t *cf, ngx_stream_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end) { - in_addr_t n; - ngx_uint_t h, i, s, e, warn; - ngx_array_t *a; - ngx_http_geo_range_t *range; + in_addr_t n; + ngx_uint_t h, i, s, e, warn; + ngx_array_t *a; + ngx_stream_geo_range_t *range; warn = 0; @@ -990,7 +940,7 @@ ngx_http_geo_delete_range(ngx_conf_t *cf && e == (ngx_uint_t) range[i].end) { ngx_memmove(&range[i], &range[i + 1], - (a->nelts - 1 - i) * sizeof(ngx_http_geo_range_t)); + (a->nelts - 1 - i) * sizeof(ngx_stream_geo_range_t)); a->nelts--; @@ -1012,7 +962,7 @@ ngx_http_geo_delete_range(ngx_conf_t *cf static char * -ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, +ngx_stream_geo_cidr(ngx_conf_t *cf, ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *value) { char *rv; @@ -1041,7 +991,7 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_ht cidr.u.in.addr = 0; cidr.u.in.mask = 0; - rv = ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]); + rv = ngx_stream_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]); if (rv != NGX_CONF_OK) { return rv; @@ -1051,7 +1001,7 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_ht 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]); + rv = ngx_stream_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]); if (rv != NGX_CONF_OK) { return rv; @@ -1070,7 +1020,7 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_ht del = 0; } - if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) { + if (ngx_stream_geo_cidr_value(cf, net, &cidr) != NGX_OK) { return NGX_CONF_ERROR; } @@ -1104,18 +1054,18 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_ht return NGX_CONF_OK; } - return ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], net); + return ngx_stream_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_stream_geo_cidr_add(ngx_conf_t *cf, ngx_stream_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; + ngx_int_t rc; + ngx_stream_variable_value_t *val, *old; - val = ngx_http_geo_value(cf, ctx, value); + val = ngx_stream_geo_value(cf, ctx, value); if (val == NULL) { return NGX_CONF_ERROR; @@ -1139,7 +1089,7 @@ ngx_http_geo_cidr_add(ngx_conf_t *cf, ng /* rc == NGX_BUSY */ - old = (ngx_http_variable_value_t *) + old = (ngx_stream_variable_value_t *) ngx_radix128tree_find(ctx->tree6, cidr->u.in6.addr.s6_addr); @@ -1177,7 +1127,7 @@ ngx_http_geo_cidr_add(ngx_conf_t *cf, ng /* rc == NGX_BUSY */ - old = (ngx_http_variable_value_t *) + old = (ngx_stream_variable_value_t *) ngx_radix32tree_find(ctx->tree, cidr->u.in.addr); ngx_conf_log_error(NGX_LOG_WARN, cf, 0, @@ -1206,24 +1156,24 @@ ngx_http_geo_cidr_add(ngx_conf_t *cf, ng } -static ngx_http_variable_value_t * -ngx_http_geo_value(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, +static ngx_stream_variable_value_t * +ngx_stream_geo_value(ngx_conf_t *cf, ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *value) { - uint32_t hash; - ngx_http_variable_value_t *val; - ngx_http_geo_variable_value_node_t *gvvn; + uint32_t hash; + ngx_stream_variable_value_t *val; + ngx_stream_geo_variable_value_node_t *gvvn; hash = ngx_crc32_long(value->data, value->len); - gvvn = (ngx_http_geo_variable_value_node_t *) + gvvn = (ngx_stream_geo_variable_value_node_t *) ngx_str_rbtree_lookup(&ctx->rbtree, value, hash); if (gvvn) { return gvvn->value; } - val = ngx_palloc(ctx->pool, sizeof(ngx_http_variable_value_t)); + val = ngx_palloc(ctx->pool, sizeof(ngx_stream_variable_value_t)); if (val == NULL) { return NULL; } @@ -1239,7 +1189,7 @@ ngx_http_geo_value(ngx_conf_t *cf, ngx_h val->not_found = 0; gvvn = ngx_palloc(ctx->temp_pool, - sizeof(ngx_http_geo_variable_value_node_t)); + sizeof(ngx_stream_geo_variable_value_node_t)); if (gvvn == NULL) { return NULL; } @@ -1252,39 +1202,15 @@ ngx_http_geo_value(ngx_conf_t *cf, ngx_h ngx_rbtree_insert(&ctx->rbtree, &gvvn->sn.node); - ctx->data_size += ngx_align(sizeof(ngx_http_variable_value_t) + value->len, - sizeof(void *)); + ctx->data_size += ngx_align(sizeof(ngx_stream_variable_value_t) + + value->len, sizeof(void *)); return val; } -static char * -ngx_http_geo_add_proxy(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, - ngx_cidr_t *cidr) -{ - ngx_cidr_t *c; - - if (ctx->proxies == NULL) { - ctx->proxies = ngx_array_create(ctx->pool, 4, sizeof(ngx_cidr_t)); - if (ctx->proxies == NULL) { - return NGX_CONF_ERROR; - } - } - - c = ngx_array_push(ctx->proxies); - if (c == NULL) { - return NGX_CONF_ERROR; - } - - *c = *cidr; - - return NGX_CONF_OK; -} - - static ngx_int_t -ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr) +ngx_stream_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr) { ngx_int_t rc; @@ -1313,7 +1239,7 @@ ngx_http_geo_cidr_value(ngx_conf_t *cf, static char * -ngx_http_geo_include(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, +ngx_stream_geo_include(ngx_conf_t *cf, ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *name) { char *rv; @@ -1334,7 +1260,7 @@ ngx_http_geo_include(ngx_conf_t *cf, ngx if (ctx->ranges) { ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data); - switch (ngx_http_geo_include_binary_base(cf, ctx, &file)) { + switch (ngx_stream_geo_include_binary_base(cf, ctx, &file)) { case NGX_OK: return NGX_CONF_OK; case NGX_ERROR: @@ -1365,22 +1291,22 @@ ngx_http_geo_include(ngx_conf_t *cf, ngx static ngx_int_t -ngx_http_geo_include_binary_base(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, - ngx_str_t *name) +ngx_stream_geo_include_binary_base(ngx_conf_t *cf, + ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *name) { - u_char *base, ch; - time_t mtime; - size_t size, len; - ssize_t n; - uint32_t crc32; - ngx_err_t err; - ngx_int_t rc; - ngx_uint_t i; - ngx_file_t file; - ngx_file_info_t fi; - ngx_http_geo_range_t *range, **ranges; - ngx_http_geo_header_t *header; - ngx_http_variable_value_t *vv; + u_char *base, ch; + time_t mtime; + size_t size, len; + ssize_t n; + uint32_t crc32; + ngx_err_t err; + ngx_int_t rc; + ngx_uint_t i; + ngx_file_t file; + ngx_file_info_t fi; + ngx_stream_geo_range_t *range, **ranges; + ngx_stream_geo_header_t *header; + ngx_stream_variable_value_t *vv; ngx_memzero(&file, sizeof(ngx_file_t)); file.name = *name; @@ -1458,9 +1384,9 @@ ngx_http_geo_include_binary_base(ngx_con goto failed; } - header = (ngx_http_geo_header_t *) base; + header = (ngx_stream_geo_header_t *) base; - if (size < 16 || ngx_memcmp(&ngx_http_geo_header, header, 12) != 0) { + if (size < 16 || ngx_memcmp(&ngx_stream_geo_header, header, 12) != 0) { ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "incompatible binary geo range base \"%s\"", name->data); goto failed; @@ -1468,40 +1394,42 @@ ngx_http_geo_include_binary_base(ngx_con ngx_crc32_init(crc32); - vv = (ngx_http_variable_value_t *) (base + sizeof(ngx_http_geo_header_t)); + vv = (ngx_stream_variable_value_t *) + (base + sizeof(ngx_stream_geo_header_t)); while (vv->data) { - len = ngx_align(sizeof(ngx_http_variable_value_t) + vv->len, + len = ngx_align(sizeof(ngx_stream_variable_value_t) + vv->len, sizeof(void *)); ngx_crc32_update(&crc32, (u_char *) vv, len); vv->data += (size_t) base; - vv = (ngx_http_variable_value_t *) ((u_char *) vv + len); + vv = (ngx_stream_variable_value_t *) ((u_char *) vv + len); } - ngx_crc32_update(&crc32, (u_char *) vv, sizeof(ngx_http_variable_value_t)); + ngx_crc32_update(&crc32, (u_char *) vv, + sizeof(ngx_stream_variable_value_t)); vv++; - ranges = (ngx_http_geo_range_t **) vv; + ranges = (ngx_stream_geo_range_t **) vv; for (i = 0; i < 0x10000; i++) { ngx_crc32_update(&crc32, (u_char *) &ranges[i], sizeof(void *)); if (ranges[i]) { - ranges[i] = (ngx_http_geo_range_t *) + ranges[i] = (ngx_stream_geo_range_t *) ((u_char *) ranges[i] + (size_t) base); } } - range = (ngx_http_geo_range_t *) &ranges[0x10000]; + range = (ngx_stream_geo_range_t *) &ranges[0x10000]; while ((u_char *) range < base + size) { while (range->value) { ngx_crc32_update(&crc32, (u_char *) range, - sizeof(ngx_http_geo_range_t)); - range->value = (ngx_http_variable_value_t *) + sizeof(ngx_stream_geo_range_t)); + range->value = (ngx_stream_variable_value_t *) ((u_char *) range->value + (size_t) base); range++; } ngx_crc32_update(&crc32, (u_char *) range, sizeof(void *)); - range = (ngx_http_geo_range_t *) ((u_char *) range + sizeof(void *)); + range = (ngx_stream_geo_range_t *) ((u_char *) range + sizeof(void *)); } ngx_crc32_final(crc32); @@ -1538,16 +1466,16 @@ done: static void -ngx_http_geo_create_binary_base(ngx_http_geo_conf_ctx_t *ctx) +ngx_stream_geo_create_binary_base(ngx_stream_geo_conf_ctx_t *ctx) { - u_char *p; - uint32_t hash; - ngx_str_t s; - ngx_uint_t i; - ngx_file_mapping_t fm; - ngx_http_geo_range_t *r, *range, **ranges; - ngx_http_geo_header_t *header; - ngx_http_geo_variable_value_node_t *gvvn; + u_char *p; + uint32_t hash; + ngx_str_t s; + ngx_uint_t i; + ngx_file_mapping_t fm; + ngx_stream_geo_range_t *r, *range, **ranges; + ngx_stream_geo_header_t *header; + ngx_stream_geo_variable_value_node_t *gvvn; fm.name = ngx_pnalloc(ctx->temp_pool, ctx->include_name.len + 5); if (fm.name == NULL) { @@ -1566,17 +1494,17 @@ ngx_http_geo_create_binary_base(ngx_http return; } - p = ngx_cpymem(fm.addr, &ngx_http_geo_header, - sizeof(ngx_http_geo_header_t)); + p = ngx_cpymem(fm.addr, &ngx_stream_geo_header, + sizeof(ngx_stream_geo_header_t)); - p = ngx_http_geo_copy_values(fm.addr, p, ctx->rbtree.root, - ctx->rbtree.sentinel); + p = ngx_stream_geo_copy_values(fm.addr, p, ctx->rbtree.root, + ctx->rbtree.sentinel); - p += sizeof(ngx_http_variable_value_t); + p += sizeof(ngx_stream_variable_value_t); - ranges = (ngx_http_geo_range_t **) p; + ranges = (ngx_stream_geo_range_t **) p; - p += 0x10000 * sizeof(ngx_http_geo_range_t *); + p += 0x10000 * sizeof(ngx_stream_geo_range_t *); for (i = 0; i < 0x10000; i++) { r = ctx->high.low[i]; @@ -1584,17 +1512,17 @@ ngx_http_geo_create_binary_base(ngx_http continue; } - range = (ngx_http_geo_range_t *) p; - ranges[i] = (ngx_http_geo_range_t *) (p - (u_char *) fm.addr); + range = (ngx_stream_geo_range_t *) p; + ranges[i] = (ngx_stream_geo_range_t *) (p - (u_char *) fm.addr); do { s.len = r->value->len; s.data = r->value->data; hash = ngx_crc32_long(s.data, s.len); - gvvn = (ngx_http_geo_variable_value_node_t *) + gvvn = (ngx_stream_geo_variable_value_node_t *) ngx_str_rbtree_lookup(&ctx->rbtree, &s, hash); - range->value = (ngx_http_variable_value_t *) gvvn->offset; + range->value = (ngx_stream_variable_value_t *) gvvn->offset; range->start = r->start; range->end = r->end; range++; @@ -1608,37 +1536,37 @@ ngx_http_geo_create_binary_base(ngx_http header = fm.addr; header->crc32 = ngx_crc32_long((u_char *) fm.addr - + sizeof(ngx_http_geo_header_t), - fm.size - sizeof(ngx_http_geo_header_t)); + + sizeof(ngx_stream_geo_header_t), + fm.size - sizeof(ngx_stream_geo_header_t)); ngx_close_file_mapping(&fm); } static u_char * -ngx_http_geo_copy_values(u_char *base, u_char *p, ngx_rbtree_node_t *node, +ngx_stream_geo_copy_values(u_char *base, u_char *p, ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel) { - ngx_http_variable_value_t *vv; - ngx_http_geo_variable_value_node_t *gvvn; + ngx_stream_variable_value_t *vv; + ngx_stream_geo_variable_value_node_t *gvvn; if (node == sentinel) { return p; } - gvvn = (ngx_http_geo_variable_value_node_t *) node; + gvvn = (ngx_stream_geo_variable_value_node_t *) node; gvvn->offset = p - base; - vv = (ngx_http_variable_value_t *) p; + vv = (ngx_stream_variable_value_t *) p; *vv = *gvvn->value; - p += sizeof(ngx_http_variable_value_t); + p += sizeof(ngx_stream_variable_value_t); vv->data = (u_char *) (p - base); p = ngx_cpymem(p, gvvn->sn.str.data, gvvn->sn.str.len); p = ngx_align_ptr(p, sizeof(void *)); - p = ngx_http_geo_copy_values(base, p, node->left, sentinel); + p = ngx_stream_geo_copy_values(base, p, node->left, sentinel); - return ngx_http_geo_copy_values(base, p, node->right, sentinel); + return ngx_stream_geo_copy_values(base, p, node->right, sentinel); }