From: Timo Sirainen Date: Tue, 31 Oct 2017 16:41:47 +0000 (+0200) Subject: lib-ssl-iostream: Add refcounting to ssl_iostream_context X-Git-Tag: 2.3.0.rc1~538 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=96359599bbd4a2d704c3f343ff4c2fcd03f0dd02;p=thirdparty%2Fdovecot%2Fcore.git lib-ssl-iostream: Add refcounting to ssl_iostream_context --- diff --git a/src/lib-ssl-iostream/iostream-openssl-context.c b/src/lib-ssl-iostream/iostream-openssl-context.c index 1a2df3a3b6..940aebb44e 100644 --- a/src/lib-ssl-iostream/iostream-openssl-context.c +++ b/src/lib-ssl-iostream/iostream-openssl-context.c @@ -586,6 +586,7 @@ int openssl_iostream_context_init_client(const struct ssl_iostream_settings *set SSL_CTX_set_mode(ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); ctx = i_new(struct ssl_iostream_context, 1); + ctx->refcount = 1; ctx->ssl_ctx = ssl_ctx; ctx->client_ctx = TRUE; if (ssl_iostream_context_init_common(ctx, &set_copy, error_r) < 0) { @@ -612,6 +613,7 @@ int openssl_iostream_context_init_server(const struct ssl_iostream_settings *set } ctx = i_new(struct ssl_iostream_context, 1); + ctx->refcount = 1; ctx->ssl_ctx = ssl_ctx; if (ssl_iostream_context_init_common(ctx, set, error_r) < 0) { ssl_iostream_context_unref(&ctx); @@ -621,8 +623,18 @@ int openssl_iostream_context_init_server(const struct ssl_iostream_settings *set return 0; } -void openssl_iostream_context_deinit(struct ssl_iostream_context *ctx) +void openssl_iostream_context_ref(struct ssl_iostream_context *ctx) { + i_assert(ctx->refcount > 0); + ctx->refcount++; +} + +void openssl_iostream_context_unref(struct ssl_iostream_context *ctx) +{ + i_assert(ctx->refcount > 0); + if (--ctx->refcount > 0) + return; + SSL_CTX_free(ctx->ssl_ctx); pool_unref(&ctx->pool); i_free(ctx); diff --git a/src/lib-ssl-iostream/iostream-openssl.c b/src/lib-ssl-iostream/iostream-openssl.c index 73f22d16ee..37af544129 100644 --- a/src/lib-ssl-iostream/iostream-openssl.c +++ b/src/lib-ssl-iostream/iostream-openssl.c @@ -776,7 +776,8 @@ openssl_iostream_get_last_error(struct ssl_iostream *ssl_io) static const struct iostream_ssl_vfuncs ssl_vfuncs = { .context_init_client = openssl_iostream_context_init_client, .context_init_server = openssl_iostream_context_init_server, - .context_deinit = openssl_iostream_context_deinit, + .context_ref = openssl_iostream_context_ref, + .context_unref = openssl_iostream_context_unref, .create = openssl_iostream_create, .unref = openssl_iostream_unref, diff --git a/src/lib-ssl-iostream/iostream-openssl.h b/src/lib-ssl-iostream/iostream-openssl.h index 5849b48c50..65a70d9bc4 100644 --- a/src/lib-ssl-iostream/iostream-openssl.h +++ b/src/lib-ssl-iostream/iostream-openssl.h @@ -16,6 +16,7 @@ enum openssl_iostream_sync_type { }; struct ssl_iostream_context { + int refcount; SSL_CTX *ssl_ctx; pool_t pool; @@ -75,7 +76,8 @@ int openssl_iostream_context_init_client(const struct ssl_iostream_settings *set int openssl_iostream_context_init_server(const struct ssl_iostream_settings *set, struct ssl_iostream_context **ctx_r, const char **error_r); -void openssl_iostream_context_deinit(struct ssl_iostream_context *ctx); +void openssl_iostream_context_ref(struct ssl_iostream_context *ctx); +void openssl_iostream_context_unref(struct ssl_iostream_context *ctx); void openssl_iostream_global_deinit(void); int openssl_iostream_load_key(const struct ssl_iostream_cert *set, diff --git a/src/lib-ssl-iostream/iostream-ssl-private.h b/src/lib-ssl-iostream/iostream-ssl-private.h index 2995381ac4..2972b38ac8 100644 --- a/src/lib-ssl-iostream/iostream-ssl-private.h +++ b/src/lib-ssl-iostream/iostream-ssl-private.h @@ -10,7 +10,8 @@ struct iostream_ssl_vfuncs { int (*context_init_server)(const struct ssl_iostream_settings *set, struct ssl_iostream_context **ctx_r, const char **error_r); - void (*context_deinit)(struct ssl_iostream_context *ctx); + void (*context_ref)(struct ssl_iostream_context *ctx); + void (*context_unref)(struct ssl_iostream_context *ctx); int (*create)(struct ssl_iostream_context *ctx, const char *host, const struct ssl_iostream_settings *set, diff --git a/src/lib-ssl-iostream/iostream-ssl.c b/src/lib-ssl-iostream/iostream-ssl.c index e4485ec4e3..343f1daa9f 100644 --- a/src/lib-ssl-iostream/iostream-ssl.c +++ b/src/lib-ssl-iostream/iostream-ssl.c @@ -98,12 +98,17 @@ int ssl_iostream_context_init_server(const struct ssl_iostream_settings *set, return ssl_vfuncs->context_init_server(set, ctx_r, error_r); } +void ssl_iostream_context_ref(struct ssl_iostream_context *ctx) +{ + ssl_vfuncs->context_ref(ctx); +} + void ssl_iostream_context_unref(struct ssl_iostream_context **_ctx) { struct ssl_iostream_context *ctx = *_ctx; *_ctx = NULL; - ssl_vfuncs->context_deinit(ctx); + ssl_vfuncs->context_unref(ctx); } int io_stream_create_ssl_client(struct ssl_iostream_context *ctx, const char *host, diff --git a/src/lib-ssl-iostream/iostream-ssl.h b/src/lib-ssl-iostream/iostream-ssl.h index 531bf05262..255495f1dc 100644 --- a/src/lib-ssl-iostream/iostream-ssl.h +++ b/src/lib-ssl-iostream/iostream-ssl.h @@ -92,6 +92,7 @@ int ssl_iostream_context_init_client(const struct ssl_iostream_settings *set, int ssl_iostream_context_init_server(const struct ssl_iostream_settings *set, struct ssl_iostream_context **ctx_r, const char **error_r); +void ssl_iostream_context_ref(struct ssl_iostream_context *ctx); void ssl_iostream_context_unref(struct ssl_iostream_context **ctx); /* FIXME: temporarily for backwards compatibility, remove later */ #define ssl_iostream_context_deinit(ctx) ssl_iostream_context_unref(ctx)