mirror of
https://github.com/nginx/nginx.git
synced 2025-01-05 23:07:49 +08:00
Stream: got rid of pseudo variables.
Stream limit_conn, upstream_hash and proxy modules now use complex values.
This commit is contained in:
parent
05db6ddfa1
commit
cb635b7879
@ -11,33 +11,34 @@
|
|||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u_char color;
|
u_char color;
|
||||||
u_char len;
|
u_char len;
|
||||||
u_short conn;
|
u_short conn;
|
||||||
u_char data[1];
|
u_char data[1];
|
||||||
} ngx_stream_limit_conn_node_t;
|
} ngx_stream_limit_conn_node_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_shm_zone_t *shm_zone;
|
ngx_shm_zone_t *shm_zone;
|
||||||
ngx_rbtree_node_t *node;
|
ngx_rbtree_node_t *node;
|
||||||
} ngx_stream_limit_conn_cleanup_t;
|
} ngx_stream_limit_conn_cleanup_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_rbtree_t *rbtree;
|
ngx_rbtree_t *rbtree;
|
||||||
|
ngx_stream_complex_value_t key;
|
||||||
} ngx_stream_limit_conn_ctx_t;
|
} ngx_stream_limit_conn_ctx_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_shm_zone_t *shm_zone;
|
ngx_shm_zone_t *shm_zone;
|
||||||
ngx_uint_t conn;
|
ngx_uint_t conn;
|
||||||
} ngx_stream_limit_conn_limit_t;
|
} ngx_stream_limit_conn_limit_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_array_t limits;
|
ngx_array_t limits;
|
||||||
ngx_uint_t log_level;
|
ngx_uint_t log_level;
|
||||||
} ngx_stream_limit_conn_conf_t;
|
} ngx_stream_limit_conn_conf_t;
|
||||||
|
|
||||||
|
|
||||||
@ -130,48 +131,36 @@ ngx_stream_limit_conn_handler(ngx_stream_session_t *s)
|
|||||||
ngx_slab_pool_t *shpool;
|
ngx_slab_pool_t *shpool;
|
||||||
ngx_rbtree_node_t *node;
|
ngx_rbtree_node_t *node;
|
||||||
ngx_pool_cleanup_t *cln;
|
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_ctx_t *ctx;
|
||||||
ngx_stream_limit_conn_node_t *lc;
|
ngx_stream_limit_conn_node_t *lc;
|
||||||
ngx_stream_limit_conn_conf_t *lccf;
|
ngx_stream_limit_conn_conf_t *lccf;
|
||||||
ngx_stream_limit_conn_limit_t *limits;
|
ngx_stream_limit_conn_limit_t *limits;
|
||||||
ngx_stream_limit_conn_cleanup_t *lccln;
|
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);
|
lccf = ngx_stream_get_module_srv_conf(s, ngx_stream_limit_conn_module);
|
||||||
limits = lccf->limits.elts;
|
limits = lccf->limits.elts;
|
||||||
|
|
||||||
for (i = 0; i < lccf->limits.nelts; i++) {
|
for (i = 0; i < lccf->limits.nelts; i++) {
|
||||||
ctx = limits[i].shm_zone->data;
|
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;
|
shpool = (ngx_slab_pool_t *) limits[i].shm_zone->shm.addr;
|
||||||
|
|
||||||
ngx_shmtx_lock(&shpool->mutex);
|
ngx_shmtx_lock(&shpool->mutex);
|
||||||
@ -383,6 +372,19 @@ ngx_stream_limit_conn_init_zone(ngx_shm_zone_t *shm_zone, void *data)
|
|||||||
ctx = shm_zone->data;
|
ctx = shm_zone->data;
|
||||||
|
|
||||||
if (octx) {
|
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;
|
ctx->rbtree = octx->rbtree;
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
@ -466,12 +468,13 @@ ngx_stream_limit_conn_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||||||
static char *
|
static char *
|
||||||
ngx_stream_limit_conn_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
ngx_stream_limit_conn_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||||
{
|
{
|
||||||
u_char *p;
|
u_char *p;
|
||||||
ssize_t size;
|
ssize_t size;
|
||||||
ngx_str_t *value, name, s;
|
ngx_str_t *value, name, s;
|
||||||
ngx_uint_t i;
|
ngx_uint_t i;
|
||||||
ngx_shm_zone_t *shm_zone;
|
ngx_shm_zone_t *shm_zone;
|
||||||
ngx_stream_limit_conn_ctx_t *ctx;
|
ngx_stream_limit_conn_ctx_t *ctx;
|
||||||
|
ngx_stream_compile_complex_value_t ccv;
|
||||||
|
|
||||||
value = cf->args->elts;
|
value = cf->args->elts;
|
||||||
|
|
||||||
@ -480,6 +483,16 @@ ngx_stream_limit_conn_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
return NGX_CONF_ERROR;
|
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;
|
size = 0;
|
||||||
name.len = 0;
|
name.len = 0;
|
||||||
|
|
||||||
@ -538,17 +551,11 @@ ngx_stream_limit_conn_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (shm_zone->data) {
|
if (shm_zone->data) {
|
||||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
ctx = shm_zone->data;
|
||||||
"%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,
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
"unsupported key \"%V\", use "
|
"%V \"%V\" is already bound to key \"%V\"",
|
||||||
"$binary_remote_addr", &value[1]);
|
&cmd->name, &name, &ctx->key.value);
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,10 +12,10 @@
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_addr_t *addr;
|
ngx_addr_t *addr;
|
||||||
|
ngx_stream_complex_value_t *value;
|
||||||
#if (NGX_HAVE_TRANSPARENT_PROXY)
|
#if (NGX_HAVE_TRANSPARENT_PROXY)
|
||||||
unsigned transparent:1;
|
ngx_uint_t transparent; /* unsigned transparent:1; */
|
||||||
#endif
|
#endif
|
||||||
unsigned no_port:1;
|
|
||||||
} ngx_stream_upstream_local_t;
|
} 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_proxy_set_local(ngx_stream_session_t *s, ngx_stream_upstream_t *u,
|
||||||
ngx_stream_upstream_local_t *local)
|
ngx_stream_upstream_local_t *local)
|
||||||
{
|
{
|
||||||
ngx_addr_t *addr;
|
ngx_int_t rc;
|
||||||
ngx_connection_t *c;
|
ngx_str_t val;
|
||||||
|
ngx_addr_t *addr;
|
||||||
|
|
||||||
if (local == NULL) {
|
if (local == NULL) {
|
||||||
u->peer.local = NULL;
|
u->peer.local = NULL;
|
||||||
@ -460,36 +461,36 @@ ngx_stream_proxy_set_local(ngx_stream_session_t *s, ngx_stream_upstream_t *u,
|
|||||||
u->peer.transparent = local->transparent;
|
u->peer.transparent = local->transparent;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (local->addr) {
|
if (local->value == NULL) {
|
||||||
u->peer.local = local->addr;
|
u->peer.local = local->addr;
|
||||||
return NGX_OK;
|
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) {
|
if (addr == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr->socklen = c->socklen;
|
rc = ngx_parse_addr_port(s->connection->pool, addr, val.data, val.len);
|
||||||
|
if (rc == NGX_ERROR) {
|
||||||
if (local->no_port) {
|
return NGX_ERROR;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
u->peer.local = addr;
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
@ -1699,9 +1700,11 @@ ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
{
|
{
|
||||||
ngx_stream_proxy_srv_conf_t *pscf = conf;
|
ngx_stream_proxy_srv_conf_t *pscf = conf;
|
||||||
|
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
ngx_str_t *value;
|
ngx_str_t *value;
|
||||||
ngx_stream_upstream_local_t *local;
|
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) {
|
if (pscf->local != NGX_CONF_UNSET_PTR) {
|
||||||
return "is duplicate";
|
return "is duplicate";
|
||||||
@ -1714,6 +1717,16 @@ ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
return NGX_CONF_OK;
|
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));
|
local = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_local_t));
|
||||||
if (local == NULL) {
|
if (local == NULL) {
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
@ -1721,12 +1734,15 @@ ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
|
|
||||||
pscf->local = local;
|
pscf->local = local;
|
||||||
|
|
||||||
if (ngx_strcmp(value[1].data, "$remote_addr") == 0) {
|
if (cv.lengths) {
|
||||||
local->no_port = 1;
|
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
|
*local->value = cv;
|
||||||
&& ngx_strcmp(value[1].data, "[$remote_addr]:$remote_port") != 0)
|
|
||||||
{
|
} else {
|
||||||
local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
|
local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
|
||||||
if (local->addr == NULL) {
|
if (local->addr == NULL) {
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
|
@ -23,6 +23,7 @@ typedef struct {
|
|||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
ngx_stream_complex_value_t key;
|
||||||
ngx_stream_upstream_chash_points_t *points;
|
ngx_stream_upstream_chash_points_t *points;
|
||||||
} ngx_stream_upstream_hash_srv_conf_t;
|
} ngx_stream_upstream_hash_srv_conf_t;
|
||||||
|
|
||||||
@ -141,7 +142,9 @@ ngx_stream_upstream_init_hash_peer(ngx_stream_session_t *s,
|
|||||||
hcf = ngx_stream_conf_upstream_srv_conf(us,
|
hcf = ngx_stream_conf_upstream_srv_conf(us,
|
||||||
ngx_stream_upstream_hash_module);
|
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,
|
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
|
||||||
"upstream hash key:\"%V\"", &hp->key);
|
"upstream hash key:\"%V\"", &hp->key);
|
||||||
@ -616,15 +619,21 @@ ngx_stream_upstream_hash_create_conf(ngx_conf_t *cf)
|
|||||||
static char *
|
static char *
|
||||||
ngx_stream_upstream_hash(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
ngx_stream_upstream_hash(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||||
{
|
{
|
||||||
ngx_str_t *value;
|
ngx_stream_upstream_hash_srv_conf_t *hcf = conf;
|
||||||
ngx_stream_upstream_srv_conf_t *uscf;
|
|
||||||
|
ngx_str_t *value;
|
||||||
|
ngx_stream_upstream_srv_conf_t *uscf;
|
||||||
|
ngx_stream_compile_complex_value_t ccv;
|
||||||
|
|
||||||
value = cf->args->elts;
|
value = cf->args->elts;
|
||||||
|
|
||||||
if (ngx_strcmp(value[1].data, "$remote_addr")) {
|
ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
|
||||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
|
||||||
"unsupported hash key \"%V\", use $remote_addr",
|
ccv.cf = cf;
|
||||||
&value[1]);
|
ccv.value = &value[1];
|
||||||
|
ccv.complex_value = &hcf->key;
|
||||||
|
|
||||||
|
if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user