Klaus Demo nginx / 7ca6c1f
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. Maxim Dounin 10 years ago
6 changed file(s) with 122 addition(s) and 157 deletion(s). Raw diff Collapse all Expand all
11411141
11421142 /* hash == node->key */
11431143
1144 do {
1145 file = (ngx_cached_open_file_t *) node;
1146
1147 rc = ngx_strcmp(name->data, file->name);
1148
1149 if (rc == 0) {
1150 return file;
1151 }
1152
1153 node = (rc < 0) ? node->left : node->right;
1154
1155 } while (node != sentinel && hash == node->key);
1156
1157 break;
1144 file = (ngx_cached_open_file_t *) node;
1145
1146 rc = ngx_strcmp(name->data, file->name);
1147
1148 if (rc == 0) {
1149 return file;
1150 }
1151
1152 node = (rc < 0) ? node->left : node->right;
11581153 }
11591154
11601155 return NULL;
16881688
16891689 /* hash == node->key */
16901690
1691 do {
1692 rn = (ngx_resolver_node_t *) node;
1693
1694 rc = ngx_memn2cmp(name->data, rn->name, name->len, rn->nlen);
1695
1696 if (rc == 0) {
1697 return rn;
1698 }
1699
1700 node = (rc < 0) ? node->left : node->right;
1701
1702 } while (node != sentinel && hash == node->key);
1703
1704 break;
1691 rn = (ngx_resolver_node_t *) node;
1692
1693 rc = ngx_memn2cmp(name->data, rn->name, name->len, rn->nlen);
1694
1695 if (rc == 0) {
1696 return rn;
1697 }
1698
1699 node = (rc < 0) ? node->left : node->right;
17051700 }
17061701
17071702 /* not found */
18001800
18011801 /* hash == node->key */
18021802
1803 do {
1804 sess_id = (ngx_ssl_sess_id_t *) node;
1805
1806 rc = ngx_memn2cmp(id, sess_id->id,
1807 (size_t) len, (size_t) node->data);
1808 if (rc == 0) {
1809
1810 if (sess_id->expire > ngx_time()) {
1811 ngx_memcpy(buf, sess_id->session, sess_id->len);
1812
1813 ngx_shmtx_unlock(&shpool->mutex);
1814
1815 p = buf;
1816 sess = d2i_SSL_SESSION(NULL, &p, sess_id->len);
1817
1818 return sess;
1819 }
1820
1821 ngx_queue_remove(&sess_id->queue);
1822
1823 ngx_rbtree_delete(&cache->session_rbtree, node);
1824
1825 ngx_slab_free_locked(shpool, sess_id->session);
1803 sess_id = (ngx_ssl_sess_id_t *) node;
1804
1805 rc = ngx_memn2cmp(id, sess_id->id, (size_t) len, (size_t) node->data);
1806
1807 if (rc == 0) {
1808
1809 if (sess_id->expire > ngx_time()) {
1810 ngx_memcpy(buf, sess_id->session, sess_id->len);
1811
1812 ngx_shmtx_unlock(&shpool->mutex);
1813
1814 p = buf;
1815 sess = d2i_SSL_SESSION(NULL, &p, sess_id->len);
1816
1817 return sess;
1818 }
1819
1820 ngx_queue_remove(&sess_id->queue);
1821
1822 ngx_rbtree_delete(&cache->session_rbtree, node);
1823
1824 ngx_slab_free_locked(shpool, sess_id->session);
18261825 #if (NGX_PTR_SIZE == 4)
1827 ngx_slab_free_locked(shpool, sess_id->id);
1826 ngx_slab_free_locked(shpool, sess_id->id);
18281827 #endif
1829 ngx_slab_free_locked(shpool, sess_id);
1830
1831 sess = NULL;
1832
1833 goto done;
1834 }
1835
1836 node = (rc < 0) ? node->left : node->right;
1837
1838 } while (node != sentinel && hash == node->key);
1839
1840 break;
1828 ngx_slab_free_locked(shpool, sess_id);
1829
1830 sess = NULL;
1831
1832 goto done;
1833 }
1834
1835 node = (rc < 0) ? node->left : node->right;
18411836 }
18421837
18431838 done:
19071902
19081903 /* hash == node->key */
19091904
1910 do {
1911 sess_id = (ngx_ssl_sess_id_t *) node;
1912
1913 rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data);
1914
1915 if (rc == 0) {
1916
1917 ngx_queue_remove(&sess_id->queue);
1918
1919 ngx_rbtree_delete(&cache->session_rbtree, node);
1920
1921 ngx_slab_free_locked(shpool, sess_id->session);
1905 sess_id = (ngx_ssl_sess_id_t *) node;
1906
1907 rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data);
1908
1909 if (rc == 0) {
1910
1911 ngx_queue_remove(&sess_id->queue);
1912
1913 ngx_rbtree_delete(&cache->session_rbtree, node);
1914
1915 ngx_slab_free_locked(shpool, sess_id->session);
19221916 #if (NGX_PTR_SIZE == 4)
1923 ngx_slab_free_locked(shpool, sess_id->id);
1917 ngx_slab_free_locked(shpool, sess_id->id);
19241918 #endif
1925 ngx_slab_free_locked(shpool, sess_id);
1926
1927 goto done;
1928 }
1929
1930 node = (rc < 0) ? node->left : node->right;
1931
1932 } while (node != sentinel && hash == node->key);
1933
1934 break;
1919 ngx_slab_free_locked(shpool, sess_id);
1920
1921 goto done;
1922 }
1923
1924 node = (rc < 0) ? node->left : node->right;
19351925 }
19361926
19371927 done:
324324
325325 /* hash == node->key */
326326
327 do {
328 lcn = (ngx_http_limit_conn_node_t *) &node->color;
329
330 rc = ngx_memn2cmp(vv->data, lcn->data,
331 (size_t) vv->len, (size_t) lcn->len);
332 if (rc == 0) {
333 return node;
334 }
335
336 node = (rc < 0) ? node->left : node->right;
337
338 } while (node != sentinel && hash == node->key);
339
340 break;
327 lcn = (ngx_http_limit_conn_node_t *) &node->color;
328
329 rc = ngx_memn2cmp(vv->data, lcn->data,
330 (size_t) vv->len, (size_t) lcn->len);
331 if (rc == 0) {
332 return node;
333 }
334
335 node = (rc < 0) ? node->left : node->right;
341336 }
342337
343338 return NULL;
384384
385385 /* hash == node->key */
386386
387 do {
388 lr = (ngx_http_limit_req_node_t *) &node->color;
389
390 rc = ngx_memn2cmp(data, lr->data, len, (size_t) lr->len);
391
392 if (rc == 0) {
393 ngx_queue_remove(&lr->queue);
394 ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
395
396 ms = (ngx_msec_int_t) (now - lr->last);
397
398 excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000;
399
400 if (excess < 0) {
401 excess = 0;
402 }
403
404 *ep = excess;
405
406 if ((ngx_uint_t) excess > limit->burst) {
407 return NGX_BUSY;
408 }
409
410 if (account) {
411 lr->excess = excess;
412 lr->last = now;
413 return NGX_OK;
414 }
415
416 lr->count++;
417
418 ctx->node = lr;
419
420 return NGX_AGAIN;
421 }
422
423 node = (rc < 0) ? node->left : node->right;
424
425 } while (node != sentinel && hash == node->key);
426
427 break;
387 lr = (ngx_http_limit_req_node_t *) &node->color;
388
389 rc = ngx_memn2cmp(data, lr->data, len, (size_t) lr->len);
390
391 if (rc == 0) {
392 ngx_queue_remove(&lr->queue);
393 ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
394
395 ms = (ngx_msec_int_t) (now - lr->last);
396
397 excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000;
398
399 if (excess < 0) {
400 excess = 0;
401 }
402
403 *ep = excess;
404
405 if ((ngx_uint_t) excess > limit->burst) {
406 return NGX_BUSY;
407 }
408
409 if (account) {
410 lr->excess = excess;
411 lr->last = now;
412 return NGX_OK;
413 }
414
415 lr->count++;
416
417 ctx->node = lr;
418
419 return NGX_AGAIN;
420 }
421
422 node = (rc < 0) ? node->left : node->right;
428423 }
429424
430425 *ep = 0;
798798
799799 /* node_key == node->key */
800800
801 do {
802 fcn = (ngx_http_file_cache_node_t *) node;
803
804 rc = ngx_memcmp(&key[sizeof(ngx_rbtree_key_t)], fcn->key,
805 NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t));
806
807 if (rc == 0) {
808 return fcn;
809 }
810
811 node = (rc < 0) ? node->left : node->right;
812
813 } while (node != sentinel && node_key == node->key);
814
815 break;
801 fcn = (ngx_http_file_cache_node_t *) node;
802
803 rc = ngx_memcmp(&key[sizeof(ngx_rbtree_key_t)], fcn->key,
804 NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t));
805
806 if (rc == 0) {
807 return fcn;
808 }
809
810 node = (rc < 0) ? node->left : node->right;
816811 }
817812
818813 /* not found */