diff options
author | Igor Sysoev <igor@sysoev.ru> | 2007-01-12 20:57:34 +0000 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2007-01-12 20:57:34 +0000 |
commit | 8785136a922a6448ac6c735a62541fbe5f0178ba (patch) | |
tree | 1f4358e0d0bd9abff187609f7f4a113173ff304e /src | |
parent | 805706a20f5c7d241c3847cd2998e7b6bd8b51ac (diff) | |
download | nginx-8785136a922a6448ac6c735a62541fbe5f0178ba.tar.gz nginx-8785136a922a6448ac6c735a62541fbe5f0178ba.zip |
fix duplicate rbtree keys case
Diffstat (limited to 'src')
-rw-r--r-- | src/event/ngx_event_openssl.c | 143 |
1 files changed, 104 insertions, 39 deletions
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c index 8ccc91220..5eecb7ae8 100644 --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -32,6 +32,8 @@ static ngx_ssl_session_t *ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, static void ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess); static void ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache, ngx_slab_pool_t *shpool, ngx_uint_t n); +static void ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp, + ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel); static void *ngx_openssl_create_conf(ngx_cycle_t *cycle); static char *ngx_openssl_init_conf(ngx_cycle_t *cycle, void *conf); @@ -1223,7 +1225,7 @@ ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data) cache->session_rbtree->root = sentinel; cache->session_rbtree->sentinel = sentinel; - cache->session_rbtree->insert = ngx_rbtree_insert_value; + cache->session_rbtree->insert = ngx_ssl_session_rbtree_insert_value; shm_zone->data = cache; @@ -1380,6 +1382,7 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len, #endif u_char *p; uint32_t hash; + ngx_int_t rc; ngx_time_t *tp; ngx_shm_zone_t *shm_zone; ngx_slab_pool_t *shpool; @@ -1392,7 +1395,7 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len, c = ngx_ssl_get_connection(ssl_conn); - hash = ngx_crc32_short(id, len); + hash = ngx_crc32_short(id, (size_t) len); *copy = 0; ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, @@ -1431,42 +1434,42 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len, /* hash == node->key */ do { - if ((u_char) len == node->data) { - sess_id = (ngx_ssl_sess_id_t *) node; + sess_id = (ngx_ssl_sess_id_t *) node; - if (ngx_strncmp(id, sess_id->id, len) == 0) { + rc = ngx_strn2cmp(id, sess_id->id, + (size_t) len, (size_t) node->data); + if (rc == 0) { - tp = ngx_timeofday(); + tp = ngx_timeofday(); - if (sess_id->expire > tp->sec) { - ngx_memcpy(buf, sess_id->session, sess_id->len); + if (sess_id->expire > tp->sec) { + ngx_memcpy(buf, sess_id->session, sess_id->len); - ngx_shmtx_unlock(&shpool->mutex); + ngx_shmtx_unlock(&shpool->mutex); - p = buf; - sess = d2i_SSL_SESSION(NULL, &p, sess_id->len); + p = buf; + sess = d2i_SSL_SESSION(NULL, &p, sess_id->len); - return sess; - } + return sess; + } - sess_id->next->prev = sess_id->prev; - sess_id->prev->next = sess_id->next; + sess_id->next->prev = sess_id->prev; + sess_id->prev->next = sess_id->next; - ngx_rbtree_delete(cache->session_rbtree, node); + ngx_rbtree_delete(cache->session_rbtree, node); - ngx_slab_free_locked(shpool, sess_id->session); + ngx_slab_free_locked(shpool, sess_id->session); #if (NGX_PTR_SIZE == 4) - ngx_slab_free_locked(shpool, sess_id->id); + ngx_slab_free_locked(shpool, sess_id->id); #endif - ngx_slab_free_locked(shpool, sess_id); + ngx_slab_free_locked(shpool, sess_id); - sess = NULL; + sess = NULL; - goto done; - } + goto done; } - node = node->right; + node = (rc < 0) ? node->left : node->right; } while (node != sentinel && hash == node->key); @@ -1484,8 +1487,10 @@ done: static void ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess) { - u_char *id, len; + size_t len; + u_char *id; uint32_t hash; + ngx_int_t rc; ngx_shm_zone_t *shm_zone; ngx_slab_pool_t *shpool; ngx_rbtree_node_t *node, *sentinel; @@ -1497,12 +1502,12 @@ ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess) cache = shm_zone->data; id = sess->session_id; - len = (u_char) sess->session_id_length; + len = (size_t) sess->session_id_length; - hash = ngx_crc32_short(id, (size_t) len); + hash = ngx_crc32_short(id, len); ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, - "http ssl remove session: %08XD:%d", hash, len); + "http ssl remove session: %08XD:%uz", hash, len); shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; @@ -1526,27 +1531,26 @@ ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess) /* hash == node->key */ do { - if ((u_char) len == node->data) { - sess_id = (ngx_ssl_sess_id_t *) node; + sess_id = (ngx_ssl_sess_id_t *) node; - if (ngx_strncmp(id, sess_id->id, (size_t) len) == 0) { + rc = ngx_strn2cmp(id, sess_id->id, len, (size_t) node->data); - sess_id->next->prev = sess_id->prev; - sess_id->prev->next = sess_id->next; + if (rc == 0) { + sess_id->next->prev = sess_id->prev; + sess_id->prev->next = sess_id->next; - ngx_rbtree_delete(cache->session_rbtree, node); + ngx_rbtree_delete(cache->session_rbtree, node); - ngx_slab_free_locked(shpool, sess_id->session); + ngx_slab_free_locked(shpool, sess_id->session); #if (NGX_PTR_SIZE == 4) - ngx_slab_free_locked(shpool, sess_id->id); + ngx_slab_free_locked(shpool, sess_id->id); #endif - ngx_slab_free_locked(shpool, sess_id); + ngx_slab_free_locked(shpool, sess_id); - goto done; - } + goto done; } - node = node->right; + node = (rc < 0) ? node->left : node->right; } while (node != sentinel && hash == node->key); @@ -1597,6 +1601,67 @@ ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache, } +static void +ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp, + ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel) +{ + ngx_ssl_sess_id_t *sess_id, *sess_id_temp; + + for ( ;; ) { + + if (node->key < temp->key) { + + if (temp->left == sentinel) { + temp->left = node; + break; + } + + temp = temp->left; + + } else if (node->key > temp->key) { + + if (temp->right == sentinel) { + temp->right = node; + break; + } + + temp = temp->right; + + } else { /* node->key == temp->key */ + + sess_id = (ngx_ssl_sess_id_t *) node; + sess_id_temp = (ngx_ssl_sess_id_t *) temp; + + if (ngx_strn2cmp(sess_id->id, sess_id_temp->id, + (size_t) node->data, (size_t) temp->data) + < 0) + { + if (temp->left == sentinel) { + temp->left = node; + break; + } + + temp = temp->left; + + } else { + + if (temp->right == sentinel) { + temp->right = node; + break; + } + + temp = temp->right; + } + } + } + + node->parent = temp; + node->left = sentinel; + node->right = sentinel; + ngx_rbt_red(node); +} + + void ngx_ssl_cleanup_ctx(void *data) { |