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)