diff options
Diffstat (limited to 'crypto/bio/bio_lib.c')
-rw-r--r-- | crypto/bio/bio_lib.c | 142 |
1 files changed, 119 insertions, 23 deletions
diff --git a/crypto/bio/bio_lib.c b/crypto/bio/bio_lib.c index 245a75afa1b8..85ab4afe182a 100644 --- a/crypto/bio/bio_lib.c +++ b/crypto/bio/bio_lib.c @@ -82,30 +82,22 @@ BIO *BIO_new_ex(OSSL_LIB_CTX *libctx, const BIO_METHOD *method) { BIO *bio = OPENSSL_zalloc(sizeof(*bio)); - if (bio == NULL) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); + if (bio == NULL) return NULL; - } bio->libctx = libctx; bio->method = method; bio->shutdown = 1; - bio->references = 1; - if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data)) + if (!CRYPTO_NEW_REF(&bio->references, 1)) goto err; - bio->lock = CRYPTO_THREAD_lock_new(); - if (bio->lock == NULL) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data); + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data)) goto err; - } if (method->create != NULL && !method->create(bio)) { ERR_raise(ERR_LIB_BIO, ERR_R_INIT_FAIL); CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data); - CRYPTO_THREAD_lock_free(bio->lock); goto err; } if (method->create == NULL) @@ -114,6 +106,7 @@ BIO *BIO_new_ex(OSSL_LIB_CTX *libctx, const BIO_METHOD *method) return bio; err: + CRYPTO_FREE_REF(&bio->references); OPENSSL_free(bio); return NULL; } @@ -130,10 +123,10 @@ int BIO_free(BIO *a) if (a == NULL) return 0; - if (CRYPTO_DOWN_REF(&a->references, &ret, a->lock) <= 0) + if (CRYPTO_DOWN_REF(&a->references, &ret) <= 0) return 0; - REF_PRINT_COUNT("BIO", a); + REF_PRINT_COUNT("BIO", ret, a); if (ret > 0) return 1; REF_ASSERT_ISNT(ret < 0); @@ -149,7 +142,7 @@ int BIO_free(BIO *a) CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data); - CRYPTO_THREAD_lock_free(a->lock); + CRYPTO_FREE_REF(&a->references); OPENSSL_free(a); @@ -195,10 +188,10 @@ int BIO_up_ref(BIO *a) { int i; - if (CRYPTO_UP_REF(&a->references, &i, a->lock) <= 0) + if (CRYPTO_UP_REF(&a->references, &i) <= 0) return 0; - REF_PRINT_COUNT("BIO", a); + REF_PRINT_COUNT("BIO", i, a); REF_ASSERT_ISNT(i < 2); return i > 1; } @@ -398,6 +391,110 @@ int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written) || (b != NULL && dlen == 0); /* order is important for *written */ } +int BIO_sendmmsg(BIO *b, BIO_MSG *msg, + size_t stride, size_t num_msg, uint64_t flags, + size_t *msgs_processed) +{ + size_t ret; + BIO_MMSG_CB_ARGS args; + + if (b == NULL) { + *msgs_processed = 0; + ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (b->method == NULL || b->method->bsendmmsg == NULL) { + *msgs_processed = 0; + ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD); + return 0; + } + + if (HAS_CALLBACK(b)) { + args.msg = msg; + args.stride = stride; + args.num_msg = num_msg; + args.flags = flags; + args.msgs_processed = msgs_processed; + + ret = (size_t)bio_call_callback(b, BIO_CB_SENDMMSG, (void *)&args, + 0, 0, 0, 1, NULL); + if (ret <= 0) + return 0; + } + + if (!b->init) { + *msgs_processed = 0; + ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED); + return 0; + } + + ret = b->method->bsendmmsg(b, msg, stride, num_msg, flags, msgs_processed); + + if (HAS_CALLBACK(b)) + ret = (size_t)bio_call_callback(b, BIO_CB_SENDMMSG | BIO_CB_RETURN, + (void *)&args, ret, 0, 0, ret, NULL); + + return ret; +} + +int BIO_recvmmsg(BIO *b, BIO_MSG *msg, + size_t stride, size_t num_msg, uint64_t flags, + size_t *msgs_processed) +{ + size_t ret; + BIO_MMSG_CB_ARGS args; + + if (b == NULL) { + *msgs_processed = 0; + ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (b->method == NULL || b->method->brecvmmsg == NULL) { + *msgs_processed = 0; + ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD); + return 0; + } + + if (HAS_CALLBACK(b)) { + args.msg = msg; + args.stride = stride; + args.num_msg = num_msg; + args.flags = flags; + args.msgs_processed = msgs_processed; + + ret = bio_call_callback(b, BIO_CB_RECVMMSG, (void *)&args, + 0, 0, 0, 1, NULL); + if (ret <= 0) + return 0; + } + + if (!b->init) { + *msgs_processed = 0; + ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED); + return 0; + } + + ret = b->method->brecvmmsg(b, msg, stride, num_msg, flags, msgs_processed); + + if (HAS_CALLBACK(b)) + ret = (size_t)bio_call_callback(b, BIO_CB_RECVMMSG | BIO_CB_RETURN, + (void *)&args, ret, 0, 0, ret, NULL); + + return ret; +} + +int BIO_get_rpoll_descriptor(BIO *b, BIO_POLL_DESCRIPTOR *desc) +{ + return BIO_ctrl(b, BIO_CTRL_GET_RPOLL_DESCRIPTOR, 0, desc); +} + +int BIO_get_wpoll_descriptor(BIO *b, BIO_POLL_DESCRIPTOR *desc) +{ + return BIO_ctrl(b, BIO_CTRL_GET_WPOLL_DESCRIPTOR, 0, desc); +} + int BIO_puts(BIO *b, const char *buf) { int ret; @@ -720,7 +817,7 @@ BIO *BIO_find_type(BIO *bio, int type) ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER); return NULL; } - mask = type & 0xff; + mask = type & BIO_TYPE_MASK; do { if (bio->method != NULL) { mt = bio->method->type; @@ -756,7 +853,7 @@ void BIO_free_all(BIO *bio) while (bio != NULL) { b = bio; - ref = b->references; + CRYPTO_GET_REF(&b->references, &ref); bio = bio->next_bio; BIO_free(b); /* Since ref count > 1, don't free anyone else. */ @@ -853,11 +950,10 @@ void bio_cleanup(void) CRYPTO_THREAD_lock_free(bio_lookup_lock); bio_lookup_lock = NULL; #endif - CRYPTO_THREAD_lock_free(bio_type_lock); - bio_type_lock = NULL; + CRYPTO_FREE_REF(&bio_type_count); } -/* Internal variant of the below BIO_wait() not calling BIOerr() */ +/* Internal variant of the below BIO_wait() not calling ERR_raise(...) */ static int bio_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds) { #ifndef OPENSSL_NO_SOCK @@ -890,7 +986,7 @@ static int bio_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds) if ((unsigned long)sec_diff * 1000 < nap_milliseconds) nap_milliseconds = (unsigned int)sec_diff * 1000; } - ossl_sleep(nap_milliseconds); + OSSL_sleep(nap_milliseconds); return 1; } @@ -899,7 +995,7 @@ static int bio_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds) * Succeed immediately if max_time == 0. * If sockets are not available support polling: succeed after waiting at most * the number of nap_milliseconds in order to avoid a tight busy loop. - * Call BIOerr(...) on timeout or error. + * Call ERR_raise(ERR_LIB_BIO, ...) on timeout or error. * Returns -1 on error, 0 on timeout, and 1 on success. */ int BIO_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds) |