Hi again,
of course i forgot to attach the patch...
Kind regards,
Julian
diff --git a/include/types/ssl_sock.h b/include/types/ssl_sock.h
index 2e02631c..76073f37 100644
--- a/include/types/ssl_sock.h
+++ b/include/types/ssl_sock.h
@@ -71,4 +71,14 @@ struct sh_ssl_sess_hdr {
unsigned char key_data[SSL_MAX_SSL_SESSION_ID_LENGTH];
};
+/* shared ssl ctx */
+struct shared_ssl_ctx {
+ struct list list; /* Used to chain refs. */
+ char *path;
+SSL_CTX *ctx;
+ int refcount; /* number of users of this shared_ssl_ctx. */
+ __decl_hathreads(HA_RWLOCK_T lock); /* lock used to protect the ref */
+enum { loaded, prepared } state;
+};
+
#endif /* _TYPES_SSL_SOCK_H */
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index d26ee789..823eda69 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -330,6 +330,7 @@ const char *SSL_SOCK_KEYTYPE_NAMES[] = {
static struct shared_context *ssl_shctx = NULL; /* ssl shared session cache */
static struct eb_root *sh_ssl_sess_tree; /* ssl shared session tree */
+static struct list shared_ssl_ctx_list = LIST_HEAD_INIT(shared_ssl_ctx_list); /* list of shared ssl ctxs */
#define sh_ssl_sess_tree_delete(s) ebmb_delete(&(s)->key);
@@ -910,6 +911,27 @@ int ssl_sock_update_tlskey(char *filename, struct buffer *tlskey, char **err)
return 0;
}
+
+struct shared_ssl_ctx *shared_ssl_ctx_lookup_name(const char* path)
+{
+struct shared_ssl_ctx *ss_ctx;
+
+list_for_each_entry(ss_ctx, _ssl_ctx_list, list)
+if (ss_ctx->path && strcmp(path, ss_ctx->path) == 0)
+return ss_ctx;
+return NULL;
+}
+
+struct shared_ssl_ctx *shared_ssl_ctx_lookup_ctx(SSL_CTX *ctx)
+{
+struct shared_ssl_ctx *ss_ctx;
+
+list_for_each_entry(ss_ctx, _ssl_ctx_list, list)
+if (ss_ctx->ctx && ctx == ss_ctx->ctx)
+return ss_ctx;
+return NULL;
+}
+
/* This function finalize the configuration parsing. Its set all the
* automatic ids. It's called just after the basic checks. It returns
* 0 on success otherwise ERR_*.
@@ -3322,20 +3344,30 @@ static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf
{
int ret;
SSL_CTX *ctx;
-
- ctx = SSL_CTX_new(SSLv23_server_method());
- if (!ctx) {
- memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
- err && *err ? *err : "", path);
- return 1;
- }
-
- if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
- memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
- err && *err ? *err : "", path);
- SSL_CTX_free(ctx);
- return 1;
- }
+struct shared_ssl_ctx *ss_ctx;
+
+ ss_ctx = shared_ssl_ctx_lookup_name(path);
+if(ss_ctx /* FIXME cfg */ ) {
+ ss_ctx->refcount++; /* FIXME lock needed? */
+ss_ctx->state = loaded;
+ctx = ss_ctx->ctx;
+}
+
+if(!ss_ctx) {
+ctx = SSL_CTX_new(SSLv23_server_method());
+if (!ctx) {
+memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
+ err && *err ? *err : "", path);
+return 1;
+}
+
+if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
+memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
+ err && *err ? *err : "", path);
+SSL_CTX_free(ctx);
+return 1;
+}
+}
ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, ssl_conf, sni_filter, fcount);
if (ret <= 0) {
@@ -3346,54 +3378,73 @@ static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf
return 1;
}
- if (SSL_CTX_check_private_key(ctx) <= 0) {
+ if (!ss_ctx && SSL_CTX_check_private_key(ctx) <= 0) {
memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
err && *err ? *err : "", path);
return 1;
}
- /* we must not free the SSL_CTX anymore below, since it's already in
- * the tree, so it will be discovered and cleaned in time.
- */
+if(!ss_ctx) {
+/* we must not free the SSL_CTX anymore below, since it's already in
+ * the tree, so it will be discovered and cleaned in time.
+ */
#ifndef OPENSSL_NO_DH
- /* store a NULL pointer to indicate we have not yet loaded
- a custom DH param file */
- if (ssl_dh_ptr_index >= 0) {
- SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
- }
+/* store a NULL pointer to indicate we have not yet loaded
+ a custom DH param file */
+if (ssl_dh_ptr_index >= 0) {
+SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
+}
- ret = ssl_sock_load_dh_params(ctx, path);
- if (ret < 0) {
- if (err)
- memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
- *err ? *err : "", path);
- return 1;
- }
+ret = ssl_sock_load_dh_params(ctx, path);
+if (ret < 0) {
+if (err)
+memprintf(err,