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)
This commit is contained in:
Hugo Landau 2022-08-01 10:33:00 +01:00
parent 709d4be78f
commit e0c4e43e40
12 changed files with 476 additions and 8 deletions

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -671,6 +671,10 @@ DEPEND[html/man3/BIO_s_socket.html]=man3/BIO_s_socket.pod
GENERATE[html/man3/BIO_s_socket.html]=man3/BIO_s_socket.pod
DEPEND[man/man3/BIO_s_socket.3]=man3/BIO_s_socket.pod
GENERATE[man/man3/BIO_s_socket.3]=man3/BIO_s_socket.pod
DEPEND[html/man3/BIO_sendmmsg.html]=man3/BIO_sendmmsg.pod
GENERATE[html/man3/BIO_sendmmsg.html]=man3/BIO_sendmmsg.pod
DEPEND[man/man3/BIO_sendmmsg.3]=man3/BIO_sendmmsg.pod
GENERATE[man/man3/BIO_sendmmsg.3]=man3/BIO_sendmmsg.pod
DEPEND[html/man3/BIO_set_callback.html]=man3/BIO_set_callback.pod
GENERATE[html/man3/BIO_set_callback.html]=man3/BIO_set_callback.pod
DEPEND[man/man3/BIO_set_callback.3]=man3/BIO_set_callback.pod
@ -2907,6 +2911,7 @@ html/man3/BIO_s_file.html \
html/man3/BIO_s_mem.html \
html/man3/BIO_s_null.html \
html/man3/BIO_s_socket.html \
html/man3/BIO_sendmmsg.html \
html/man3/BIO_set_callback.html \
html/man3/BIO_should_retry.html \
html/man3/BIO_socket_wait.html \
@ -3504,6 +3509,7 @@ man/man3/BIO_s_file.3 \
man/man3/BIO_s_mem.3 \
man/man3/BIO_s_null.3 \
man/man3/BIO_s_socket.3 \
man/man3/BIO_sendmmsg.3 \
man/man3/BIO_set_callback.3 \
man/man3/BIO_should_retry.3 \
man/man3/BIO_socket_wait.3 \

View File

@ -9,7 +9,8 @@ BIO_meth_set_write, BIO_meth_get_read, BIO_meth_set_read, BIO_meth_get_puts,
BIO_meth_set_puts, BIO_meth_get_gets, BIO_meth_set_gets, BIO_meth_get_ctrl,
BIO_meth_set_ctrl, BIO_meth_get_create, BIO_meth_set_create,
BIO_meth_get_destroy, BIO_meth_set_destroy, BIO_meth_get_callback_ctrl,
BIO_meth_set_callback_ctrl - Routines to build up BIO methods
BIO_meth_set_callback_ctrl, BIO_meth_set_sendmmsg, BIO_meth_get_sendmmsg,
BIO_meth_set_recvmmsg, BIO_meth_get_recvmmsg - Routines to build up BIO methods
=head1 SYNOPSIS
@ -56,6 +57,25 @@ BIO_meth_set_callback_ctrl - Routines to build up BIO methods
int BIO_meth_set_callback_ctrl(BIO_METHOD *biom,
long (*callback_ctrl)(BIO *, int, BIO_info_cb *));
ossl_ssize_t (*BIO_meth_get_sendmmsg(const BIO_METHOD *biom))(BIO *,
BIO_MSG *,
size_t,
size_t,
uint64_t);
int BIO_meth_set_sendmmsg(BIO_METHOD *biom,
ossl_ssize_t (*f) (BIO *, BIO_MSG *, size_t,
size_t, uint64_t));
ossl_ssize_t (*BIO_meth_get_recvmmsg(const BIO_METHOD *biom))(BIO *,
BIO_MSG *,
size_t,
size_t,
uint64_t);
int BIO_meth_set_recvmmsg(BIO_METHOD *biom,
ossl_ssize_t (*f) (BIO *, BIO_MSG *, size_t,
size_t, uint64_t));
=head1 DESCRIPTION
The B<BIO_METHOD> type is a structure used for the implementation of new BIO
@ -136,6 +156,11 @@ the L<BIO_callback_ctrl(3)> page for more information. This function will be cal
in response to the application calling BIO_callback_ctrl(). The parameters for
the function have the same meaning as for BIO_callback_ctrl().
BIO_meth_get_sendmmsg(), BIO_meth_set_sendmmsg(), BIO_meth_get_recvmmsg() and
BIO_meth_set_recvmmsg() get and set the functions used for handling
BIO_sendmmsg() and BIO_recvmmsg() calls respectively. See L<BIO_sendmmsg(3)> for
more information.
=head1 RETURN VALUES
BIO_get_new_index() returns the new BIO type value or -1 if an error occurred.

