diff options
author | Hugo Landau <hlandau@openssl.org> | 2022-08-01 10:33:00 +0100 |
---|---|---|
committer | Hugo Landau <hlandau@openssl.org> | 2022-08-19 09:01:30 +0100 |
commit | e0c4e43e40390e44614d14817e34b47e1c17d630 (patch) | |
tree | 7448a600dab52bff8359fcb6b10d29d796cf185f /crypto/bio | |
parent | 709d4be78f64a8ba0707fb5682b90039e848dad4 (diff) |
BIO_sendmmsg/BIO_recvmmsg (API only)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18923)
Diffstat (limited to 'crypto/bio')
-rw-r--r-- | crypto/bio/bio_cb.c | 22 | ||||
-rw-r--r-- | crypto/bio/bio_err.c | 19 | ||||
-rw-r--r-- | crypto/bio/bio_lib.c | 94 | ||||
-rw-r--r-- | crypto/bio/bio_meth.c | 22 |
4 files changed, 156 insertions, 1 deletions
diff --git a/crypto/bio/bio_cb.c b/crypto/bio/bio_cb.c index 522a05369d..8e4f79ea3c 100644 --- a/crypto/bio/bio_cb.c +++ b/crypto/bio/bio_cb.c @@ -24,6 +24,8 @@ long BIO_debug_callback_ex(BIO *bio, int cmd, const char *argp, size_t len, char *p; int left; size_t l = 0; + BIO_MMSG_CB_ARGS *args; + long ret_ = ret; if (processed != NULL) l = *processed; @@ -69,6 +71,16 @@ long BIO_debug_callback_ex(BIO *bio, int cmd, const char *argp, size_t len, BIO_snprintf(p, left, "ctrl(%d) - %s\n", argi, bio->method->name); break; + case BIO_CB_RECVMMSG: + args = (BIO_MMSG_CB_ARGS *)argp; + BIO_snprintf(p, left, "recvmmsg(%zu) - %s", + args->num_msg, bio->method->name); + break; + case BIO_CB_SENDMMSG: + args = (BIO_MMSG_CB_ARGS *)argp; + BIO_snprintf(p, left, "sendmmsg(%zu) - %s", + args->num_msg, bio->method->name); + break; case BIO_CB_RETURN | BIO_CB_READ: BIO_snprintf(p, left, "read return %d processed: %zu\n", ret, l); break; @@ -84,6 +96,14 @@ long BIO_debug_callback_ex(BIO *bio, int cmd, const char *argp, size_t len, case BIO_CB_RETURN | BIO_CB_CTRL: BIO_snprintf(p, left, "ctrl return %d\n", ret); break; + case BIO_CB_RETURN | BIO_CB_RECVMMSG: + BIO_snprintf(p, left, "recvmmsg processed: %zu\n", len); + ret_ = (long)len; + break; + case BIO_CB_RETURN | BIO_CB_SENDMMSG: + BIO_snprintf(p, left, "sendmmsg processed: %zu\n", len); + ret_ = (long)len; + break; default: BIO_snprintf(p, left, "bio callback - unknown type (%d)\n", cmd); break; @@ -96,7 +116,7 @@ long BIO_debug_callback_ex(BIO *bio, int cmd, const char *argp, size_t len, else fputs(buf, stderr); #endif - return ret; + return ret_; } #ifndef OPENSSL_NO_DEPRECATED_3_0 diff --git a/crypto/bio/bio_err.c b/crypto/bio/bio_err.c index 466280b647..87a744ec49 100644 --- a/crypto/bio/bio_err.c +++ b/crypto/bio/bio_err.c @@ -75,6 +75,10 @@ static const ERR_STRING_DATA BIO_str_reasons[] = { {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_WRITE_TO_READ_ONLY_BIO), "write to read only BIO"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_WSASTARTUP), "WSAStartup"}, + {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_LOCAL_ADDR_NOT_AVAILABLE), + "local address not available"}, + {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NON_FATAL), + "non-fatal or transient error"}, {0, NULL} }; @@ -88,3 +92,18 @@ int ossl_err_load_BIO_strings(void) #endif return 1; } + +#ifndef OPENSSL_NO_SOCK + +int BIO_err_is_non_fatal(unsigned int errcode) +{ + if (ERR_SYSTEM_ERROR(errcode)) + return BIO_sock_non_fatal_error(ERR_GET_REASON(errcode)); + else if (ERR_GET_LIB(errcode) == ERR_LIB_BIO + && ERR_GET_REASON(errcode) == BIO_R_NON_FATAL) + return 1; + else + return 0; +} + +#endif diff --git a/crypto/bio/bio_lib.c b/crypto/bio/bio_lib.c index b5454f14b2..f6d40b2d1c 100644 --- a/crypto/bio/bio_lib.c +++ b/crypto/bio/bio_lib.c @@ -397,6 +397,100 @@ 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, 0, 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, 0, 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, 0, 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, 0, NULL); + + return ret; +} + int BIO_puts(BIO *b, const char *buf) { int ret; diff --git a/crypto/bio/bio_meth.c b/crypto/bio/bio_meth.c index 469715ba09..3865d82f0e 100644 --- a/crypto/bio/bio_meth.c +++ b/crypto/bio/bio_meth.c @@ -218,3 +218,25 @@ int BIO_meth_set_callback_ctrl(BIO_METHOD *biom, biom->callback_ctrl = callback_ctrl; return 1; } + +int BIO_meth_set_sendmmsg(BIO_METHOD *biom, + int (*bsendmmsg) (BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *)) +{ + biom->bsendmmsg = bsendmmsg; + return 1; +} + +int (*BIO_meth_get_sendmmsg(const BIO_METHOD *biom))(BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *) { + return biom->bsendmmsg; +} + +int BIO_meth_set_recvmmsg(BIO_METHOD *biom, + int (*brecvmmsg) (BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *)) +{ + biom->brecvmmsg = brecvmmsg; + return 1; +} + +int (*BIO_meth_get_recvmmsg(const BIO_METHOD *biom))(BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *) { + return biom->brecvmmsg; +} |