Skip to content

Commit bc6ec0a

Browse files
committed
Fix SSL context refcount
1 parent 92bb165 commit bc6ec0a

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

include/cat_ssl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ typedef struct cat_ssl_s {
199199
cat_buffer_t write_buffer;
200200
/* options */
201201
cat_bool_t allow_self_signed;
202+
/* internals */
203+
cat_ssl_context_t *context; // for free data before SSL_free()
202204
} cat_ssl_t;
203205

204206
typedef enum cat_ssl_ret_e {

src/cat_ssl.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,9 +230,8 @@ CAT_API cat_ssl_context_t *cat_ssl_context_create(cat_ssl_method_t method, cat_s
230230
return NULL;
231231
}
232232

233-
CAT_API void cat_ssl_context_close(cat_ssl_context_t *context)
233+
static cat_always_inline void cat_ssl_context_close_data(cat_ssl_context_t *context)
234234
{
235-
SSL_CTX_free(context->ctx);
236235
if (CAT_REF_DEL(context) != 0) {
237236
return;
238237
}
@@ -241,6 +240,12 @@ CAT_API void cat_ssl_context_close(cat_ssl_context_t *context)
241240
cat_free(context);
242241
}
243242

243+
CAT_API void cat_ssl_context_close(cat_ssl_context_t *context)
244+
{
245+
SSL_CTX_free(context->ctx);
246+
cat_ssl_context_close_data(context);
247+
}
248+
244249
CAT_API void cat_ssl_context_set_protocols(cat_ssl_context_t *context, cat_ssl_protocols_t protocols)
245250
{
246251
cat_ssl_ctx_t *ctx = context->ctx;
@@ -697,6 +702,7 @@ CAT_API cat_ssl_t *cat_ssl_create(cat_ssl_t *ssl, cat_ssl_context_t *context)
697702
cat_ssl_update_last_error(CAT_ESSL, "SSL_new() failed");
698703
goto _new_failed;
699704
}
705+
CAT_REF_ADD(context);
700706

701707
/* malloc for SSL handle */
702708
if (ssl == NULL) {
@@ -736,6 +742,7 @@ CAT_API cat_ssl_t *cat_ssl_create(cat_ssl_t *ssl, cat_ssl_context_t *context)
736742

737743
/* init ssl fields */
738744
ssl->connection = connection;
745+
ssl->context = context;
739746
ssl->allow_self_signed = cat_false;
740747

741748
return ssl;
@@ -745,8 +752,11 @@ CAT_API cat_ssl_t *cat_ssl_create(cat_ssl_t *ssl, cat_ssl_context_t *context)
745752
BIO_free(ssl->nbio);
746753
_set_ex_data_failed:
747754
_new_bio_pair_failed:
755+
CAT_REF_DEL(context);
756+
/* When context can be passed as a parameter,
757+
* its reference count must be greater than or equal to 1. */
758+
CAT_ASSERT(CAT_REF_GET(context) >= 1);
748759
SSL_free(connection);
749-
ssl->connection = NULL;
750760
#if CAT_ALLOC_HANDLE_ERRORS
751761
_malloc_failed:
752762
#endif
@@ -763,6 +773,7 @@ CAT_API void cat_ssl_close(cat_ssl_t *ssl)
763773
cat_buffer_close(&ssl->read_buffer);
764774
/* ibio will be free'd by SSL_free */
765775
BIO_free(ssl->nbio);
776+
cat_ssl_context_close_data(ssl->context);
766777
/* implicitly frees internal_bio */
767778
SSL_free(ssl->connection);
768779
/* free */

0 commit comments

Comments
 (0)