220
doc/man3/BIO_sendmmsg.pod Normal file
View File

@ -0,0 +1,220 @@
=pod
=head1 NAME
BIO_sendmmsg, BIO_recvmmsg, BIO_dgram_set_local_addr_enable,
BIO_dgram_get_local_addr_enable, BIO_dgram_get_local_addr_cap,
BIO_err_is_non_fatal - send and receive multiple datagrams in a single call
=head1 SYNOPSIS
#include <openssl/bio.h>
typedef struct bio_msg_st {
void *data;
size_t data_len;
BIO_ADDR *peer, *local;
uint64_t flags;
} BIO_MSG;
int BIO_sendmmsg(BIO *b, BIO_MSG *msg,
size_t stride, size_t num_msg, uint64_t flags,
size_t *msgs_processed);
int BIO_recvmmsg(BIO *b, BIO_MSG *msg,
size_t stride, size_t num_msg, uint64_t flags,
size_t *msgs_processed);
int BIO_dgram_set_local_addr_enable(BIO *b, int enable);
int BIO_dgram_get_local_addr_enable(BIO *b, int *enable);
int BIO_dgram_get_local_addr_cap(BIO *b);
int BIO_err_is_non_fatal(unsigned int errcode);
=head1 DESCRIPTION
BIO_sendmmsg() and BIO_recvmmsg() functions can be used to send and receive
multiple messages in a single call to a BIO. They are analagous to sendmmsg(2)
and recvmmsg(2) on operating systems which provide those functions.
The B<BIO_MSG> structure provides a subset of the functionality of the B<struct
msghdr> structure defined by POSIX. These functions accept an array of
B<BIO_MSG> structures. On any particular invocation, these functions may process
all of the passed structures, some of them, or none of them. This is indicated
by the value stored in I<*msgs_processed>, which expresses the number of
messages processed.
The caller should set the I<data> member of a B<BIO_MSG> to a buffer containing
the data to send, or to be filled with a received message. I<data_len> should be
set to the size of the buffer in bytes. If the given B<BIO_MSG> is processed (in
other words, if the integer returned by the function is greater than or equal to
that B<BIO_MSG>'s array index), I<data_len> will be modified to specify the
actual amount of data sent or received.
The I<flags> field of a B<BIO_MSG> provides input per-message flags to the
invocation. If the invocation processes that B<BIO_MSG>, the I<flags> field is
written with output per-message flags, or zero if no such flags are applicable.
Currently, no input or output per-message flags are defined and this field
should be set to zero before calling BIO_sendmmsg() or BIO_recvmmsg().
The I<flags> argument to BIO_sendmmsg() and BIO_recvmmsg() provides global
flags which affect the entire invocation. No global flags are currently
defined and this argument should be set to zero.
When these functions are used to send and receive datagrams, the I<peer> field
of a B<BIO_MSG> allows the destination address of sent datagrams to be specified
on a per-datagram basis, and the source address of received datagrams to be
determined. The I<peer> field should be set to point to a B<BIO_ADDR>, which
will be read by BIO_sendmmsg() and used as the destination address for sent
datagrams, and written by BIO_recvmmsg() with the source address of received
datagrams.
Similarly, the I<local> field of a B<BIO_MSG> allows the source address of sent
datagrams to be specified on a per-datagram basis, and the destination address
of received datagrams to be determined. Unlike I<peer>, support for I<local>
must be explicitly enabled on a B<BIO> before it can be used; see
BIO_dgram_set_local_addr_enable(). If I<local> is non-NULL in a B<BIO_MSG> and
support for I<local> has not been enabled, processing of that B<BIO_MSG> fails.
I<peer> and I<local> should be set to NULL if they are not required. Support for
I<local> may not be available on all platforms; on these platforms, these
functions always fail if I<local> is non-NULL.
If I<local> is specified and local address support is enabled, but the operating
system does not report a local address for a specific received message, the
B<BIO_ADDR> it points to will be cleared (address family set to C<AF_UNSPEC>).
This is known to happen on Windows when a packet is received which was sent by
the local system, regardless of whether the packet's destination address was the
loopback address or the IP address of a local non-loopback interface. This is
also known to happen on macOS in some circumstances, such as for packets sent
before local address support was enabled for a receiving socket. These are
OS-specific limitations. As such, users of this API using local address support
should expect to sometimes receive a cleared local B<BIO_ADDR> instead of the
correct value.
The I<stride> argument must be set to C<sizeof(BIO_MSG)>. This argument
facilitates backwards compatibility if fields are added to B<BIO_MSG>. Callers
must zero-initialize B<BIO_MSG>.
I<num_msg> should be sent to the maximum number of messages to send or receive,
which is also the length of the array pointed to by I<msg>.
I<msgs_processed> must be non-NULL and points to an integer written with the
number of messages successfully processed; see the RETURN VALUES section for
further discussion.
Unlike most BIO functions, these functions explicitly support multi-threaded
use. Multiple concurrent writers and multiple concurrent readers of the same BIO
are permitted in any combination. As such, these functions do not clear, set, or
otherwise modify BIO retry flags. The return value must be used to determine
whether an operation should be retried; see below.
The support for concurrent use extends to BIO_sendmmsg() and BIO_recvmmsg()
only, and no other function may be called on a given BIO while any call to
BIO_sendmmsg() or BIO_recvmmsg() is in progress, or vice versa.
BIO_dgram_set_local_addr_enable() and BIO_dgram_get_local_addr_enable() control
whether local address support is enabled. To enable local address support, call
BIO_dgram_set_local_addr_enable() with an argument of 1. The call will fail if
local address support is not available for the platform.
BIO_dgram_get_local_addr_enable() retrieves the value set by
BIO_dgram_set_local_addr_enable().
BIO_dgram_get_local_addr_cap() determines if the B<BIO> is capable of supporting
local addresses.
BIO_err_is_non_fatal() determines if a packed error code represents an error
which is transient in nature.
=head1 NOTES
Some implementations of the BIO_sendmmsg() and BIO_recvmmsg() BIO methods might
always process at most one message at a time, for example when OS-level
functionality to transmit or receive multiple messages at a time is not
available.
=head1 RETURN VALUES
On success, the functions BIO_sendmmsg() and BIO_recvmmsg() return 1 and write
the number of messages successfully processed (which need not be nonzero) to
I<msgs_processed>. Where a positive value n is written to I<msgs_processed>, all
entries in the B<BIO_MSG> array from 0 through n-1 inclusive have their
I<data_len> and I<flags> fields updated with the results of the operation on
that message. If the call was to BIO_recvmmsg() and the I<peer> or I<local>
fields of that message are non-NULL, the B<BIO_ADDR> structures they point to
are written with the relevant address.
On failure, the functions BIO_sendmmsg() and BIO_recvmmsg() return 0 and write
zero to I<msgs_processed>. Thus I<msgs_processed> is always written regardless
of the outcome of the function call.
If BIO_sendmmsg() and BIO_recvmmsg() fail, they always raise an B<ERR_LIB_BIO>
error using L<ERR_raise(3)>. Any error may be raised, but the following in
particular may be noted:
=over 2
=item B<BIO_R_LOCAL_ADDR_NOT_AVAILABLE>
The I<local> field was set to a non-NULL value, but local address support is not
available or not enabled on the BIO.
=item B<BIO_R_UNSUPPORTED_METHOD>
The BIO_sendmmsg() or BIO_recvmmsg() method is not supported on the BIO.
=item B<BIO_R_NON_FATAL>
The call failed due to a transient, non-fatal error (for example, because the
BIO is in nonblocking mode and the call would otherwise have blocked).
Implementations of this interface which do not make system calls and thereby
pass through system error codes using B<ERR_LIB_SYS> (for example, memory-based
implementations) should issue this reason code to indicate a transient failure.
However, users of this interface should not test for this reason code directly,
as there are multiple possible packed error codes representing a transient
failure; use BIO_err_is_non_fatal() instead (discussed below).
=item Socket errors
OS-level socket errors are reported using an error with library code
B<ERR_LIB_SYS>; for a packed error code B<errcode> where
C<ERR_SYSTEM_ERROR(errcode) == 1>, the OS-level socket error code can be
retrieved using C<ERR_GET_REASON(errcode)>. The packed error code can be
retrieved by calling L<ERR_peek_last_error(3)> after the call to BIO_sendmmsg()
or BIO_recvmmsg() returns 0.
=item Non-fatal errors
Whether an error is transient can be determined by passing the packed error code
to BIO_err_is_non_fatal(). Callers should do this instead of testing the reason
code directly, as there are many possible error codes which can indicate a
transient error, many of which are system specific.
=back
BIO_dgram_set_local_addr_enable() returns 1 if local address support was
successfully enabled or disabled and 0 otherwise.
BIO_dgram_get_local_addr_enable() returns 1 if the local address support enable
flag was successfully retrieved.
BIO_dgram_get_local_addr_cap() returns 1 if the B<BIO> can support local
addresses.
BIO_err_is_non_fatal() returns 1 if the passed packed error code represents an
error which is transient in nature.
=head1 HISTORY
These functions were added in OpenSSL 3.1.
=head1 COPYRIGHT
Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View File

@ -27,6 +27,8 @@ struct bio_method_st {
int (*create) (BIO *);
int (*destroy) (BIO *);
long (*callback_ctrl) (BIO *, int, BIO_info_cb *);
int (*bsendmmsg) (BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *);
int (*brecvmmsg) (BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *);
};
void bio_free_ex_data(BIO *bio);

View File

@ -172,6 +172,10 @@ extern "C" {
# define BIO_CTRL_SET_INDENT 80
# define BIO_CTRL_GET_INDENT 81
# define BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP 82
# define BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE 83
# define BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE 84
# ifndef OPENSSL_NO_KTLS
# define BIO_get_ktls_send(b) \
(BIO_ctrl(b, BIO_CTRL_GET_KTLS_SEND, 0, NULL) > 0)
@ -257,12 +261,14 @@ void BIO_clear_flags(BIO *b, int flags);
# define BIO_RR_ACCEPT 0x03
/* These are passed by the BIO callback */
# define BIO_CB_FREE 0x01
# define BIO_CB_READ 0x02
# define BIO_CB_WRITE 0x03
# define BIO_CB_PUTS 0x04
# define BIO_CB_GETS 0x05
# define BIO_CB_CTRL 0x06
# define BIO_CB_FREE 0x01
# define BIO_CB_READ 0x02
# define BIO_CB_WRITE 0x03
# define BIO_CB_PUTS 0x04
# define BIO_CB_GETS 0x05
# define BIO_CB_CTRL 0x06
# define BIO_CB_RECVMMSG 0x07
# define BIO_CB_SENDMMSG 0x08
/*
* The callback is called before and after the underling operation, The
@ -339,6 +345,21 @@ struct bio_dgram_sctp_prinfo {
};
# endif
/* BIO_sendmmsg/BIO_recvmmsg-related definitions */
typedef struct bio_msg_st {
void *data;
size_t data_len;
BIO_ADDR *peer, *local;
uint64_t flags;
} BIO_MSG;
typedef struct bio_mmsg_cb_args_st {
BIO_MSG *msg;
size_t stride, num_msg;
uint64_t flags;
size_t *msgs_processed;
} BIO_MMSG_CB_ARGS;
/*
* #define BIO_CONN_get_param_hostname BIO_ctrl
*/
@ -580,6 +601,12 @@ int BIO_ctrl_reset_read_request(BIO *b);
(int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)(peer))
# define BIO_dgram_get_mtu_overhead(b) \
(unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL)
# define BIO_dgram_get_local_addr_cap(b) \
(int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP, 0, NULL)
# define BIO_dgram_get_local_addr_enable(b, penable) \
(int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE, 0, (char *)(penable))
# define BIO_dgram_set_local_addr_enable(b, enable) \
(int)BIO_ctrl((b), BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE, (enable), NULL)
/* ctrl macros for BIO_f_prefix */
# define BIO_set_prefix(b,p) BIO_ctrl((b), BIO_CTRL_SET_PREFIX, 0, (void *)(p))
@ -622,10 +649,16 @@ void BIO_vfree(BIO *a);
int BIO_up_ref(BIO *a);
int BIO_read(BIO *b, void *data, int dlen);
int BIO_read_ex(BIO *b, void *data, size_t dlen, size_t *readbytes);
__owur int BIO_recvmmsg(BIO *b, BIO_MSG *msg,
size_t stride, size_t num_msg, uint64_t flags,
size_t *msgs_processed);
int BIO_gets(BIO *bp, char *buf, int size);
int BIO_get_line(BIO *bio, char *buf, int size);
int BIO_write(BIO *b, const void *data, int dlen);
int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written);
__owur int BIO_sendmmsg(BIO *b, BIO_MSG *msg,
size_t stride, size_t num_msg, uint64_t flags,
size_t *msgs_processed);
int BIO_puts(BIO *bp, const char *buf);
int BIO_indent(BIO *b, int indent, int max);
long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg);
@ -687,6 +720,7 @@ int BIO_dgram_sctp_msg_waiting(BIO *b);
# ifndef OPENSSL_NO_SOCK
int BIO_sock_should_retry(int i);
int BIO_sock_non_fatal_error(int error);
int BIO_err_is_non_fatal(unsigned int errcode);
int BIO_socket_wait(int fd, int for_read, time_t max_time);
# endif
int BIO_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds);
@ -840,12 +874,24 @@ int BIO_meth_set_write(BIO_METHOD *biom,
int (*write) (BIO *, const char *, int));
int BIO_meth_set_write_ex(BIO_METHOD *biom,
int (*bwrite) (BIO *, const char *, size_t, size_t *));
int BIO_meth_set_sendmmsg(BIO_METHOD *biom,
int (*f) (BIO *, BIO_MSG *, size_t, size_t,
uint64_t, size_t *));
int (*BIO_meth_get_sendmmsg(const BIO_METHOD *biom))(BIO *, BIO_MSG *,
size_t, size_t,
uint64_t, size_t *);
int (*BIO_meth_get_read(const BIO_METHOD *biom)) (BIO *, char *, int);
int (*BIO_meth_get_read_ex(const BIO_METHOD *biom)) (BIO *, char *, size_t, size_t *);
int BIO_meth_set_read(BIO_METHOD *biom,
int (*read) (BIO *, char *, int));
int BIO_meth_set_read_ex(BIO_METHOD *biom,
int (*bread) (BIO *, char *, size_t, size_t *));
int BIO_meth_set_recvmmsg(BIO_METHOD *biom,
int (*f) (BIO *, BIO_MSG *, size_t, size_t,
uint64_t, size_t *));
int (*BIO_meth_get_recvmmsg(const BIO_METHOD *biom))(BIO *, BIO_MSG *,
size_t, size_t,
uint64_t, size_t *);
int (*BIO_meth_get_puts(const BIO_METHOD *biom)) (BIO *, const char *);
int BIO_meth_set_puts(BIO_METHOD *biom,
int (*puts) (BIO *, const char *));

