Mercurial > hg > nginx
comparison src/http/modules/ngx_http_limit_req_module.c @ 4497:95ab6658654a
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.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 27 Feb 2012 22:15:39 +0000 |
parents | aacd7356c197 |
children | 778ef9c3fd2d |
comparison
equal
deleted
inserted
replaced
4496:be6c250b827b | 4497:95ab6658654a |
---|---|
383 continue; | 383 continue; |
384 } | 384 } |
385 | 385 |
386 /* hash == node->key */ | 386 /* hash == node->key */ |
387 | 387 |
388 do { | 388 lr = (ngx_http_limit_req_node_t *) &node->color; |
389 lr = (ngx_http_limit_req_node_t *) &node->color; | 389 |
390 | 390 rc = ngx_memn2cmp(data, lr->data, len, (size_t) lr->len); |
391 rc = ngx_memn2cmp(data, lr->data, len, (size_t) lr->len); | 391 |
392 | 392 if (rc == 0) { |
393 if (rc == 0) { | 393 ngx_queue_remove(&lr->queue); |
394 ngx_queue_remove(&lr->queue); | 394 ngx_queue_insert_head(&ctx->sh->queue, &lr->queue); |
395 ngx_queue_insert_head(&ctx->sh->queue, &lr->queue); | 395 |
396 | 396 ms = (ngx_msec_int_t) (now - lr->last); |
397 ms = (ngx_msec_int_t) (now - lr->last); | 397 |
398 | 398 excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000; |
399 excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000; | 399 |
400 | 400 if (excess < 0) { |
401 if (excess < 0) { | 401 excess = 0; |
402 excess = 0; | 402 } |
403 } | 403 |
404 | 404 *ep = excess; |
405 *ep = excess; | 405 |
406 | 406 if ((ngx_uint_t) excess > limit->burst) { |
407 if ((ngx_uint_t) excess > limit->burst) { | 407 return NGX_BUSY; |
408 return NGX_BUSY; | 408 } |
409 } | 409 |
410 | 410 if (account) { |
411 if (account) { | 411 lr->excess = excess; |
412 lr->excess = excess; | 412 lr->last = now; |
413 lr->last = now; | 413 return NGX_OK; |
414 return NGX_OK; | 414 } |
415 } | 415 |
416 | 416 lr->count++; |
417 lr->count++; | 417 |
418 | 418 ctx->node = lr; |
419 ctx->node = lr; | 419 |
420 | 420 return NGX_AGAIN; |
421 return NGX_AGAIN; | 421 } |
422 } | 422 |
423 | 423 node = (rc < 0) ? node->left : node->right; |
424 node = (rc < 0) ? node->left : node->right; | |
425 | |
426 } while (node != sentinel && hash == node->key); | |
427 | |
428 break; | |
429 } | 424 } |
430 | 425 |
431 *ep = 0; | 426 *ep = 0; |
432 | 427 |
433 size = offsetof(ngx_rbtree_node_t, color) | 428 size = offsetof(ngx_rbtree_node_t, color) |