comparison src/event/ngx_event_openssl.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 e8c61e79364e
children 778ef9c3fd2d
comparison
equal deleted inserted replaced
4496:be6c250b827b 4497:95ab6658654a
1799 continue; 1799 continue;
1800 } 1800 }
1801 1801
1802 /* hash == node->key */ 1802 /* hash == node->key */
1803 1803
1804 do { 1804 sess_id = (ngx_ssl_sess_id_t *) node;
1805 sess_id = (ngx_ssl_sess_id_t *) node; 1805
1806 1806 rc = ngx_memn2cmp(id, sess_id->id, (size_t) len, (size_t) node->data);
1807 rc = ngx_memn2cmp(id, sess_id->id, 1807
1808 (size_t) len, (size_t) node->data); 1808 if (rc == 0) {
1809 if (rc == 0) { 1809
1810 1810 if (sess_id->expire > ngx_time()) {
1811 if (sess_id->expire > ngx_time()) { 1811 ngx_memcpy(buf, sess_id->session, sess_id->len);
1812 ngx_memcpy(buf, sess_id->session, sess_id->len); 1812
1813 1813 ngx_shmtx_unlock(&shpool->mutex);
1814 ngx_shmtx_unlock(&shpool->mutex); 1814
1815 1815 p = buf;
1816 p = buf; 1816 sess = d2i_SSL_SESSION(NULL, &p, sess_id->len);
1817 sess = d2i_SSL_SESSION(NULL, &p, sess_id->len); 1817
1818 1818 return sess;
1819 return sess; 1819 }
1820 } 1820
1821 1821 ngx_queue_remove(&sess_id->queue);
1822 ngx_queue_remove(&sess_id->queue); 1822
1823 1823 ngx_rbtree_delete(&cache->session_rbtree, node);
1824 ngx_rbtree_delete(&cache->session_rbtree, node); 1824
1825 1825 ngx_slab_free_locked(shpool, sess_id->session);
1826 ngx_slab_free_locked(shpool, sess_id->session);
1827 #if (NGX_PTR_SIZE == 4) 1826 #if (NGX_PTR_SIZE == 4)
1828 ngx_slab_free_locked(shpool, sess_id->id); 1827 ngx_slab_free_locked(shpool, sess_id->id);
1829 #endif 1828 #endif
1830 ngx_slab_free_locked(shpool, sess_id); 1829 ngx_slab_free_locked(shpool, sess_id);
1831 1830
1832 sess = NULL; 1831 sess = NULL;
1833 1832
1834 goto done; 1833 goto done;
1835 } 1834 }
1836 1835
1837 node = (rc < 0) ? node->left : node->right; 1836 node = (rc < 0) ? node->left : node->right;
1838
1839 } while (node != sentinel && hash == node->key);
1840
1841 break;
1842 } 1837 }
1843 1838
1844 done: 1839 done:
1845 1840
1846 ngx_shmtx_unlock(&shpool->mutex); 1841 ngx_shmtx_unlock(&shpool->mutex);
1906 continue; 1901 continue;
1907 } 1902 }
1908 1903
1909 /* hash == node->key */ 1904 /* hash == node->key */
1910 1905
1911 do { 1906 sess_id = (ngx_ssl_sess_id_t *) node;
1912 sess_id = (ngx_ssl_sess_id_t *) node; 1907
1913 1908 rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data);
1914 rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data); 1909
1915 1910 if (rc == 0) {
1916 if (rc == 0) { 1911
1917 1912 ngx_queue_remove(&sess_id->queue);
1918 ngx_queue_remove(&sess_id->queue); 1913
1919 1914 ngx_rbtree_delete(&cache->session_rbtree, node);
1920 ngx_rbtree_delete(&cache->session_rbtree, node); 1915
1921 1916 ngx_slab_free_locked(shpool, sess_id->session);
1922 ngx_slab_free_locked(shpool, sess_id->session);
1923 #if (NGX_PTR_SIZE == 4) 1917 #if (NGX_PTR_SIZE == 4)
1924 ngx_slab_free_locked(shpool, sess_id->id); 1918 ngx_slab_free_locked(shpool, sess_id->id);
1925 #endif 1919 #endif
1926 ngx_slab_free_locked(shpool, sess_id); 1920 ngx_slab_free_locked(shpool, sess_id);
1927 1921
1928 goto done; 1922 goto done;
1929 } 1923 }
1930 1924
1931 node = (rc < 0) ? node->left : node->right; 1925 node = (rc < 0) ? node->left : node->right;
1932
1933 } while (node != sentinel && hash == node->key);
1934
1935 break;
1936 } 1926 }
1937 1927
1938 done: 1928 done:
1939 1929
1940 ngx_shmtx_unlock(&shpool->mutex); 1930 ngx_shmtx_unlock(&shpool->mutex);