SSL_set_tlsext_host_name(ctx->ssl, srv->ssl_ctx.reused_sess[tid].sni);
HA_RWLOCK_RDUNLOCK(SSL_SERVER_LOCK, &srv->ssl_ctx.reused_sess[tid].sess_lock);
}
+ } else {
+ /* No session available yet, let's see if we can pick one
+ * from another thread. If old_tid is non-null, it designates
+ * the index of a recently updated thread that might still have
+ * a usable session. All threads are collectively responsible
+ * for resetting the index if it fails.
+ */
+ const unsigned char *ptr;
+ SSL_SESSION *sess;
+ uint old_tid = HA_ATOMIC_LOAD(&srv->ssl_ctx.last_ssl_sess_tid); // 0=none, >0 = tid + 1
+
+ if (old_tid) {
+ HA_RWLOCK_RDLOCK(SSL_SERVER_LOCK, &srv->ssl_ctx.reused_sess[old_tid-1].sess_lock);
+
+ ptr = srv->ssl_ctx.reused_sess[old_tid-1].ptr;
+ if (ptr) {
+ sess = d2i_SSL_SESSION(NULL, &ptr, srv->ssl_ctx.reused_sess[old_tid-1].size);
+ if (sess) {
+ if (!SSL_set_session(ctx->ssl, sess))
+ HA_ATOMIC_CAS(&srv->ssl_ctx.last_ssl_sess_tid, &old_tid, 0); // no more valid
+ SSL_SESSION_free(sess);
+ }
+ }
+
+ if (srv->ssl_ctx.reused_sess[old_tid-1].sni)
+ SSL_set_tlsext_host_name(ctx->ssl, srv->ssl_ctx.reused_sess[old_tid-1].sni);
+
+ HA_RWLOCK_RDUNLOCK(SSL_SERVER_LOCK, &srv->ssl_ctx.reused_sess[old_tid-1].sess_lock);
+ }
}
HA_RWLOCK_RDUNLOCK(SSL_SERVER_LOCK, &srv->ssl_ctx.lock);