diff options
Diffstat (limited to '')
-rw-r--r-- | tls_bio_cb.c | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/tls_bio_cb.c b/tls_bio_cb.c index 8adbf55..9dd435a 100644 --- a/tls_bio_cb.c +++ b/tls_bio_cb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_bio_cb.c,v 1.19 2017/01/12 16:18:39 jsing Exp $ */ +/* $OpenBSD: tls_bio_cb.c,v 1.20 2022/01/10 23:39:48 tb Exp $ */ /* * Copyright (c) 2016 Tobias Pape <tobias@netshed.de> * @@ -32,26 +32,39 @@ static long bio_cb_ctrl(BIO *bio, int cmd, long num, void *ptr); static BIO_METHOD *bio_cb_method; -static pthread_once_t bio_cb_init_once = PTHREAD_ONCE_INIT; +static pthread_mutex_t bio_cb_method_lock = PTHREAD_MUTEX_INITIALIZER; static void -bio_s_cb_init(void) +bio_cb_method_init(void) { - bio_cb_method = BIO_meth_new(BIO_TYPE_MEM, "libtls_callbacks"); - if (bio_cb_method == NULL) + BIO_METHOD *bio_method; + + if (bio_cb_method != NULL) + return; + + bio_method = BIO_meth_new(BIO_TYPE_MEM, "libtls_callbacks"); + if (bio_method == NULL) return; - BIO_meth_set_write(bio_cb_method, bio_cb_write); - BIO_meth_set_read(bio_cb_method, bio_cb_read); - BIO_meth_set_puts(bio_cb_method, bio_cb_puts); - BIO_meth_set_ctrl(bio_cb_method, bio_cb_ctrl); + BIO_meth_set_write(bio_method, bio_cb_write); + BIO_meth_set_read(bio_method, bio_cb_read); + BIO_meth_set_puts(bio_method, bio_cb_puts); + BIO_meth_set_ctrl(bio_method, bio_cb_ctrl); + + bio_cb_method = bio_method; } static BIO_METHOD * bio_s_cb(void) { - pthread_once(&bio_cb_init_once, bio_s_cb_init); - return bio_cb_method; + if (bio_cb_method != NULL) + return (bio_cb_method); + + pthread_mutex_lock(&bio_cb_method_lock); + bio_cb_method_init(); + pthread_mutex_unlock(&bio_cb_method_lock); + + return (bio_cb_method); } static int @@ -125,8 +138,9 @@ int tls_set_cbs(struct tls *ctx, tls_read_cb read_cb, tls_write_cb write_cb, void *cb_arg) { - int rv = -1; + const BIO_METHOD *bio_cb; BIO *bio; + int rv = -1; if (read_cb == NULL || write_cb == NULL) { tls_set_errorx(ctx, "no callbacks provided"); @@ -137,7 +151,11 @@ tls_set_cbs(struct tls *ctx, tls_read_cb read_cb, tls_write_cb write_cb, ctx->write_cb = write_cb; ctx->cb_arg = cb_arg; - if ((bio = BIO_new(bio_s_cb())) == NULL) { + if ((bio_cb = bio_s_cb()) == NULL) { + tls_set_errorx(ctx, "failed to create callback method"); + goto err; + } + if ((bio = BIO_new(bio_cb)) == NULL) { tls_set_errorx(ctx, "failed to create callback i/o"); goto err; } |