View File

@ -64,5 +64,7 @@
# define BIO_R_UNSUPPORTED_PROTOCOL_FAMILY 131
# define BIO_R_WRITE_TO_READ_ONLY_BIO 126
# define BIO_R_WSASTARTUP 122
# define BIO_R_LOCAL_ADDR_NOT_AVAILABLE 148
# define BIO_R_NON_FATAL 149
#endif

View File

@ -5448,3 +5448,10 @@ CMS_SignedData_verify ? 3_1_0 EXIST::FUNCTION:CMS
OPENSSL_strcasecmp ? 3_0_3 EXIST::FUNCTION:
OPENSSL_strncasecmp ? 3_0_3 EXIST::FUNCTION:
BIO_s_dgram_mem ? 3_1_0 EXIST::FUNCTION:
BIO_recvmmsg ? 3_1_0 EXIST::FUNCTION:
BIO_sendmmsg ? 3_1_0 EXIST::FUNCTION:
BIO_meth_set_sendmmsg ? 3_1_0 EXIST::FUNCTION:
BIO_meth_get_sendmmsg ? 3_1_0 EXIST::FUNCTION:
BIO_meth_set_recvmmsg ? 3_1_0 EXIST::FUNCTION:
BIO_meth_get_recvmmsg ? 3_1_0 EXIST::FUNCTION:
BIO_err_is_non_fatal ? 3_1_0 EXIST::FUNCTION:SOCK

View File

@ -141,8 +141,13 @@ ASYNC_stack_alloc_fn datatype
ASYNC_stack_free_fn datatype
#
ASN1_BIT_STRING_digest define
BIO_IS_ERRNO define
BIO_UNPACK_ERRNO define
BIO_append_filename define
BIO_destroy_bio_pair define
BIO_dgram_get_local_addr_cap define
BIO_dgram_get_local_addr_enable define
BIO_dgram_set_local_addr_enable define
BIO_do_accept define
BIO_do_connect define
BIO_do_handshake define