summaryrefslogtreecommitdiffstats
path: root/crypto/bio
diff options
context:
space:
mode:
authorHugo Landau <hlandau@openssl.org>2022-08-01 10:33:00 +0100
committerHugo Landau <hlandau@openssl.org>2022-08-19 09:01:30 +0100
commite0c4e43e40390e44614d14817e34b47e1c17d630 (patch)
tree7448a600dab52bff8359fcb6b10d29d796cf185f /crypto/bio
parent709d4be78f64a8ba0707fb5682b90039e848dad4 (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.c22
-rw-r--r--crypto/bio/bio_err.c19
-rw-r--r--crypto/bio/bio_lib.c94
-rw-r--r--crypto/bio/bio_meth.c22
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;
+}