comparison src/stream/ngx_stream_limit_conn_module.c @ 6610:d5b5866c06c4

Stream: got rid of pseudo variables. Stream limit_conn, upstream_hash and proxy modules now use complex values.
author Vladimir Homutov <vl@nginx.com>
date Wed, 29 Jun 2016 12:46:12 +0300
parents 2f41d383c9c7
children 8ed51b02f655
comparison
equal deleted inserted replaced
6609:73543af69f14 6610:d5b5866c06c4
9 #include <ngx_core.h> 9 #include <ngx_core.h>
10 #include <ngx_stream.h> 10 #include <ngx_stream.h>
11 11
12 12
13 typedef struct { 13 typedef struct {
14 u_char color; 14 u_char color;
15 u_char len; 15 u_char len;
16 u_short conn; 16 u_short conn;
17 u_char data[1]; 17 u_char data[1];
18 } ngx_stream_limit_conn_node_t; 18 } ngx_stream_limit_conn_node_t;
19 19
20 20
21 typedef struct { 21 typedef struct {
22 ngx_shm_zone_t *shm_zone; 22 ngx_shm_zone_t *shm_zone;
23 ngx_rbtree_node_t *node; 23 ngx_rbtree_node_t *node;
24 } ngx_stream_limit_conn_cleanup_t; 24 } ngx_stream_limit_conn_cleanup_t;
25 25
26 26
27 typedef struct { 27 typedef struct {
28 ngx_rbtree_t *rbtree; 28 ngx_rbtree_t *rbtree;
29 ngx_stream_complex_value_t key;
29 } ngx_stream_limit_conn_ctx_t; 30 } ngx_stream_limit_conn_ctx_t;
30 31
31 32
32 typedef struct { 33 typedef struct {
33 ngx_shm_zone_t *shm_zone; 34 ngx_shm_zone_t *shm_zone;
34 ngx_uint_t conn; 35 ngx_uint_t conn;
35 } ngx_stream_limit_conn_limit_t; 36 } ngx_stream_limit_conn_limit_t;
36 37
37 38
38 typedef struct { 39 typedef struct {
39 ngx_array_t limits; 40 ngx_array_t limits;
40 ngx_uint_t log_level; 41 ngx_uint_t log_level;
41 } ngx_stream_limit_conn_conf_t; 42 } ngx_stream_limit_conn_conf_t;
42 43
43 44
44 static ngx_rbtree_node_t *ngx_stream_limit_conn_lookup(ngx_rbtree_t *rbtree, 45 static ngx_rbtree_node_t *ngx_stream_limit_conn_lookup(ngx_rbtree_t *rbtree,
45 ngx_str_t *key, uint32_t hash); 46 ngx_str_t *key, uint32_t hash);
128 ngx_str_t key; 129 ngx_str_t key;
129 ngx_uint_t i; 130 ngx_uint_t i;
130 ngx_slab_pool_t *shpool; 131 ngx_slab_pool_t *shpool;
131 ngx_rbtree_node_t *node; 132 ngx_rbtree_node_t *node;
132 ngx_pool_cleanup_t *cln; 133 ngx_pool_cleanup_t *cln;
133 struct sockaddr_in *sin;
134 #if (NGX_HAVE_INET6)
135 struct sockaddr_in6 *sin6;
136 #endif
137 ngx_stream_limit_conn_ctx_t *ctx; 134 ngx_stream_limit_conn_ctx_t *ctx;
138 ngx_stream_limit_conn_node_t *lc; 135 ngx_stream_limit_conn_node_t *lc;
139 ngx_stream_limit_conn_conf_t *lccf; 136 ngx_stream_limit_conn_conf_t *lccf;
140 ngx_stream_limit_conn_limit_t *limits; 137 ngx_stream_limit_conn_limit_t *limits;
141 ngx_stream_limit_conn_cleanup_t *lccln; 138 ngx_stream_limit_conn_cleanup_t *lccln;
142 139
143 switch (s->connection->sockaddr->sa_family) {
144
145 case AF_INET:
146 sin = (struct sockaddr_in *) s->connection->sockaddr;
147
148 key.len = sizeof(in_addr_t);
149 key.data = (u_char *) &sin->sin_addr;
150
151 break;
152
153 #if (NGX_HAVE_INET6)
154 case AF_INET6:
155 sin6 = (struct sockaddr_in6 *) s->connection->sockaddr;
156
157 key.len = sizeof(struct in6_addr);
158 key.data = sin6->sin6_addr.s6_addr;
159
160 break;
161 #endif
162
163 default:
164 return NGX_DECLINED;
165 }
166
167 hash = ngx_crc32_short(key.data, key.len);
168
169 lccf = ngx_stream_get_module_srv_conf(s, ngx_stream_limit_conn_module); 140 lccf = ngx_stream_get_module_srv_conf(s, ngx_stream_limit_conn_module);
170 limits = lccf->limits.elts; 141 limits = lccf->limits.elts;
171 142
172 for (i = 0; i < lccf->limits.nelts; i++) { 143 for (i = 0; i < lccf->limits.nelts; i++) {
173 ctx = limits[i].shm_zone->data; 144 ctx = limits[i].shm_zone->data;
145
146 if (ngx_stream_complex_value(s, &ctx->key, &key) != NGX_OK) {
147 return NGX_ERROR;
148 }
149
150 if (key.len == 0) {
151 continue;
152 }
153
154 if (key.len > 255) {
155 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
156 "the value of the \"%V\" key "
157 "is more than 255 bytes: \"%V\"",
158 &ctx->key.value, &key);
159 continue;
160 }
161
162 hash = ngx_crc32_short(key.data, key.len);
174 163
175 shpool = (ngx_slab_pool_t *) limits[i].shm_zone->shm.addr; 164 shpool = (ngx_slab_pool_t *) limits[i].shm_zone->shm.addr;
176 165
177 ngx_shmtx_lock(&shpool->mutex); 166 ngx_shmtx_lock(&shpool->mutex);
178 167
381 ngx_stream_limit_conn_ctx_t *ctx; 370 ngx_stream_limit_conn_ctx_t *ctx;
382 371
383 ctx = shm_zone->data; 372 ctx = shm_zone->data;
384 373
385 if (octx) { 374 if (octx) {
375 if (ctx->key.value.len != octx->key.value.len
376 || ngx_strncmp(ctx->key.value.data, octx->key.value.data,
377 ctx->key.value.len)
378 != 0)
379 {
380 ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0,
381 "limit_conn_zone \"%V\" uses the \"%V\" key "
382 "while previously it used the \"%V\" key",
383 &shm_zone->shm.name, &ctx->key.value,
384 &octx->key.value);
385 return NGX_ERROR;
386 }
387
386 ctx->rbtree = octx->rbtree; 388 ctx->rbtree = octx->rbtree;
387 389
388 return NGX_OK; 390 return NGX_OK;
389 } 391 }
390 392
464 466
465 467
466 static char * 468 static char *
467 ngx_stream_limit_conn_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 469 ngx_stream_limit_conn_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
468 { 470 {
469 u_char *p; 471 u_char *p;
470 ssize_t size; 472 ssize_t size;
471 ngx_str_t *value, name, s; 473 ngx_str_t *value, name, s;
472 ngx_uint_t i; 474 ngx_uint_t i;
473 ngx_shm_zone_t *shm_zone; 475 ngx_shm_zone_t *shm_zone;
474 ngx_stream_limit_conn_ctx_t *ctx; 476 ngx_stream_limit_conn_ctx_t *ctx;
477 ngx_stream_compile_complex_value_t ccv;
475 478
476 value = cf->args->elts; 479 value = cf->args->elts;
477 480
478 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_stream_limit_conn_ctx_t)); 481 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_stream_limit_conn_ctx_t));
479 if (ctx == NULL) { 482 if (ctx == NULL) {
483 return NGX_CONF_ERROR;
484 }
485
486 ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
487
488 ccv.cf = cf;
489 ccv.value = &value[1];
490 ccv.complex_value = &ctx->key;
491
492 if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
480 return NGX_CONF_ERROR; 493 return NGX_CONF_ERROR;
481 } 494 }
482 495
483 size = 0; 496 size = 0;
484 name.len = 0; 497 name.len = 0;
536 if (shm_zone == NULL) { 549 if (shm_zone == NULL) {
537 return NGX_CONF_ERROR; 550 return NGX_CONF_ERROR;
538 } 551 }
539 552
540 if (shm_zone->data) { 553 if (shm_zone->data) {
554 ctx = shm_zone->data;
555
541 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 556 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
542 "%V \"%V\" is already bound to key " 557 "%V \"%V\" is already bound to key \"%V\"",
543 "\"$binary_remote_addr\"", 558 &cmd->name, &name, &ctx->key.value);
544 &cmd->name, &name);
545 return NGX_CONF_ERROR;
546 }
547
548 if (ngx_strcmp(value[1].data, "$binary_remote_addr") != 0) {
549 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
550 "unsupported key \"%V\", use "
551 "$binary_remote_addr", &value[1]);
552 return NGX_CONF_ERROR; 559 return NGX_CONF_ERROR;
553 } 560 }
554 561
555 shm_zone->init = ngx_stream_limit_conn_init_zone; 562 shm_zone->init = ngx_stream_limit_conn_init_zone;
556 shm_zone->data = ctx; 563 shm_zone->data = ctx;