/* The bind_conf will be null on server ckch_instances. */
if (ckchi->is_server_instance) {
int i;
-
- /* The certificate update on the server side (backend)
- * can be done by rewriting a single pointer so no
- * locks are needed here. */
+ /* a lock is needed here since we have to free the SSL cache */
+ HA_RWLOCK_WRLOCK(SSL_SERVER_LOCK, &ckchi->server->ssl_ctx.lock);
/* free the server current SSL_CTX */
SSL_CTX_free(ckchi->server->ssl_ctx.ctx);
/* Actual ssl context update */
- thread_isolate();
SSL_CTX_up_ref(ckchi->ctx);
ckchi->server->ssl_ctx.ctx = ckchi->ctx;
ckchi->server->ssl_ctx.inst = ckchi;
free(ckchi->server->ssl_ctx.reused_sess[i].ptr);
ckchi->server->ssl_ctx.reused_sess[i].ptr = NULL;
}
- thread_release();
+ HA_RWLOCK_WRUNLOCK(SSL_SERVER_LOCK, &ckchi->server->ssl_ctx.lock);
} else {
HA_RWLOCK_WRLOCK(SNI_LOCK, &ckchi->bind_conf->sni_lock);
s = __objt_server(conn->target);
+ /* RWLOCK: only read lock the SSL cache even when writing in it because there is
+ * one cache per thread, it only prevents to flush it from the CLI in
+ * another thread */
+
if (!(s->ssl_ctx.options & SRV_SSL_O_NO_REUSE)) {
int len;
unsigned char *ptr;
len = i2d_SSL_SESSION(sess, NULL);
+ HA_RWLOCK_RDLOCK(SSL_SERVER_LOCK, &s->ssl_ctx.lock);
if (s->ssl_ctx.reused_sess[tid].ptr && s->ssl_ctx.reused_sess[tid].allocated_size >= len) {
ptr = s->ssl_ctx.reused_sess[tid].ptr;
} else {
s->ssl_ctx.reused_sess[tid].size = i2d_SSL_SESSION(sess,
&ptr);
}
+ HA_RWLOCK_RDUNLOCK(SSL_SERVER_LOCK, &s->ssl_ctx.lock);
} else {
+ HA_RWLOCK_RDLOCK(SSL_SERVER_LOCK, &s->ssl_ctx.lock);
free(s->ssl_ctx.reused_sess[tid].ptr);
s->ssl_ctx.reused_sess[tid].ptr = NULL;
+ HA_RWLOCK_RDUNLOCK(SSL_SERVER_LOCK, &s->ssl_ctx.lock);
}
return 0;
goto err;
SSL_set_connect_state(ctx->ssl);
+ HA_RWLOCK_RDLOCK(SSL_SERVER_LOCK, &(__objt_server(conn->target)->ssl_ctx.lock));
if (__objt_server(conn->target)->ssl_ctx.reused_sess[tid].ptr) {
const unsigned char *ptr = __objt_server(conn->target)->ssl_ctx.reused_sess[tid].ptr;
SSL_SESSION *sess = d2i_SSL_SESSION(NULL, &ptr, __objt_server(conn->target)->ssl_ctx.reused_sess[tid].size);
SSL_SESSION_free(sess);
}
}
+ HA_RWLOCK_RDUNLOCK(SSL_SERVER_LOCK, &(__objt_server(conn->target)->ssl_ctx.lock));
/* leave init state and start handshake */
conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
ERR_clear_error();
/* free resumed session if exists */
- if (objt_server(conn->target) && __objt_server(conn->target)->ssl_ctx.reused_sess[tid].ptr) {
- free(__objt_server(conn->target)->ssl_ctx.reused_sess[tid].ptr);
- __objt_server(conn->target)->ssl_ctx.reused_sess[tid].ptr = NULL;
+ if (objt_server(conn->target)) {
+ struct server *s = __objt_server(conn->target);
+ /* RWLOCK: only rdlock the SSL cache even when writing in it because there is
+ * one cache per thread, it only prevents to flush it from the CLI in
+ * another thread */
+
+ HA_RWLOCK_RDLOCK(SSL_SERVER_LOCK, &s->ssl_ctx.lock);
+ if (s->ssl_ctx.reused_sess[tid].ptr) {
+ free(s->ssl_ctx.reused_sess[tid].ptr);
+ s->ssl_ctx.reused_sess[tid].ptr = NULL;
+ }
+ HA_RWLOCK_RDUNLOCK(SSL_SERVER_LOCK, &s->ssl_ctx.lock);
}
if (counters) {