MEDIUM: ssl: Give ssl_sock its own context.

Instead of using directly a SSL * as xprt_ctx, give ssl_sock its own context.
It's useless for now, but will be useful later when we'll want to be able to
stack xprts.
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 93bf53d..4979d8a 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -238,6 +238,14 @@
 	.capture_cipherlist = 0,
 };
 
+struct ssl_sock_ctx {
+	SSL *ssl;
+	struct xprt_ops *xprt;
+	void *xprt_ctx;
+};
+
+DECLARE_STATIC_POOL(ssl_sock_ctx_pool, "ssl_sock_ctx_pool", sizeof(struct ssl_sock_ctx));
+
 #if defined(USE_THREAD) && ((OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER))
 
 static HA_RWLOCK_T *ssl_rwlocks;
@@ -1912,8 +1920,9 @@
 ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
 {
 	struct bind_conf *bind_conf = __objt_listener(conn->target)->bind_conf;
+	struct ssl_sock_ctx *ctx = conn->xprt_ctx;
 
-	return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
+	return ssl_sock_do_create_cert(servername, bind_conf, ctx->ssl);
 }
 
 /* Do a lookup for a certificate in the LRU cache used to store generated
@@ -4503,6 +4512,7 @@
 {
 	SSL *ssl;
 	struct connection *conn;
+	struct ssl_sock_ctx *ssl_ctx;
 	const char *servername;
 	const char *sni;
 
@@ -4518,6 +4528,7 @@
 
 	ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
 	conn = SSL_get_ex_data(ssl, ssl_app_data_index);
+	ssl_ctx = conn->xprt_ctx;
 
 	/* We're checking if the provided hostnames match the desired one. The
 	 * desired hostname comes from the SNI we presented if any, or if not
@@ -4525,7 +4536,7 @@
 	 * directive. If neither is set, we don't care about the name so the
 	 * verification is OK.
 	 */
