aboutsummaryrefslogtreecommitdiff
path: root/src/http/modules/ngx_http_limit_req_module.c
diff options
context:
space:
mode:
authorMaxim Dounin <mdounin@mdounin.ru>2012-02-27 22:15:39 +0000
committerMaxim Dounin <mdounin@mdounin.ru>2012-02-27 22:15:39 +0000
commit7ca6c1ff782afbb83b9f17d6552566c823247e29 (patch)
tree9f357793d471ec5655beb15e02e2b72f2f5e7c5e /src/http/modules/ngx_http_limit_req_module.c
parent53d9677de451bae3d3da5c1ecbe6fa7b34fa5313 (diff)
downloadnginx-7ca6c1ff782afbb83b9f17d6552566c823247e29.tar.gz
nginx-7ca6c1ff782afbb83b9f17d6552566c823247e29.zip
Fix of rbtree lookup on hash collisions.
Previous code incorrectly assumed that nodes with identical keys are linked together. This might not be true after tree rebalance. Patch by Lanshun Zhou.
Diffstat (limited to 'src/http/modules/ngx_http_limit_req_module.c')
-rw-r--r--src/http/modules/ngx_http_limit_req_module.c53
1 files changed, 24 insertions, 29 deletions
diff --git a/src/http/modules/ngx_http_limit_req_module.c b/src/http/modules/ngx_http_limit_req_module.c
index e4d90a98f..f1698a394 100644
--- a/src/http/modules/ngx_http_limit_req_module.c
+++ b/src/http/modules/ngx_http_limit_req_module.c
@@ -385,47 +385,42 @@ ngx_http_limit_req_lookup(ngx_http_limit_req_limit_t *limit, ngx_uint_t hash,
/* hash == node->key */
- do {
- lr = (ngx_http_limit_req_node_t *) &node->color;
+ lr = (ngx_http_limit_req_node_t *) &node->color;
- rc = ngx_memn2cmp(data, lr->data, len, (size_t) lr->len);
+ rc = ngx_memn2cmp(data, lr->data, len, (size_t) lr->len);
- if (rc == 0) {
- ngx_queue_remove(&lr->queue);
- ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
+ if (rc == 0) {
+ ngx_queue_remove(&lr->queue);
+ ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
- ms = (ngx_msec_int_t) (now - lr->last);
-
- excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000;
-
- if (excess < 0) {
- excess = 0;
- }
-
- *ep = excess;
+ ms = (ngx_msec_int_t) (now - lr->last);
- if ((ngx_uint_t) excess > limit->burst) {
- return NGX_BUSY;
- }
+ excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000;
- if (account) {
- lr->excess = excess;
- lr->last = now;
- return NGX_OK;
- }
+ if (excess < 0) {
+ excess = 0;
+ }
- lr->count++;
+ *ep = excess;
- ctx->node = lr;
+ if ((ngx_uint_t) excess > limit->burst) {
+ return NGX_BUSY;
+ }
- return NGX_AGAIN;
+ if (account) {
+ lr->excess = excess;
+ lr->last = now;
+ return NGX_OK;
}
- node = (rc < 0) ? node->left : node->right;
+ lr->count++;
- } while (node != sentinel && hash == node->key);
+ ctx->node = lr;
+
+ return NGX_AGAIN;
+ }
- break;
+ node = (rc < 0) ? node->left : node->right;
}
*ep = 0;