1=pod 2 3=head1 NAME 4 5BIO_sendmmsg, BIO_recvmmsg, BIO_dgram_set_local_addr_enable, 6BIO_dgram_get_local_addr_enable, BIO_dgram_get_local_addr_cap, 7BIO_err_is_non_fatal - send and receive multiple datagrams in a single call 8 9=head1 SYNOPSIS 10 11 #include <openssl/bio.h> 12 13 typedef struct bio_msg_st { 14 void *data; 15 size_t data_len; 16 BIO_ADDR *peer, *local; 17 uint64_t flags; 18 } BIO_MSG; 19 20 int BIO_sendmmsg(BIO *b, BIO_MSG *msg, 21 size_t stride, size_t num_msg, uint64_t flags, 22 size_t *msgs_processed); 23 int BIO_recvmmsg(BIO *b, BIO_MSG *msg, 24 size_t stride, size_t num_msg, uint64_t flags, 25 size_t *msgs_processed); 26 27 int BIO_dgram_set_local_addr_enable(BIO *b, int enable); 28 int BIO_dgram_get_local_addr_enable(BIO *b, int *enable); 29 int BIO_dgram_get_local_addr_cap(BIO *b); 30 int BIO_err_is_non_fatal(unsigned int errcode); 31 32=head1 DESCRIPTION 33 34BIO_sendmmsg() and BIO_recvmmsg() functions can be used to send and receive 35multiple messages in a single call to a BIO. They are analogous to sendmmsg(2) 36and recvmmsg(2) on operating systems which provide those functions. 37 38The B<BIO_MSG> structure provides a subset of the functionality of the B<struct 39msghdr> structure defined by POSIX. These functions accept an array of 40B<BIO_MSG> structures. On any particular invocation, these functions may process 41all of the passed structures, some of them, or none of them. This is indicated 42by the value stored in I<*msgs_processed>, which expresses the number of 43messages processed. 44 45The caller should set the I<data> member of a B<BIO_MSG> to a buffer containing 46the data to send, or to be filled with a received message. I<data_len> should be 47set to the size of the buffer in bytes. If the given B<BIO_MSG> is processed (in 48other words, if the integer returned by the function is greater than or equal to 49that B<BIO_MSG>'s array index), I<data_len> will be modified to specify the 50actual amount of data sent or received. 51 52The I<flags> field of a B<BIO_MSG> provides input per-message flags to the 53invocation. If the invocation processes that B<BIO_MSG>, the I<flags> field is 54written with output per-message flags, or zero if no such flags are applicable. 55 56Currently, no input or output per-message flags are defined and this field 57should be set to zero before calling BIO_sendmmsg() or BIO_recvmmsg(). 58 59The I<flags> argument to BIO_sendmmsg() and BIO_recvmmsg() provides global 60flags which affect the entire invocation. No global flags are currently 61defined and this argument should be set to zero. 62 63When these functions are used to send and receive datagrams, the I<peer> field 64of a B<BIO_MSG> allows the destination address of sent datagrams to be specified 65on a per-datagram basis, and the source address of received datagrams to be 66determined. The I<peer> field should be set to point to a B<BIO_ADDR>, which 67will be read by BIO_sendmmsg() and used as the destination address for sent 68datagrams, and written by BIO_recvmmsg() with the source address of received 69datagrams. 70 71Similarly, the I<local> field of a B<BIO_MSG> allows the source address of sent 72datagrams to be specified on a per-datagram basis, and the destination address 73of received datagrams to be determined. Unlike I<peer>, support for I<local> 74must be explicitly enabled on a B<BIO> before it can be used; see 75BIO_dgram_set_local_addr_enable(). If I<local> is non-NULL in a B<BIO_MSG> and 76support for I<local> has not been enabled, processing of that B<BIO_MSG> fails. 77 78I<peer> and I<local> should be set to NULL if they are not required. Support for 79I<local> may not be available on all platforms; on these platforms, these 80functions always fail if I<local> is non-NULL. 81 82If I<local> is specified and local address support is enabled, but the operating 83system does not report a local address for a specific received message, the 84B<BIO_ADDR> it points to will be cleared (address family set to C<AF_UNSPEC>). 85This is known to happen on Windows when a packet is received which was sent by 86the local system, regardless of whether the packet's destination address was the 87loopback address or the IP address of a local non-loopback interface. This is 88also known to happen on macOS in some circumstances, such as for packets sent 89before local address support was enabled for a receiving socket. These are 90OS-specific limitations. As such, users of this API using local address support 91should expect to sometimes receive a cleared local B<BIO_ADDR> instead of the 92correct value. 93 94The I<stride> argument must be set to C<sizeof(BIO_MSG)>. This argument 95facilitates backwards compatibility if fields are added to B<BIO_MSG>. Callers 96must zero-initialize B<BIO_MSG>. 97 98I<num_msg> should be sent to the maximum number of messages to send or receive, 99which is also the length of the array pointed to by I<msg>. 100 101I<msgs_processed> must be non-NULL and points to an integer written with the 102number of messages successfully processed; see the RETURN VALUES section for 103further discussion. 104 105Unlike most BIO functions, these functions explicitly support multi-threaded 106use. Multiple concurrent writers and multiple concurrent readers of the same BIO 107are permitted in any combination. As such, these functions do not clear, set, or 108otherwise modify BIO retry flags. The return value must be used to determine 109whether an operation should be retried; see below. 110 111The support for concurrent use extends to BIO_sendmmsg() and BIO_recvmmsg() 112only, and no other function may be called on a given BIO while any call to 113BIO_sendmmsg() or BIO_recvmmsg() is in progress, or vice versa. 114 115BIO_dgram_set_local_addr_enable() and BIO_dgram_get_local_addr_enable() control 116whether local address support is enabled. To enable local address support, call 117BIO_dgram_set_local_addr_enable() with an argument of 1. The call will fail if 118local address support is not available for the platform. 119BIO_dgram_get_local_addr_enable() retrieves the value set by 120BIO_dgram_set_local_addr_enable(). 121 122BIO_dgram_get_local_addr_cap() determines if the B<BIO> is capable of supporting 123local addresses. 124 125BIO_err_is_non_fatal() determines if a packed error code represents an error 126which is transient in nature. 127 128=head1 NOTES 129 130Some implementations of the BIO_sendmmsg() and BIO_recvmmsg() BIO methods might 131always process at most one message at a time, for example when OS-level 132functionality to transmit or receive multiple messages at a time is not 133available. 134 135=head1 RETURN VALUES 136 137On success, the functions BIO_sendmmsg() and BIO_recvmmsg() return 1 and write 138the number of messages successfully processed (which need not be nonzero) to 139I<msgs_processed>. Where a positive value n is written to I<msgs_processed>, all 140entries in the B<BIO_MSG> array from 0 through n-1 inclusive have their 141I<data_len> and I<flags> fields updated with the results of the operation on 142that message. If the call was to BIO_recvmmsg() and the I<peer> or I<local> 143fields of that message are non-NULL, the B<BIO_ADDR> structures they point to 144are written with the relevant address. 145 146On failure, the functions BIO_sendmmsg() and BIO_recvmmsg() return 0 and write 147zero to I<msgs_processed>. Thus I<msgs_processed> is always written regardless 148of the outcome of the function call. 149 150If BIO_sendmmsg() and BIO_recvmmsg() fail, they always raise an B<ERR_LIB_BIO> 151error using L<ERR_raise(3)>. Any error may be raised, but the following in 152particular may be noted: 153 154=over 2 155 156=item B<BIO_R_LOCAL_ADDR_NOT_AVAILABLE> 157 158The I<local> field was set to a non-NULL value, but local address support is not 159available or not enabled on the BIO. 160 161=item B<BIO_R_PEER_ADDR_NOT_AVAILABLE> 162 163The I<peer> field was set to a non-NULL value, but peer address support is not 164available on the BIO. 165 166=item B<BIO_R_UNSUPPORTED_METHOD> 167 168The BIO_sendmmsg() or BIO_recvmmsg() method is not supported on the BIO. 169 170=item B<BIO_R_NON_FATAL> 171 172The call failed due to a transient, non-fatal error (for example, because the 173BIO is in nonblocking mode and the call would otherwise have blocked). 174 175Implementations of this interface which do not make system calls and thereby 176pass through system error codes using B<ERR_LIB_SYS> (for example, memory-based 177implementations) should issue this reason code to indicate a transient failure. 178However, users of this interface should not test for this reason code directly, 179as there are multiple possible packed error codes representing a transient 180failure; use BIO_err_is_non_fatal() instead (discussed below). 181 182=item Socket errors 183 184OS-level socket errors are reported using an error with library code 185B<ERR_LIB_SYS>; for a packed error code B<errcode> where 186C<ERR_SYSTEM_ERROR(errcode) == 1>, the OS-level socket error code can be 187retrieved using C<ERR_GET_REASON(errcode)>. The packed error code can be 188retrieved by calling L<ERR_peek_last_error(3)> after the call to BIO_sendmmsg() 189or BIO_recvmmsg() returns 0. 190 191=item Non-fatal errors 192 193Whether an error is transient can be determined by passing the packed error code 194to BIO_err_is_non_fatal(). Callers should do this instead of testing the reason 195code directly, as there are many possible error codes which can indicate a 196transient error, many of which are system specific. 197 198=back 199 200Third parties implementing custom BIOs supporting the BIO_sendmmsg() or 201BIO_recvmmsg() methods should note that it is a required part of the API 202contract that an error is always raised when either of these functions return 0. 203 204BIO_dgram_set_local_addr_enable() returns 1 if local address support was 205successfully enabled or disabled and 0 otherwise. 206 207BIO_dgram_get_local_addr_enable() returns 1 if the local address support enable 208flag was successfully retrieved. 209 210BIO_dgram_get_local_addr_cap() returns 1 if the B<BIO> can support local 211addresses. 212 213BIO_err_is_non_fatal() returns 1 if the passed packed error code represents an 214error which is transient in nature. 215 216=head1 HISTORY 217 218These functions were added in OpenSSL 3.2. 219 220=head1 COPYRIGHT 221 222Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. 223 224Licensed under the Apache License 2.0 (the "License"). You may not use 225this file except in compliance with the License. You can obtain a copy 226in the file LICENSE in the source distribution or at 227L<https://www.openssl.org/source/license.html>. 228 229=cut 230