-	servername = SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
+	servername = SSL_get_servername(ssl_ctx->ssl, TLSEXT_NAMETYPE_host_name);
 	sni = servername;
 	if (!servername) {
 		servername = __objt_server(conn->target)->ssl_ctx.verify_host;
@@ -5076,6 +5087,7 @@
  */
 static int ssl_sock_init(struct connection *conn)
 {
+	struct ssl_sock_ctx *ctx;
 	/* already initialized */
 	if (conn->xprt_ctx)
 		return 0;
@@ -5083,6 +5095,12 @@
 	if (!conn_ctrl_ready(conn))
 		return 0;
 
+	ctx = pool_alloc(ssl_sock_ctx_pool);
+	if (!ctx) {
+		conn->err_code = CO_ER_SSL_NO_MEM;
+		return -1;
+	}
+
 	if (global.maxsslconn && sslconns >= global.maxsslconn) {
 		conn->err_code = CO_ER_SSL_TOO_MANY;
 		return -1;
@@ -5095,45 +5113,46 @@
 
 	retry_connect:
 		/* Alloc a new SSL session ctx */
-		conn->xprt_ctx = SSL_new(__objt_server(conn->target)->ssl_ctx.ctx);
-		if (!conn->xprt_ctx) {
+		ctx->ssl = SSL_new(__objt_server(conn->target)->ssl_ctx.ctx);
+		if (!ctx->ssl) {
 			if (may_retry--) {
 				pool_gc(NULL);
 				goto retry_connect;
 			}
 			conn->err_code = CO_ER_SSL_NO_MEM;
-			return -1;
+			goto err;
 		}
 
 		/* set fd on SSL session context */
-		if (!SSL_set_fd(conn->xprt_ctx, conn->handle.fd)) {
-			SSL_free(conn->xprt_ctx);
-			conn->xprt_ctx = NULL;
+		if (!SSL_set_fd(ctx->ssl, conn->handle.fd)) {
+			SSL_free(ctx->ssl);
+			ctx->ssl = NULL;
 			if (may_retry--) {
 				pool_gc(NULL);
 				goto retry_connect;
 			}
 			conn->err_code = CO_ER_SSL_NO_MEM;
-			return -1;
+			goto err;
 		}
 
 		/* set connection pointer */
-		if (!SSL_set_ex_data(conn->xprt_ctx, ssl_app_data_index, conn)) {
-			SSL_free(conn->xprt_ctx);
+		if (!SSL_set_ex_data(ctx->ssl, ssl_app_data_index, conn)) {
+			SSL_free(ctx->ssl);
+			ctx->ssl = NULL;
 			conn->xprt_ctx = NULL;
 			if (may_retry--) {
 				pool_gc(NULL);
 				goto retry_connect;
 			}
 			conn->err_code = CO_ER_SSL_NO_MEM;
-			return -1;
+			goto err;
 		}
 
-		SSL_set_connect_state(conn->xprt_ctx);
+		SSL_set_connect_state(ctx->ssl);
 		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);
-			if (sess && !SSL_set_session(conn->xprt_ctx, sess)) {
+			if (sess && !SSL_set_session(ctx->ssl, sess)) {
 				SSL_SESSION_free(sess);
 				free(__objt_server(conn->target)->ssl_ctx.reused_sess[tid].ptr);
 				__objt_server(conn->target)->ssl_ctx.reused_sess[tid].ptr = NULL;
@@ -5144,6 +5163,7 @@
 
 		/* leave init state and start handshake */
 		conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
+		conn->xprt_ctx = ctx;
 
 		_HA_ATOMIC_ADD(&sslconns, 1);
 		_HA_ATOMIC_ADD(&totalsslconns, 1);
@@ -5154,41 +5174,41 @@
 
 	retry_accept:
 		/* Alloc a new SSL session ctx */
-		conn->xprt_ctx = SSL_new(__objt_listener(conn->target)->bind_conf->initial_ctx);
-		if (!conn->xprt_ctx) {
+		ctx->ssl = SSL_new(__objt_listener(conn->target)->bind_conf->initial_ctx);
+		if (!ctx->ssl) {
 			if (may_retry--) {
 				pool_gc(NULL);
 				goto retry_accept;
 			}
 			conn->err_code = CO_ER_SSL_NO_MEM;
-			return -1;
+			goto err;
 		}
 
 		/* set fd on SSL session context */
-		if (!SSL_set_fd(conn->xprt_ctx, conn->handle.fd)) {
-			SSL_free(conn->xprt_ctx);
-			conn->xprt_ctx = NULL;
+		if (!SSL_set_fd(ctx->ssl, conn->handle.fd)) {
+			SSL_free(ctx->ssl);
+			ctx->ssl = NULL;
 			if (may_retry--) {
 				pool_gc(NULL);
 				goto retry_accept;
 			}
 			conn->err_code = CO_ER_SSL_NO_MEM;
-			return -1;
+			goto err;
 		}
 
 		/* set connection pointer */
-		if (!SSL_set_ex_data(conn->xprt_ctx, ssl_app_data_index, conn)) {
-			SSL_free(conn->xprt_ctx);
-			conn->xprt_ctx = NULL;
+		if (!SSL_set_ex_data(ctx->ssl, ssl_app_data_index, conn)) {
+			SSL_free(ctx->ssl);
+			ctx->ssl = NULL;
 			if (may_retry--) {
 				pool_gc(NULL);
 				goto retry_accept;
 			}
 			conn->err_code = CO_ER_SSL_NO_MEM;
-			return -1;
+			goto err;
 		}
 
-		SSL_set_accept_state(conn->xprt_ctx);
+		SSL_set_accept_state(ctx->ssl);
 
 		/* leave init state and start handshake */
 		conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
@@ -5198,10 +5218,13 @@
 
 		_HA_ATOMIC_ADD(&sslconns, 1);
 		_HA_ATOMIC_ADD(&totalsslconns, 1);
+		conn->xprt_ctx = ctx;
 		return 0;
 	}
 	/* don't know how to handle such a target */
 	conn->err_code = CO_ER_SSL_NO_TARGET;
+err:
+	pool_free(ssl_sock_ctx_pool, ctx);
 	return -1;
 }
 
@@ -5214,6 +5237,7 @@
  */
 int ssl_sock_handshake(struct connection *conn, unsigned int flag)
 {
+	struct ssl_sock_ctx *ctx = conn->xprt_ctx;
 	int ret;
 
 	if (!conn_ctrl_ready(conn))
@@ -5231,7 +5255,7 @@
 	if (conn->flags & CO_FL_EARLY_SSL_HS) {
 		size_t read_data;
 
-		ret = SSL_read_early_data(conn->xprt_ctx, &conn->tmp_early_data,
+		ret = SSL_read_early_data(ctx->ssl, &conn->tmp_early_data,
 		    1, &read_data);
 		if (ret == SSL_READ_EARLY_DATA_ERROR)
 			goto check_error;
@@ -5248,13 +5272,13 @@
 	 * the reneg handshake.
 	 * Here we use SSL_peek as a workaround for reneg.
 	 */
-	if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
+	if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(ctx->ssl)) {
 		char c;
 
-		ret = SSL_peek(conn->xprt_ctx, &c, 1);
+		ret = SSL_peek(ctx->ssl, &c, 1);
 		if (ret <= 0) {
 			/* handshake may have not been completed, let's find why */
-			ret = SSL_get_error(conn->xprt_ctx, ret);
+			ret = SSL_get_error(ctx->ssl, ret);
 
 			if (ret == SSL_ERROR_WANT_WRITE) {
 				/* SSL handshake needs to write, L4 connection may not be ready */
@@ -5267,7 +5291,7 @@
 				/* handshake may have been completed but we have
 				 * no more data to read.
                                  */
-				if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
+				if (!SSL_renegotiate_pending(ctx->ssl)) {
 					ret = 1;
 					goto reneg_ok;
 				}
@@ -5281,7 +5305,7 @@
 			}
 #if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
 			else if (ret == SSL_ERROR_WANT_ASYNC) {
-				ssl_async_process_fds(conn, conn->xprt_ctx);
+				ssl_async_process_fds(conn, ctx->ssl);
 				return 0;
 			}
 #endif
@@ -5295,10 +5319,10 @@
 #else
 					int empty_handshake;
 #if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
-					OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
+					OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)ctx->ssl);
 					empty_handshake = state == TLS_ST_BEFORE;
 #else
-					empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
+					empty_handshake = !ctx->ssl->packet_length;
 #endif
 					if (empty_handshake) {
 						if (!errno) {
@@ -5341,11 +5365,11 @@
 		/* read some data: consider handshake completed */
 		goto reneg_ok;
 	}
-	ret = SSL_do_handshake(conn->xprt_ctx);
+	ret = SSL_do_handshake(ctx->ssl);
 check_error:
 	if (ret != 1) {
 		/* handshake did not complete, let's find why */
-		ret = SSL_get_error(conn->xprt_ctx, ret);
+		ret = SSL_get_error(ctx->ssl, ret);
 
 		if (ret == SSL_ERROR_WANT_WRITE) {
 			/* SSL handshake needs to write, L4 connection may not be ready */
@@ -5365,7 +5389,7 @@
 		}
 #if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
 		else if (ret == SSL_ERROR_WANT_ASYNC) {
-			ssl_async_process_fds(conn, conn->xprt_ctx);
+			ssl_async_process_fds(conn, ctx->ssl);
 			return 0;
 		}
 #endif
@@ -5379,10 +5403,10 @@
 #else
 				int empty_handshake;
 #if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
-				OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
+				OSSL_HANDSHAKE_STATE state = SSL_get_state(ctx->ssl);
 				empty_handshake = state == TLS_ST_BEFORE;
 #else
-				empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
+				empty_handshake = !ctx->ssl->packet_length;
 #endif
 				if (empty_handshake) {
 					if (!errno) {
@@ -5430,7 +5454,7 @@
 		 * them again.
 		 */
 		if ((conn->flags & CO_FL_EARLY_DATA) && (objt_server(conn->target))) {
-			if (SSL_get_early_data_status(conn->xprt_ctx) == SSL_EARLY_DATA_REJECTED) {
+			if (SSL_get_early_data_status(ctx->ssl) == SSL_EARLY_DATA_REJECTED) {
 				conn->err_code = CO_ER_SSL_EARLY_FAILED;
 				goto out_error;
 			}
@@ -5447,10 +5471,10 @@
 	 * the handshake to avoid buffer oveflows.
 	 */
 	if (global_ssl.async)
-		SSL_clear_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
+		SSL_clear_mode(ctx->ssl, SSL_MODE_ASYNC);
 #endif
 	/* Handshake succeeded */
-	if (!SSL_session_reused(conn->xprt_ctx)) {
+	if (!SSL_session_reused(ctx->ssl)) {
 		if (objt_server(conn->target)) {
 			update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
 			if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
@@ -5464,7 +5488,7 @@
 	}
 
 #ifdef OPENSSL_IS_BORINGSSL
-	if ((conn->flags & CO_FL_EARLY_SSL_HS) && !SSL_in_early_data(conn->xprt_ctx))
+	if ((conn->flags & CO_FL_EARLY_SSL_HS) && !SSL_in_early_data(ctx->ssl))
 		conn->flags &= ~CO_FL_EARLY_SSL_HS;
 #endif
 	/* The connection is now established at both layers, it's time to leave */
@@ -5499,6 +5523,7 @@
  */
 static size_t ssl_sock_to_buf(struct connection *conn, struct buffer *buf, size_t count, int flags)
 {
+	struct ssl_sock_ctx *ctx = conn->xprt_ctx;
 	ssize_t ret;
 	size_t try, done = 0;
 
@@ -5541,7 +5566,7 @@
 		if (conn->flags & CO_FL_EARLY_SSL_HS) {
 			size_t read_length;
 
-			ret = SSL_read_early_data(conn->xprt_ctx,
+			ret = SSL_read_early_data(ctx->ssl,
 			    b_tail(buf), try, &read_length);
 			if (ret == SSL_READ_EARLY_DATA_SUCCESS &&
 			    read_length > 0)
@@ -5563,10 +5588,10 @@
 			}
 		} else
 #endif
-		ret = SSL_read(conn->xprt_ctx, b_tail(buf), try);
+		ret = SSL_read(ctx->ssl, b_tail(buf), try);
 #ifdef OPENSSL_IS_BORINGSSL
 		if (conn->flags & CO_FL_EARLY_SSL_HS) {
-			if (SSL_in_early_data(conn->xprt_ctx)) {
+			if (SSL_in_early_data(ctx->ssl)) {
 				if (ret > 0)
 					conn->flags |= CO_FL_EARLY_DATA;
 			} else {
@@ -5584,7 +5609,7 @@
 			count -= ret;
 		}
 		else {
-			ret =  SSL_get_error(conn->xprt_ctx, ret);
+			ret =  SSL_get_error(ctx->ssl, ret);
 			if (ret == SSL_ERROR_WANT_WRITE) {
 				/* handshake is running, and it needs to enable write */
 				conn->flags |= CO_FL_SSL_WAIT_HS;
@@ -5592,19 +5617,19 @@
 #if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
 				/* Async mode can be re-enabled, because we're leaving data state.*/
 				if (global_ssl.async)
-					SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
+					SSL_set_mode(ctx->ssl, SSL_MODE_ASYNC);
 #endif
 				break;
 			}
 			else if (ret == SSL_ERROR_WANT_READ) {
-				if (SSL_renegotiate_pending(conn->xprt_ctx)) {
+				if (SSL_renegotiate_pending(ctx->ssl)) {
 					/* handshake is running, and it may need to re-enable read */
 					conn->flags |= CO_FL_SSL_WAIT_HS;
 					__conn_sock_want_recv(conn);
 #if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
 					/* Async mode can be re-enabled, because we're leaving data state.*/
 					if (global_ssl.async)
-						SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
+						SSL_set_mode(ctx->ssl, SSL_MODE_ASYNC);
 #endif
 					break;
 				}
@@ -5659,6 +5684,7 @@
  */
 static size_t ssl_sock_from_buf(struct connection *conn, const struct buffer *buf, size_t count, int flags)
 {
+	struct ssl_sock_ctx *ctx = conn->xprt_ctx;
 	ssize_t ret;
 	size_t try, done;
 
@@ -5699,14 +5725,14 @@
 		}
 
 #if (OPENSSL_VERSION_NUMBER >= 0x10101000L)
-		if (!SSL_is_init_finished(conn->xprt_ctx)) {
+		if (!SSL_is_init_finished(ctx->ssl)) {
 			unsigned int max_early;
 
 			if (objt_listener(conn->target))
-				max_early = SSL_get_max_early_data(conn->xprt_ctx);
+				max_early = SSL_get_max_early_data(ctx->ssl);
 			else {
-				if (SSL_get0_session(conn->xprt_ctx))
-					max_early = SSL_SESSION_get_max_early_data(SSL_get0_session(conn->xprt_ctx));
+				if (SSL_get0_session(ctx->ssl))
+					max_early = SSL_SESSION_get_max_early_data(SSL_get0_session(ctx->ssl));
 				else
 					max_early = 0;
 			}
@@ -5719,7 +5745,7 @@
 					break;
 				}
 			}
-			ret = SSL_write_early_data(conn->xprt_ctx, b_peek(buf, done), try, &written_data);
+			ret = SSL_write_early_data(ctx->ssl, b_peek(buf, done), try, &written_data);
 			if (ret == 1) {
 				ret = written_data;
 				conn->sent_early_data += ret;
@@ -5732,7 +5758,7 @@
 
 		} else
 #endif
-			ret = SSL_write(conn->xprt_ctx, b_peek(buf, done), try);
+			ret = SSL_write(ctx->ssl, b_peek(buf, done), try);
 
 		if (conn->flags & CO_FL_ERROR) {
 			/* CO_FL_ERROR may be set by ssl_sock_infocbk */
@@ -5746,17 +5772,17 @@
 			done += ret;
 		}
 		else {
-			ret = SSL_get_error(conn->xprt_ctx, ret);
+			ret = SSL_get_error(ctx->ssl, ret);
 
 			if (ret == SSL_ERROR_WANT_WRITE) {
-				if (SSL_renegotiate_pending(conn->xprt_ctx)) {
+				if (SSL_renegotiate_pending(ctx->ssl)) {
 					/* handshake is running, and it may need to re-enable write */
 					conn->flags |= CO_FL_SSL_WAIT_HS;
 					__conn_sock_want_send(conn);
 #if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
 					/* Async mode can be re-enabled, because we're leaving data state.*/
 					if (global_ssl.async)
-						SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
+						SSL_set_mode(ctx->ssl, SSL_MODE_ASYNC);
 #endif
 					break;
 				}
@@ -5771,7 +5797,7 @@
 #if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
 				/* Async mode can be re-enabled, because we're leaving data state.*/
 				if (global_ssl.async)
-					SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
+					SSL_set_mode(ctx->ssl, SSL_MODE_ASYNC);
 #endif
 				break;
 			}
@@ -5793,6 +5819,8 @@
 
 static void ssl_sock_close(struct connection *conn) {
 
+	struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+
 	if (conn->xprt_ctx) {
 #if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(OPENSSL_NO_ASYNC)
 		if (global_ssl.async) {
@@ -5800,31 +5828,32 @@
 			size_t num_all_fds = 0;
 			int i;
 
-			SSL_get_all_async_fds(conn->xprt_ctx, NULL, &num_all_fds);
+			SSL_get_all_async_fds(ctx->ssl, NULL, &num_all_fds);
 			if (num_all_fds > 32) {
 				send_log(NULL, LOG_EMERG, "haproxy: openssl returns too many async fds. It seems a bug. Process may crash\n");
 				return;
 			}
 
-			SSL_get_all_async_fds(conn->xprt_ctx, all_fd, &num_all_fds);
+			SSL_get_all_async_fds(ctx->ssl, all_fd, &num_all_fds);
 
 			/* If an async job is pending, we must try to
 			   to catch the end using polling before calling
 			   SSL_free */
-			if (num_all_fds && SSL_waiting_for_async(conn->xprt_ctx)) {
+			if (num_all_fds && SSL_waiting_for_async(ctx->ssl)) {
 				for (i=0 ; i < num_all_fds ; i++) {
 					/* switch on an handler designed to
 					 * handle the SSL_free
 					 */
 					afd = all_fd[i];
 					fdtab[afd].iocb = ssl_async_fd_free;
-					fdtab[afd].owner = conn->xprt_ctx;
+					fdtab[afd].owner = ctx->ssl;
 					fd_want_recv(afd);
 					/* To ensure that the fd cache won't be used
 					 * and we'll catch a real RD event.
 					 */
 					fd_cant_recv(afd);
 				}
+				pool_free(ssl_sock_ctx_pool, ctx);
 				conn->xprt_ctx = NULL;
 				_HA_ATOMIC_ADD(&jobs, 1);
 				return;
@@ -5839,7 +5868,8 @@
 				fd_remove(all_fd[i]);
 		}
 #endif
-		SSL_free(conn->xprt_ctx);
+		SSL_free(ctx->ssl);
+		pool_free(ssl_sock_ctx_pool, ctx);
 		conn->xprt_ctx = NULL;
 		_HA_ATOMIC_SUB(&sslconns, 1);
 	}
@@ -5850,13 +5880,15 @@
  */
 static void ssl_sock_shutw(struct connection *conn, int clean)
 {
+	struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+
 	if (conn->flags & CO_FL_HANDSHAKE)
 		return;
 	if (!clean)
 		/* don't sent notify on SSL_shutdown */
-		SSL_set_quiet_shutdown(conn->xprt_ctx, 1);
+		SSL_set_quiet_shutdown(ctx->ssl, 1);
 	/* no handshake was in progress, try a clean ssl shutdown */
-	if (SSL_shutdown(conn->xprt_ctx) <= 0) {
+	if (SSL_shutdown(ctx->ssl) <= 0) {
 		/* Clear openssl global errors stack */
 		ssl_sock_dump_errors(conn);
 		ERR_clear_error();
@@ -5866,6 +5898,7 @@
 /* used for ppv2 pkey alog (can be used for logging) */
 int ssl_sock_get_pkey_algo(struct connection *conn, struct buffer *out)
 {
+	struct ssl_sock_ctx *ctx = conn->xprt_ctx;
 	struct pkey_info *pkinfo;
 	int bits = 0;
 	int sig = TLSEXT_signature_anonymous;
@@ -5874,7 +5907,7 @@
 	if (!ssl_sock_is_ssl(conn))
 		return 0;
 
-	pkinfo = SSL_CTX_get_ex_data(SSL_get_SSL_CTX(conn->xprt_ctx), ssl_pkey_info_index);
+	pkinfo = SSL_CTX_get_ex_data(SSL_get_SSL_CTX(ctx->ssl), ssl_pkey_info_index);
 	if (pkinfo) {
 		sig = pkinfo->sig;
 		bits = pkinfo->bits;
@@ -5882,7 +5915,7 @@
 		/* multicert and generated cert have no pkey info */
 		X509 *crt;
 		EVP_PKEY *pkey;
-		crt = SSL_get_certificate(conn->xprt_ctx);
+		crt = SSL_get_certificate(ctx->ssl);
 		if (!crt)
 			return 0;
 		pkey = X509_get_pubkey(crt);
@@ -5924,12 +5957,14 @@
 /* used for ppv2 cert signature (can be used for logging) */
 const char *ssl_sock_get_cert_sig(struct connection *conn)
 {
+	struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+
 	__OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
 	X509 *crt;
 
 	if (!ssl_sock_is_ssl(conn))
 		return NULL;
-	crt = SSL_get_certificate(conn->xprt_ctx);
+	crt = SSL_get_certificate(ctx->ssl);
 	if (!crt)
 		return NULL;
 	X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
@@ -5940,30 +5975,36 @@
 const char *ssl_sock_get_sni(struct connection *conn)
 {
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+	struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+
 	if (!ssl_sock_is_ssl(conn))
 		return NULL;
-	return SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
+	return SSL_get_servername(ctx->ssl, TLSEXT_NAMETYPE_host_name);
 #else
-	return 0;
+	return NULL;
 #endif
 }
 
 /* used for logging/ppv2, may be changed for a sample fetch later */
 const char *ssl_sock_get_cipher_name(struct connection *conn)
 {
+	struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+
 	if (!ssl_sock_is_ssl(conn))
 		return NULL;
 
-	return SSL_get_cipher_name(conn->xprt_ctx);
+	return SSL_get_cipher_name(ctx->ssl);
 }
 
 /* used for logging/ppv2, may be changed for a sample fetch later */
 const char *ssl_sock_get_proto_version(struct connection *conn)
 {
+	struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+
 	if (!ssl_sock_is_ssl(conn))
 		return NULL;
 
-	return SSL_get_version(conn->xprt_ctx);
+	return SSL_get_version(ctx->ssl);
 }
 
 /* Extract a serial from a cert, and copy it to a chunk.
@@ -6168,7 +6209,9 @@
 void ssl_sock_set_alpn(struct connection *conn, const unsigned char *alpn, int len)
 {
 #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
-	SSL_set_alpn_protos(conn->xprt_ctx, alpn, len);
+	struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+
+	SSL_set_alpn_protos(ctx->ssl, alpn, len);
 #endif
 }
 
@@ -6178,6 +6221,8 @@
 void ssl_sock_set_servername(struct connection *conn, const char *hostname)
 {
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+	struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+
 	char *prev_name;
 
 	if (!ssl_sock_is_ssl(conn))
@@ -6188,12 +6233,12 @@
 	 * later imagine having a small cache of ssl_ctx to hold a few SNI per
 	 * server.
 	 */
-	prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
+	prev_name = (char *)SSL_get_servername(ctx->ssl, TLSEXT_NAMETYPE_host_name);
 	if ((!prev_name && hostname) ||
 	    (prev_name && (!hostname || strcmp(hostname, prev_name) != 0)))
-		SSL_set_session(conn->xprt_ctx, NULL);
+		SSL_set_session(ctx->ssl, NULL);
 
-	SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
+	SSL_set_tlsext_host_name(ctx->ssl, hostname);
 #endif
 }
 
@@ -6206,6 +6251,7 @@
 int ssl_sock_get_remote_common_name(struct connection *conn,
 				    struct buffer *dest)
 {
+	struct ssl_sock_ctx *ctx = conn->xprt_ctx;
 	X509 *crt = NULL;
 	X509_NAME *name;
 	const char find_cn[] = "CN";
@@ -6219,7 +6265,7 @@
 		goto out;
 
 	/* SSL_get_peer_certificate, it increase X509 * ref count */
-	crt = SSL_get_peer_certificate(conn->xprt_ctx);
+	crt = SSL_get_peer_certificate(ctx->ssl);
 	if (!crt)
 		goto out;
 
@@ -6238,13 +6284,14 @@
 /* returns 1 if client passed a certificate for this session, 0 if not */
 int ssl_sock_get_cert_used_sess(struct connection *conn)
 {
+	struct ssl_sock_ctx *ctx = conn->xprt_ctx;
 	X509 *crt = NULL;
 
 	if (!ssl_sock_is_ssl(conn))
 		return 0;
 
 	/* SSL_get_peer_certificate, it increase X509 * ref count */
-	crt = SSL_get_peer_certificate(conn->xprt_ctx);
+	crt = SSL_get_peer_certificate(ctx->ssl);
 	if (!crt)
 		return 0;
 
@@ -6264,10 +6311,12 @@
 /* returns result from SSL verify */
 unsigned int ssl_sock_get_verify_result(struct connection *conn)
 {
+	struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+
 	if (!ssl_sock_is_ssl(conn))
 		return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
 
-	return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
+	return (unsigned int)SSL_get_verify_result(ctx->ssl);
 }
 
 /* Returns the application layer protocol name in <str> and <len> when known.
@@ -6278,18 +6327,23 @@
  */
 static int ssl_sock_get_alpn(const struct connection *conn, const char **str, int *len)
 {
+#if defined(TLSEXT_TYPE_application_layer_protocol_negotiation) || \
+	defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
+struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+#endif
+
 	if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
 		return 0;
 
 	*str = NULL;
 
 #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
-	SSL_get0_alpn_selected(conn->xprt_ctx, (const unsigned char **)str, (unsigned *)len);
+	SSL_get0_alpn_selected(ctx->ssl, (const unsigned char **)str, (unsigned *)len);
 	if (*str)
 		return 1;
 #endif
 #if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
-	SSL_get0_next_proto_negotiated(conn->xprt_ctx, (const unsigned char **)str, (unsigned *)len);
+	SSL_get0_next_proto_negotiated(ctx->ssl, (const unsigned char **)str, (unsigned *)len);
 	if (*str)
 		return 1;
 #endif
@@ -6349,10 +6403,12 @@
 	int ret = 0;
 	struct buffer *smp_trash;
 	struct connection *conn;
+	struct ssl_sock_ctx *ctx;
 
 	conn = objt_conn(smp->sess->origin);
 	if (!conn || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
 	if (!(conn->flags & CO_FL_CONNECTED)) {
 		smp->flags |= SMP_F_MAY_CHANGE;
@@ -6360,9 +6416,9 @@
 	}
 
 	if (cert_peer)
-		crt = SSL_get_peer_certificate(conn->xprt_ctx);
+		crt = SSL_get_peer_certificate(ctx->ssl);
 	else
-		crt = SSL_get_certificate(conn->xprt_ctx);
+		crt = SSL_get_certificate(ctx->ssl);
 
 	if (!crt)
 		goto out;
@@ -6393,20 +6449,23 @@
 	int ret = 0;
 	struct buffer *smp_trash;
 	struct connection *conn;
+	struct ssl_sock_ctx *ctx;
 
 	conn = objt_conn(smp->sess->origin);
 	if (!conn || conn->xprt != &ssl_sock)
 		return 0;
 
+	ctx = conn->xprt_ctx;
+
 	if (!(conn->flags & CO_FL_CONNECTED)) {
 		smp->flags |= SMP_F_MAY_CHANGE;
 		return 0;
 	}
 
 	if (cert_peer)
-		crt = SSL_get_peer_certificate(conn->xprt_ctx);
+		crt = SSL_get_peer_certificate(ctx->ssl);
 	else
-		crt = SSL_get_certificate(conn->xprt_ctx);
+		crt = SSL_get_certificate(ctx->ssl);
 
 	if (!crt)
 		goto out;
@@ -6438,10 +6497,12 @@
 	int ret = 0;
 	struct buffer *smp_trash;
 	struct connection *conn;
+	struct ssl_sock_ctx *ctx;
 
 	conn = objt_conn(smp->sess->origin);
 	if (!conn || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
 	if (!(conn->flags & CO_FL_CONNECTED)) {
 		smp->flags |= SMP_F_MAY_CHANGE;
@@ -6449,9 +6510,9 @@
 	}
 
 	if (cert_peer)
-		crt = SSL_get_peer_certificate(conn->xprt_ctx);
+		crt = SSL_get_peer_certificate(ctx->ssl);
 	else
-		crt = SSL_get_certificate(conn->xprt_ctx);
+		crt = SSL_get_certificate(ctx->ssl);
 	if (!crt)
 		goto out;
 
@@ -6482,10 +6543,12 @@
 	int ret = 0;
 	struct buffer *smp_trash;
 	struct connection *conn;
+	struct ssl_sock_ctx *ctx;
 
 	conn = objt_conn(smp->sess->origin);
 	if (!conn || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
 	if (!(conn->flags & CO_FL_CONNECTED)) {
 		smp->flags |= SMP_F_MAY_CHANGE;
@@ -6493,9 +6556,9 @@
 	}
 
 	if (cert_peer)
-		crt = SSL_get_peer_certificate(conn->xprt_ctx);
+		crt = SSL_get_peer_certificate(ctx->ssl);
 	else
-		crt = SSL_get_certificate(conn->xprt_ctx);
+		crt = SSL_get_certificate(ctx->ssl);
 	if (!crt)
 		goto out;
 
@@ -6526,10 +6589,12 @@
 	int ret = 0;
 	struct buffer *smp_trash;
 	struct connection *conn;
+	struct ssl_sock_ctx *ctx;
 
 	conn = objt_conn(smp->sess->origin);
 	if (!conn || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
 	if (!(conn->flags & CO_FL_CONNECTED)) {
 		smp->flags |= SMP_F_MAY_CHANGE;
@@ -6537,9 +6602,9 @@
 	}
 
 	if (cert_peer)
-		crt = SSL_get_peer_certificate(conn->xprt_ctx);
+		crt = SSL_get_peer_certificate(ctx->ssl);
 	else
-		crt = SSL_get_certificate(conn->xprt_ctx);
+		crt = SSL_get_certificate(ctx->ssl);
 	if (!crt)
 		goto out;
 
@@ -6582,10 +6647,12 @@
 	int ret = 0;
 	struct buffer *smp_trash;
 	struct connection *conn;
+	struct ssl_sock_ctx *ctx;
 
 	conn = objt_conn(smp->sess->origin);
 	if (!conn || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
 	if (!(conn->flags & CO_FL_CONNECTED)) {
 		smp->flags |= SMP_F_MAY_CHANGE;
@@ -6593,9 +6660,9 @@
 	}
 
 	if (cert_peer)
-		crt = SSL_get_peer_certificate(conn->xprt_ctx);
+		crt = SSL_get_peer_certificate(ctx->ssl);
 	else
-		crt = SSL_get_certificate(conn->xprt_ctx);
+		crt = SSL_get_certificate(ctx->ssl);
 	if (!crt)
 		goto out;
 
@@ -6626,10 +6693,12 @@
 	int ret = 0;
 	struct buffer *smp_trash;
 	struct connection *conn;
+	struct ssl_sock_ctx *ctx;
 
 	conn = objt_conn(smp->sess->origin);
 	if (!conn || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
 	if (!(conn->flags & CO_FL_CONNECTED)) {
 		smp->flags |= SMP_F_MAY_CHANGE;
@@ -6637,9 +6706,9 @@
 	}
 
 	if (cert_peer)
-		crt = SSL_get_peer_certificate(conn->xprt_ctx);
+		crt = SSL_get_peer_certificate(ctx->ssl);
 	else
-		crt = SSL_get_certificate(conn->xprt_ctx);
+		crt = SSL_get_certificate(ctx->ssl);
 	if (!crt)
 		goto out;
 
@@ -6676,10 +6745,12 @@
 {
 	X509 *crt;
 	struct connection *conn;
+	struct ssl_sock_ctx *ctx;
 
 	conn = objt_conn(smp->sess->origin);
 	if (!conn || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
 	if (!(conn->flags & CO_FL_CONNECTED)) {
 		smp->flags |= SMP_F_MAY_CHANGE;
@@ -6687,7 +6758,7 @@
 	}
 
 	/* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
-	crt = SSL_get_peer_certificate(conn->xprt_ctx);
+	crt = SSL_get_peer_certificate(ctx->ssl);
 	if (crt) {
 		X509_free(crt);
 	}
@@ -6707,10 +6778,12 @@
 	int cert_peer = (kw[4] == 'c') ? 1 : 0;
 	X509 *crt;
 	struct connection *conn;
+	struct ssl_sock_ctx *ctx;
 
 	conn = objt_conn(smp->sess->origin);
 	if (!conn || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
 	if (!(conn->flags & CO_FL_CONNECTED)) {
 		smp->flags |= SMP_F_MAY_CHANGE;
@@ -6718,9 +6791,9 @@
 	}
 
 	if (cert_peer)
-		crt = SSL_get_peer_certificate(conn->xprt_ctx);
+		crt = SSL_get_peer_certificate(ctx->ssl);
 	else
-		crt = SSL_get_certificate(conn->xprt_ctx);
+		crt = SSL_get_certificate(ctx->ssl);
 	if (!crt)
 		return 0;
 
@@ -6745,10 +6818,12 @@
 	__OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
 	int nid;
 	struct connection *conn;
+	struct ssl_sock_ctx *ctx;
 
 	conn = objt_conn(smp->sess->origin);
 	if (!conn || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
 	if (!(conn->flags & CO_FL_CONNECTED)) {
 		smp->flags |= SMP_F_MAY_CHANGE;
@@ -6756,9 +6831,9 @@
 	}
 
 	if (cert_peer)
-		crt = SSL_get_peer_certificate(conn->xprt_ctx);
+		crt = SSL_get_peer_certificate(ctx->ssl);
 	else
-		crt = SSL_get_certificate(conn->xprt_ctx);
+		crt = SSL_get_certificate(ctx->ssl);
 	if (!crt)
 		return 0;
 
@@ -6795,10 +6870,12 @@
 	ASN1_OBJECT *algorithm;
 	int nid;
 	struct connection *conn;
+	struct ssl_sock_ctx *ctx;
 
 	conn = objt_conn(smp->sess->origin);
 	if (!conn || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
 	if (!(conn->flags & CO_FL_CONNECTED)) {
 		smp->flags |= SMP_F_MAY_CHANGE;
@@ -6806,9 +6883,9 @@
 	}
 
 	if (cert_peer)
-		crt = SSL_get_peer_certificate(conn->xprt_ctx);
+		crt = SSL_get_peer_certificate(ctx->ssl);
 	else
-		crt = SSL_get_certificate(conn->xprt_ctx);
+		crt = SSL_get_certificate(ctx->ssl);
 	if (!crt)
 		return 0;
 
@@ -6853,11 +6930,12 @@
 {
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
 	struct connection *conn = objt_conn(smp->sess->origin);
+	struct ssl_sock_ctx *ctx = conn ? conn->xprt_ctx : NULL;
 
 	smp->data.type = SMP_T_BOOL;
 	smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
 		conn->xprt_ctx &&
-		SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
+		SSL_get_servername(ctx->ssl, TLSEXT_NAMETYPE_host_name) != NULL;
 	return 1;
 #else
 	return 0;
@@ -6873,12 +6951,13 @@
 {
 	struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
 	                                    smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+	struct ssl_sock_ctx *ctx = conn ? conn->xprt_ctx : NULL;
 
 
 	smp->data.type = SMP_T_BOOL;
 	smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
 		conn->xprt_ctx &&
-		SSL_session_reused(conn->xprt_ctx);
+		SSL_session_reused(ctx->ssl);
 	return 1;
 }
 
@@ -6891,12 +6970,14 @@
 {
 	struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
 	                                    smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+	struct ssl_sock_ctx *ctx;
 
 	smp->flags = 0;
 	if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
-	smp->data.u.str.area = (char *)SSL_get_cipher_name(conn->xprt_ctx);
+	smp->data.u.str.area = (char *)SSL_get_cipher_name(ctx->ssl);
 	if (!smp->data.u.str.area)
 		return 0;
 
@@ -6917,13 +6998,15 @@
 {
 	struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
 	                                    smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+	struct ssl_sock_ctx *ctx;
 	int sint;
 
 	smp->flags = 0;
 	if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
-	if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
+	if (!SSL_get_cipher_bits(ctx->ssl, &sint))
 		return 0;
 
 	smp->data.u.sint = sint;
@@ -6941,12 +7024,14 @@
 {
 	struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
 	                                    smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+	struct ssl_sock_ctx *ctx;
 
 	smp->flags = 0;
 	if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
-	smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
+	smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(ctx->ssl, NULL);
 	if (!smp->data.u.sint)
 		return 0;
 
@@ -6960,6 +7045,7 @@
 smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
 {
 	struct connection *conn;
+	struct ssl_sock_ctx *ctx;
 
 	smp->flags = SMP_F_CONST;
 	smp->data.type = SMP_T_STR;
@@ -6968,9 +7054,10 @@
 	    smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
 	if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
 	smp->data.u.str.area = NULL;
-	SSL_get0_next_proto_negotiated(conn->xprt_ctx,
+	SSL_get0_next_proto_negotiated(ctx->ssl,
 	                                (const unsigned char **)&smp->data.u.str.area,
 	                                (unsigned *)&smp->data.u.str.data);
 
@@ -6986,6 +7073,7 @@
 smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
 {
 	struct connection *conn;
+	struct ssl_sock_ctx *ctx;
 
 	smp->flags = SMP_F_CONST;
 	smp->data.type = SMP_T_STR;
@@ -6995,9 +7083,10 @@
 
 	if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
 	smp->data.u.str.area = NULL;
-	SSL_get0_alpn_selected(conn->xprt_ctx,
+	SSL_get0_alpn_selected(ctx->ssl,
 	                         (const unsigned char **)&smp->data.u.str.area,
 	                         (unsigned *)&smp->data.u.str.data);
 
@@ -7017,12 +7106,14 @@
 {
 	struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
 	                                    smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+	struct ssl_sock_ctx *ctx;
 
 	smp->flags = 0;
 	if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
-	smp->data.u.str.area = (char *)SSL_get_version(conn->xprt_ctx);
+	smp->data.u.str.area = (char *)SSL_get_version(ctx->ssl);
 	if (!smp->data.u.str.area)
 		return 0;
 
@@ -7044,14 +7135,16 @@
 	struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
 	                                    smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
 	SSL_SESSION *ssl_sess;
+	struct ssl_sock_ctx *ctx;
 
 	smp->flags = SMP_F_CONST;
 	smp->data.type = SMP_T_BIN;
 
 	if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
-	ssl_sess = SSL_get_session(conn->xprt_ctx);
+	ssl_sess = SSL_get_session(ctx->ssl);
 	if (!ssl_sess)
 		return 0;
 
@@ -7073,11 +7166,13 @@
 	                                    smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
 	SSL_SESSION *ssl_sess;
 	struct buffer *data;
+	struct ssl_sock_ctx *ctx;
 
 	if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
-	ssl_sess = SSL_get_session(conn->xprt_ctx);
+	ssl_sess = SSL_get_session(ctx->ssl);
 	if (!ssl_sess)
 		return 0;
 
@@ -7101,6 +7196,7 @@
 smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
 {
 	struct connection *conn;
+	struct ssl_sock_ctx *ctx;
 
 	smp->flags = SMP_F_CONST;
 	smp->data.type = SMP_T_STR;
@@ -7108,8 +7204,9 @@
 	conn = objt_conn(smp->sess->origin);
 	if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
-	smp->data.u.str.area = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
+	smp->data.u.str.area = (char *)SSL_get_servername(ctx->ssl, TLSEXT_NAMETYPE_host_name);
 	if (!smp->data.u.str.area)
 		return 0;
 
@@ -7123,12 +7220,14 @@
 {
 	struct connection *conn;
 	struct ssl_capture *capture;
+	struct ssl_sock_ctx *ctx;
 
 	conn = objt_conn(smp->sess->origin);
 	if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
-	capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
+	capture = SSL_get_ex_data(ctx->ssl, ssl_capture_ptr_index);
 	if (!capture)
 		return 0;
 
@@ -7159,12 +7258,14 @@
 {
 	struct connection *conn;
 	struct ssl_capture *capture;
+	struct ssl_sock_ctx *ctx;
 
 	conn = objt_conn(smp->sess->origin);
 	if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
-	capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
+	capture = SSL_get_ex_data(ctx->ssl, ssl_capture_ptr_index);
 	if (!capture)
 		return 0;
 
@@ -7193,7 +7294,8 @@
 		cipher = SSL_get_cipher_by_value(id);
 #else
 		struct connection *conn = __objt_conn(smp->sess->origin);
-		cipher = SSL_CIPHER_find(conn->xprt_ctx, bin);
+		struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+		cipher = SSL_CIPHER_find(ctx->ssl, bin);
 #endif
 		str = SSL_CIPHER_get_name(cipher);
 		if (!str || strcmp(str, "(NONE)") == 0)
@@ -7217,10 +7319,12 @@
 	                                    smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
 	int finished_len;
 	struct buffer *finished_trash;
+	struct ssl_sock_ctx *ctx;
 
 	smp->flags = 0;
 	if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
 		return 0;
+	ctx = conn->xprt_ctx;
 
 	if (!(conn->flags & CO_FL_CONNECTED)) {
 		smp->flags |= SMP_F_MAY_CHANGE;
@@ -7228,12 +7332,12 @@
 	}
 
 	finished_trash = get_trash_chunk();
-	if (!SSL_session_reused(conn->xprt_ctx))
-		finished_len = SSL_get_peer_finished(conn->xprt_ctx,
+	if (!SSL_session_reused(ctx->ssl))
+		finished_len = SSL_get_peer_finished(ctx->ssl,
 						     finished_trash->area,
 						     finished_trash->size);
 	else
-		finished_len = SSL_get_finished(conn->xprt_ctx,
+		finished_len = SSL_get_finished(ctx->ssl,
 						finished_trash->area,
 						finished_trash->size);
 
@@ -7319,6 +7423,7 @@
 smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
 {
 	struct connection *conn;
+	struct ssl_sock_ctx *ctx;
 
 	conn = objt_conn(smp->sess->origin);
 	if (!conn || conn->xprt != &ssl_sock)
@@ -7331,9 +7436,10 @@
 
 	if (!conn->xprt_ctx)
 		return 0;
+	ctx = conn->xprt_ctx;
 
 	smp->data.type = SMP_T_SINT;
-	smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
+	smp->data.u.sint = (long long int)SSL_get_verify_result(ctx->ssl);
 	smp->flags = 0;
 
 	return 1;