diff --git a/include/haproxy/server-t.h b/include/haproxy/server-t.h index 068d56d21..03f6899a9 100644 --- a/include/haproxy/server-t.h +++ b/include/haproxy/server-t.h @@ -390,6 +390,7 @@ struct server { char *sni; /* SNI used for the session */ __decl_thread(HA_RWLOCK_T sess_lock); } * reused_sess; + uint last_ssl_sess_tid; /* last tid+1 having updated reused_sess (0=none, >0=tid+1) */ struct ckch_inst *inst; /* Instance of the ckch_store in which the certificate was loaded (might be null if server has no certificate) */ __decl_thread(HA_RWLOCK_T lock); /* lock the cache and SSL_CTX during commit operations */ diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 4aae83b23..679ae2e78 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -4261,6 +4261,7 @@ static int ssl_sess_new_srv_cb(SSL *ssl, SSL_SESSION *sess) { struct connection *conn = SSL_get_ex_data(ssl, ssl_app_data_index); struct server *s; + uint old_tid; s = __objt_server(conn->target); @@ -4306,6 +4307,16 @@ static int ssl_sess_new_srv_cb(SSL *ssl, SSL_SESSION *sess) /* done updating the session */ + /* Now we'll try to add or remove this entry as a valid one: + * - if no entry is set and we have one, let's share it + * - if our entry was set and we have no more, let's clear it + */ + old_tid = HA_ATOMIC_LOAD(&s->ssl_ctx.last_ssl_sess_tid); // 0=none, >0 = tid + 1 + if (!s->ssl_ctx.reused_sess[tid].ptr && old_tid == tid + 1) + HA_ATOMIC_CAS(&s->ssl_ctx.last_ssl_sess_tid, &old_tid, 0); // no more valid + else if (s->ssl_ctx.reused_sess[tid].ptr && !old_tid) + HA_ATOMIC_CAS(&s->ssl_ctx.last_ssl_sess_tid, &old_tid, tid + 1); + if (s->ssl_ctx.reused_sess[tid].sni) { /* if the new sni is empty or isn' t the same as the old one */ if ((!sni) || strcmp(s->ssl_ctx.reused_sess[tid].sni, sni) != 0) { @@ -4328,6 +4339,10 @@ static int ssl_sess_new_srv_cb(SSL *ssl, SSL_SESSION *sess) HA_RWLOCK_WRUNLOCK(SSL_SERVER_LOCK, &s->ssl_ctx.reused_sess[tid].sess_lock); } + old_tid = HA_ATOMIC_LOAD(&s->ssl_ctx.last_ssl_sess_tid); // 0=none, >0 = tid + 1 + if (old_tid == tid + 1) + HA_ATOMIC_CAS(&s->ssl_ctx.last_ssl_sess_tid, &old_tid, 0); // no more valid + HA_RWLOCK_RDUNLOCK(SSL_SERVER_LOCK, &s->ssl_ctx.lock); }