# HG changeset patch # User Vladimir Homutov # Date 1467193572 -10800 # Node ID d5b5866c06c49ed2ec3e84303a76065c415367b3 # Parent 73543af69f14bc2579ced2abee8c3ef93085be4f Stream: got rid of pseudo variables. Stream limit_conn, upstream_hash and proxy modules now use complex values. diff --git a/src/stream/ngx_stream_limit_conn_module.c b/src/stream/ngx_stream_limit_conn_module.c --- a/src/stream/ngx_stream_limit_conn_module.c +++ b/src/stream/ngx_stream_limit_conn_module.c @@ -11,33 +11,34 @@ typedef struct { - u_char color; - u_char len; - u_short conn; - u_char data[1]; + u_char color; + u_char len; + u_short conn; + u_char data[1]; } ngx_stream_limit_conn_node_t; typedef struct { - ngx_shm_zone_t *shm_zone; - ngx_rbtree_node_t *node; + ngx_shm_zone_t *shm_zone; + ngx_rbtree_node_t *node; } ngx_stream_limit_conn_cleanup_t; typedef struct { - ngx_rbtree_t *rbtree; + ngx_rbtree_t *rbtree; + ngx_stream_complex_value_t key; } ngx_stream_limit_conn_ctx_t; typedef struct { - ngx_shm_zone_t *shm_zone; - ngx_uint_t conn; + ngx_shm_zone_t *shm_zone; + ngx_uint_t conn; } ngx_stream_limit_conn_limit_t; typedef struct { - ngx_array_t limits; - ngx_uint_t log_level; + ngx_array_t limits; + ngx_uint_t log_level; } ngx_stream_limit_conn_conf_t; @@ -130,48 +131,36 @@ ngx_stream_limit_conn_handler(ngx_stream ngx_slab_pool_t *shpool; ngx_rbtree_node_t *node; ngx_pool_cleanup_t *cln; - struct sockaddr_in *sin; -#if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; -#endif ngx_stream_limit_conn_ctx_t *ctx; ngx_stream_limit_conn_node_t *lc; ngx_stream_limit_conn_conf_t *lccf; ngx_stream_limit_conn_limit_t *limits; ngx_stream_limit_conn_cleanup_t *lccln; - switch (s->connection->sockaddr->sa_family) { - - case AF_INET: - sin = (struct sockaddr_in *) s->connection->sockaddr; - - key.len = sizeof(in_addr_t); - key.data = (u_char *) &sin->sin_addr; - - break; - -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = (struct sockaddr_in6 *) s->connection->sockaddr; - - key.len = sizeof(struct in6_addr); - key.data = sin6->sin6_addr.s6_addr; - - break; -#endif - - default: - return NGX_DECLINED; - } - - hash = ngx_crc32_short(key.data, key.len); - lccf = ngx_stream_get_module_srv_conf(s, ngx_stream_limit_conn_module); limits = lccf->limits.elts; for (i = 0; i < lccf->limits.nelts; i++) { ctx = limits[i].shm_zone->data; + if (ngx_stream_complex_value(s, &ctx->key, &key) != NGX_OK) { + return NGX_ERROR; + } + + if (key.len == 0) { + continue; + } + + if (key.len > 255) { + ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, + "the value of the \"%V\" key " + "is more than 255 bytes: \"%V\"", + &ctx->key.value, &key); + continue; + } + + hash = ngx_crc32_short(key.data, key.len); + shpool = (ngx_slab_pool_t *) limits[i].shm_zone->shm.addr; ngx_shmtx_lock(&shpool->mutex); @@ -383,6 +372,19 @@ ngx_stream_limit_conn_init_zone(ngx_shm_ ctx = shm_zone->data; if (octx) { + if (ctx->key.value.len != octx->key.value.len + || ngx_strncmp(ctx->key.value.data, octx->key.value.data, + ctx->key.value.len) + != 0) + { + ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0, + "limit_conn_zone \"%V\" uses the \"%V\" key " + "while previously it used the \"%V\" key", + &shm_zone->shm.name, &ctx->key.value, + &octx->key.value); + return NGX_ERROR; + } + ctx->rbtree = octx->rbtree; return NGX_OK; @@ -466,12 +468,13 @@ ngx_stream_limit_conn_merge_conf(ngx_con static char * ngx_stream_limit_conn_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - u_char *p; - ssize_t size; - ngx_str_t *value, name, s; - ngx_uint_t i; - ngx_shm_zone_t *shm_zone; - ngx_stream_limit_conn_ctx_t *ctx; + u_char *p; + ssize_t size; + ngx_str_t *value, name, s; + ngx_uint_t i; + ngx_shm_zone_t *shm_zone; + ngx_stream_limit_conn_ctx_t *ctx; + ngx_stream_compile_complex_value_t ccv; value = cf->args->elts; @@ -480,6 +483,16 @@ ngx_stream_limit_conn_zone(ngx_conf_t *c return NGX_CONF_ERROR; } + ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t)); + + ccv.cf = cf; + ccv.value = &value[1]; + ccv.complex_value = &ctx->key; + + if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) { + return NGX_CONF_ERROR; + } + size = 0; name.len = 0; @@ -538,17 +551,11 @@ ngx_stream_limit_conn_zone(ngx_conf_t *c } if (shm_zone->data) { + ctx = shm_zone->data; + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "%V \"%V\" is already bound to key " - "\"$binary_remote_addr\"", - &cmd->name, &name); - return NGX_CONF_ERROR; - } - - if (ngx_strcmp(value[1].data, "$binary_remote_addr") != 0) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "unsupported key \"%V\", use " - "$binary_remote_addr", &value[1]); + "%V \"%V\" is already bound to key \"%V\"", + &cmd->name, &name, &ctx->key.value); return NGX_CONF_ERROR; } diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c +++ b/src/stream/ngx_stream_proxy_module.c @@ -12,10 +12,10 @@ typedef struct { ngx_addr_t *addr; + ngx_stream_complex_value_t *value; #if (NGX_HAVE_TRANSPARENT_PROXY) - unsigned transparent:1; + ngx_uint_t transparent; /* unsigned transparent:1; */ #endif - unsigned no_port:1; } ngx_stream_upstream_local_t; @@ -448,8 +448,9 @@ static ngx_int_t ngx_stream_proxy_set_local(ngx_stream_session_t *s, ngx_stream_upstream_t *u, ngx_stream_upstream_local_t *local) { - ngx_addr_t *addr; - ngx_connection_t *c; + ngx_int_t rc; + ngx_str_t val; + ngx_addr_t *addr; if (local == NULL) { u->peer.local = NULL; @@ -460,36 +461,36 @@ ngx_stream_proxy_set_local(ngx_stream_se u->peer.transparent = local->transparent; #endif - if (local->addr) { + if (local->value == NULL) { u->peer.local = local->addr; return NGX_OK; } - /* $remote_addr, $remote_addr:$remote_port, [$remote_addr]:$remote_port */ + if (ngx_stream_complex_value(s, local->value, &val) != NGX_OK) { + return NGX_ERROR; + } - c = s->connection; + if (val.len == 0) { + return NGX_OK; + } - addr = ngx_palloc(c->pool, sizeof(ngx_addr_t)); + addr = ngx_palloc(s->connection->pool, sizeof(ngx_addr_t)); if (addr == NULL) { return NGX_ERROR; } - addr->socklen = c->socklen; - - if (local->no_port) { - addr->sockaddr = ngx_palloc(c->pool, addr->socklen); - if (addr->sockaddr == NULL) { - return NGX_ERROR; - } - - ngx_memcpy(addr->sockaddr, c->sockaddr, c->socklen); - ngx_inet_set_port(addr->sockaddr, 0); - - } else { - addr->sockaddr = c->sockaddr; + rc = ngx_parse_addr_port(s->connection->pool, addr, val.data, val.len); + if (rc == NGX_ERROR) { + return NGX_ERROR; } - addr->name = c->addr_text; + if (rc != NGX_OK) { + ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, + "invalid local address \"%V\"", &val); + return NGX_OK; + } + + addr->name = val; u->peer.local = addr; return NGX_OK; @@ -1699,9 +1700,11 @@ ngx_stream_proxy_bind(ngx_conf_t *cf, ng { ngx_stream_proxy_srv_conf_t *pscf = conf; - ngx_int_t rc; - ngx_str_t *value; - ngx_stream_upstream_local_t *local; + ngx_int_t rc; + ngx_str_t *value; + ngx_stream_complex_value_t cv; + ngx_stream_upstream_local_t *local; + ngx_stream_compile_complex_value_t ccv; if (pscf->local != NGX_CONF_UNSET_PTR) { return "is duplicate"; @@ -1714,6 +1717,16 @@ ngx_stream_proxy_bind(ngx_conf_t *cf, ng return NGX_CONF_OK; } + ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t)); + + ccv.cf = cf; + ccv.value = &value[1]; + ccv.complex_value = &cv; + + if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) { + return NGX_CONF_ERROR; + } + local = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_local_t)); if (local == NULL) { return NGX_CONF_ERROR; @@ -1721,12 +1734,15 @@ ngx_stream_proxy_bind(ngx_conf_t *cf, ng pscf->local = local; - if (ngx_strcmp(value[1].data, "$remote_addr") == 0) { - local->no_port = 1; + if (cv.lengths) { + local->value = ngx_palloc(cf->pool, sizeof(ngx_stream_complex_value_t)); + if (local->value == NULL) { + return NGX_CONF_ERROR; + } - } else if (ngx_strcmp(value[1].data, "$remote_addr:$remote_port") != 0 - && ngx_strcmp(value[1].data, "[$remote_addr]:$remote_port") != 0) - { + *local->value = cv; + + } else { local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t)); if (local->addr == NULL) { return NGX_CONF_ERROR; diff --git a/src/stream/ngx_stream_upstream_hash_module.c b/src/stream/ngx_stream_upstream_hash_module.c --- a/src/stream/ngx_stream_upstream_hash_module.c +++ b/src/stream/ngx_stream_upstream_hash_module.c @@ -23,6 +23,7 @@ typedef struct { typedef struct { + ngx_stream_complex_value_t key; ngx_stream_upstream_chash_points_t *points; } ngx_stream_upstream_hash_srv_conf_t; @@ -141,7 +142,9 @@ ngx_stream_upstream_init_hash_peer(ngx_s hcf = ngx_stream_conf_upstream_srv_conf(us, ngx_stream_upstream_hash_module); - hp->key = s->connection->addr_text; + if (ngx_stream_complex_value(s, &hcf->key, &hp->key) != NGX_OK) { + return NGX_ERROR; + } ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, "upstream hash key:\"%V\"", &hp->key); @@ -616,15 +619,21 @@ ngx_stream_upstream_hash_create_conf(ngx static char * ngx_stream_upstream_hash(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - ngx_str_t *value; - ngx_stream_upstream_srv_conf_t *uscf; + ngx_stream_upstream_hash_srv_conf_t *hcf = conf; + + ngx_str_t *value; + ngx_stream_upstream_srv_conf_t *uscf; + ngx_stream_compile_complex_value_t ccv; value = cf->args->elts; - if (ngx_strcmp(value[1].data, "$remote_addr")) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "unsupported hash key \"%V\", use $remote_addr", - &value[1]); + ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t)); + + ccv.cf = cf; + ccv.value = &value[1]; + ccv.complex_value = &hcf->key; + + if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) { return NGX_CONF_ERROR; }