diff options
author | Alessandro Ghedini <alessandro@ghedini.me> | 2016-02-29 17:26:07 +0000 |
---|---|---|
committer | Rich Salz <rsalz@openssl.org> | 2016-03-08 18:48:38 -0500 |
commit | 16203f7b71bd343550f89f266eaf9fb9693f6148 (patch) | |
tree | 08a0080d1a26dc6db34c0c28387c99da44744de1 /ssl/ssl_sess.c | |
parent | be1251f73def8169b98d53430b631df13d430dbc (diff) |
Convert CRYPTO_LOCK_SSL_* to new multi-threading API
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
Diffstat (limited to 'ssl/ssl_sess.c')
-rw-r--r-- | ssl/ssl_sess.c | 73 |
1 files changed, 49 insertions, 24 deletions
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index 97f3ce2480..ebeeba011c 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -161,12 +161,12 @@ SSL_SESSION *SSL_get1_session(SSL *ssl) * somebody doesn't free ssl->session between when we check it's non-null * and when we up the reference count. */ - CRYPTO_w_lock(CRYPTO_LOCK_SSL_SESSION); + CRYPTO_THREAD_read_lock(ssl->lock); sess = ssl->session; if (sess) - sess->references++; - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_SESSION); - return (sess); + SSL_SESSION_up_ref(sess); + CRYPTO_THREAD_unlock(ssl->lock); + return sess; } int SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg) @@ -186,15 +186,23 @@ SSL_SESSION *SSL_SESSION_new(void) ss = OPENSSL_zalloc(sizeof(*ss)); if (ss == NULL) { SSLerr(SSL_F_SSL_SESSION_NEW, ERR_R_MALLOC_FAILURE); - return (NULL); + return NULL; } ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */ ss->references = 1; ss->timeout = 60 * 5 + 4; /* 5 minute timeout by default */ ss->time = (unsigned long)time(NULL); + ss->lock = CRYPTO_THREAD_lock_new(); + if (ss->lock == NULL) { + SSLerr(SSL_F_SSL_SESSION_NEW, ERR_R_MALLOC_FAILURE); + OPENSSL_free(ss); + return NULL; + } + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); - return (ss); + + return ss; } /* @@ -237,6 +245,10 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) dest->references = 1; + dest->lock = CRYPTO_THREAD_lock_new(); + if (dest->lock == NULL) + goto err; + if (src->peer != NULL) X509_up_ref(src->peer); @@ -437,12 +449,14 @@ int ssl_get_new_session(SSL *s, int session) } /* Choose which callback will set the session ID */ - CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); + CRYPTO_THREAD_read_lock(s->lock); + CRYPTO_THREAD_read_lock(s->session_ctx->lock); if (s->generate_session_id) cb = s->generate_session_id; else if (s->session_ctx->generate_session_id) cb = s->session_ctx->generate_session_id; - CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + CRYPTO_THREAD_unlock(s->session_ctx->lock); + CRYPTO_THREAD_unlock(s->lock); /* Choose a session ID */ tmp = ss->session_id_length; if (!cb(s, ss->session_id, &tmp)) { @@ -562,13 +576,13 @@ int ssl_get_prev_session(SSL *s, const PACKET *ext, const PACKET *session_id) goto err; } data.session_id_length = local_len; - CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); + CRYPTO_THREAD_read_lock(s->session_ctx->lock); ret = lh_SSL_SESSION_retrieve(s->session_ctx->sessions, &data); if (ret != NULL) { /* don't allow other threads to steal it: */ - CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_SSL_SESSION); + SSL_SESSION_up_ref(ret); } - CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + CRYPTO_THREAD_unlock(s->session_ctx->lock); if (ret == NULL) s->session_ctx->stats.sess_miss++; } @@ -591,7 +605,7 @@ int ssl_get_prev_session(SSL *s, const PACKET *ext, const PACKET *session_id) * thread-safe). */ if (copy) - CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_SSL_SESSION); + SSL_SESSION_up_ref(ret); /* * Add the externally cached session to the internal cache as @@ -714,12 +728,12 @@ int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) * it has two ways of access: each session is in a doubly linked list and * an lhash */ - CRYPTO_add(&c->references, 1, CRYPTO_LOCK_SSL_SESSION); + SSL_SESSION_up_ref(c); /* * if session c is in already in cache, we take back the increment later */ - CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + CRYPTO_THREAD_write_lock(ctx->lock); s = lh_SSL_SESSION_insert(ctx->sessions, c); /* @@ -769,8 +783,8 @@ int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) } } } - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); - return (ret); + CRYPTO_THREAD_unlock(ctx->lock); + return ret; } int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c) @@ -785,7 +799,7 @@ static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck) if ((c != NULL) && (c->session_id_length != 0)) { if (lck) - CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + CRYPTO_THREAD_write_lock(ctx->lock); if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) == c) { ret = 1; r = lh_SSL_SESSION_delete(ctx->sessions, c); @@ -793,7 +807,7 @@ static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck) } if (lck) - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + CRYPTO_THREAD_unlock(ctx->lock); if (ret) { r->not_resumable = 1; @@ -813,7 +827,7 @@ void SSL_SESSION_free(SSL_SESSION *ss) if (ss == NULL) return; - i = CRYPTO_add(&ss->references, -1, CRYPTO_LOCK_SSL_SESSION); + CRYPTO_atomic_add(&ss->references, -1, &i, ss->lock); REF_PRINT_COUNT("SSL_SESSION", ss); if (i > 0) return; @@ -841,9 +855,22 @@ void SSL_SESSION_free(SSL_SESSION *ss) #ifndef OPENSSL_NO_SRP OPENSSL_free(ss->srp_username); #endif + CRYPTO_THREAD_lock_free(ss->lock); OPENSSL_clear_free(ss, sizeof(*ss)); } +int SSL_SESSION_up_ref(SSL_SESSION *ss) +{ + int i; + + if (CRYPTO_atomic_add(&ss->references, 1, &i, ss->lock) <= 0) + return 0; + + REF_PRINT_COUNT("SSL_SESSION", ss); + REF_ASSERT_ISNT(i < 2); + return ((i > 1) ? 1 : 0); +} + int SSL_set_session(SSL *s, SSL_SESSION *session) { int ret = 0; @@ -863,12 +890,10 @@ int SSL_set_session(SSL *s, SSL_SESSION *session) return (0); } - /* CRYPTO_w_lock(CRYPTO_LOCK_SSL); */ - CRYPTO_add(&session->references, 1, CRYPTO_LOCK_SSL_SESSION); + SSL_SESSION_up_ref(session); SSL_SESSION_free(s->session); s->session = session; s->verify_result = s->session->verify_result; - /* CRYPTO_w_unlock(CRYPTO_LOCK_SSL); */ ret = 1; } else { SSL_SESSION_free(s->session); @@ -1056,12 +1081,12 @@ void SSL_CTX_flush_sessions(SSL_CTX *s, long t) if (tp.cache == NULL) return; tp.time = t; - CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + CRYPTO_THREAD_write_lock(s->lock); i = CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load; CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = 0; lh_SSL_SESSION_doall_TIMEOUT_PARAM(tp.cache, timeout_cb, &tp); CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = i; - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + CRYPTO_THREAD_unlock(s->lock); } int ssl_clear_bad_session(SSL *s) |