mirror of
https://github.com/nginx/nginx.git
synced 2024-12-31 19:27:43 -06:00
fix duplicate rbtree keys case
This commit is contained in:
parent
6043c80639
commit
805706a20f
@ -104,6 +104,7 @@ ngx_http_limit_zone_handler(ngx_http_request_t *r)
|
|||||||
{
|
{
|
||||||
size_t len, n;
|
size_t len, n;
|
||||||
uint32_t hash;
|
uint32_t hash;
|
||||||
|
ngx_int_t rc;
|
||||||
ngx_slab_pool_t *shpool;
|
ngx_slab_pool_t *shpool;
|
||||||
ngx_rbtree_node_t *node, *sentinel;
|
ngx_rbtree_node_t *node, *sentinel;
|
||||||
ngx_pool_cleanup_t *cln;
|
ngx_pool_cleanup_t *cln;
|
||||||
@ -178,9 +179,9 @@ ngx_http_limit_zone_handler(ngx_http_request_t *r)
|
|||||||
do {
|
do {
|
||||||
lz = (ngx_http_limit_zone_node_t *) &node->color;
|
lz = (ngx_http_limit_zone_node_t *) &node->color;
|
||||||
|
|
||||||
if (len == (size_t) lz->len
|
rc = ngx_strn2cmp(lz->data, vv->data, (size_t) lz->len, len);
|
||||||
&& ngx_strncmp(lz->data, vv->data, len) == 0)
|
|
||||||
{
|
if (rc == 0) {
|
||||||
if ((ngx_uint_t) lz->conn < lzcf->conn) {
|
if ((ngx_uint_t) lz->conn < lzcf->conn) {
|
||||||
lz->conn++;
|
lz->conn++;
|
||||||
goto done;
|
goto done;
|
||||||
@ -191,7 +192,7 @@ ngx_http_limit_zone_handler(ngx_http_request_t *r)
|
|||||||
return NGX_HTTP_SERVICE_UNAVAILABLE;
|
return NGX_HTTP_SERVICE_UNAVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
node = node->right;
|
node = (rc < 0) ? node->left : node->right;
|
||||||
|
|
||||||
} while (node != sentinel && hash == node->key);
|
} while (node != sentinel && hash == node->key);
|
||||||
|
|
||||||
@ -234,6 +235,65 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
ngx_http_limit_zone_rbtree_insert_value(ngx_rbtree_node_t *temp,
|
||||||
|
ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
|
||||||
|
{
|
||||||
|
ngx_http_limit_zone_node_t *lzn, *lznt;
|
||||||
|
|
||||||
|
for ( ;; ) {
|
||||||
|
|
||||||
|
if (node->key < temp->key) {
|
||||||
|
|
||||||
|
if (temp->left == sentinel) {
|
||||||
|
temp->left = node;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp = temp->left;
|
||||||
|
|
||||||
|
} else if (node->key > temp->key) {
|
||||||
|
|
||||||
|
if (temp->right == sentinel) {
|
||||||
|
temp->right = node;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp = temp->right;
|
||||||
|
|
||||||
|
} else { /* node->key == temp->key */
|
||||||
|
|
||||||
|
lzn = (ngx_http_limit_zone_node_t *) &node->color;
|
||||||
|
lznt = (ngx_http_limit_zone_node_t *) &temp->color;
|
||||||
|
|
||||||
|
if (ngx_strn2cmp(lzn->data, lznt->data, lzn->len, lznt->len) < 0) {
|
||||||
|
|
||||||
|
if (temp->left == sentinel) {
|
||||||
|
temp->left = node;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp = temp->left;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (temp->right == sentinel) {
|
||||||
|
temp->right = node;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp = temp->right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node->parent = temp;
|
||||||
|
node->left = sentinel;
|
||||||
|
node->right = sentinel;
|
||||||
|
ngx_rbt_red(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ngx_http_limit_zone_cleanup(void *data)
|
ngx_http_limit_zone_cleanup(void *data)
|
||||||
{
|
{
|
||||||
@ -306,7 +366,7 @@ ngx_http_limit_zone_init_zone(ngx_shm_zone_t *shm_zone, void *data)
|
|||||||
|
|
||||||
ctx->rbtree->root = sentinel;
|
ctx->rbtree->root = sentinel;
|
||||||
ctx->rbtree->sentinel = sentinel;
|
ctx->rbtree->sentinel = sentinel;
|
||||||
ctx->rbtree->insert = ngx_rbtree_insert_value;
|
ctx->rbtree->insert = ngx_http_limit_zone_rbtree_insert_value;
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user