BIO_SENDMMSG(3ossl)
okay bestie, welcome to BIO_SENDMMSG(3ossl), straight from OpenSSL π β¨. Itβs giving βsend and receive multiple datagrams in a single call,β and honestly? iconic. Letβs unpack it together, no cap.
π 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.
β¨ SYNOPSIS β¨
Copy these exactly, bestie β character for character:
#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);
π¦ DESCRIPTION π¦
BIO_sendmmsg() and BIO_recvmmsg() are the functions that let you send and receive multiple messages in a single call to a BIO. Theyβre analogous to sendmmsg(2) and recvmmsg(2) on operating systems that provide those functions. Think βbatch mode, but make it datagramsβ β¨
The BIO_MSG structure gives you a subset of the functionality of the struct msghdr structure defined by POSIX. These functions accept an array of BIO_MSG structures. On any particular invocation, they may process all of the passed structures, some of them, or none of them. Thatβs indicated by the value stored in *msgs_processed, which expresses the number of messages processed.
Hereβs the little field-by-field vibe check π
dataβ set this to a buffer containing the data to send, or to be filled with a received message.data_lenβ set this to the size of the buffer in bytes. If the givenBIO_MSGis processed (in other words, if the integer returned by the function is greater than or equal to thatBIO_MSGβs array index),data_lenwill be modified to specify the actual amount of data sent or received.flagsβ this field provides input per-message flags to the invocation. If the invocation processes thatBIO_MSG, theflagsfield 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 callingBIO_sendmmsg()orBIO_recvmmsg().peerβ when these functions are used to send and receive datagrams, this lets the destination address of sent datagrams be specified on a per-datagram basis, and the source address of received datagrams be determined. Set it to point to aBIO_ADDR:BIO_sendmmsg()reads it as the destination address for sent datagrams, andBIO_recvmmsg()writes it with the source address of received datagrams.localβ similarly, this lets the source address of sent datagrams be specified on a per-datagram basis, and the destination address of received datagrams be determined. Unlikepeer, support forlocalmust be explicitly enabled on a BIO before it can be used; seeBIO_dgram_set_local_addr_enable(). Iflocalis non-NULLin aBIO_MSGand support forlocalhas not been enabled, processing of thatBIO_MSGfails.
peer and local should be set to NULL if they are not required. Support for local may not be available on all platforms; on these platforms, these functions always fail if local is non-NULL.
If 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 BIO_ADDR it points to will be cleared (address family set to "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 BIO_ADDR instead of the correct value.
π«Ά real talk: that cleared-BIO_ADDR moment is an OS-specific limitation, not you being bad at Unix. Itβs just sometimes what the platform gives you.
The 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.
The stride argument must be set to sizeof(BIO_MSG). This argument facilitates backwards compatibility if fields are added to BIO_MSG. Callers must zero-initialize BIO_MSG.
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 msg.
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 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.
π 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.
π 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 msgs_processed. Where a positive value n is written to msgs_processed, all entries in the BIO_MSG array from 0 through n-1 inclusive have their data_len and flags fields updated with the results of the operation on that message. If the call was to BIO_recvmmsg() and the peer or local fields of that message are non-NULL, the 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 msgs_processed. Thus msgs_processed is always written regardless of the outcome of the function call.
If BIO_sendmmsg() and BIO_recvmmsg() fail, they always raise an ERR_LIB_BIO error using ERR_raise(3). Any error may be raised, but the following in particular may be noted:
BIO_R_LOCAL_ADDR_NOT_AVAILABLEβ Thelocalfield was set to a non-NULLvalue, but local address support is not available or not enabled on the BIO.BIO_R_PEER_ADDR_NOT_AVAILABLEβ Thepeerfield was set to a non-NULLvalue, but peer address support is not available on the BIO.BIO_R_UNSUPPORTED_METHODβ TheBIO_sendmmsg()orBIO_recvmmsg()method is not supported on the BIO.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 usingERR_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; useBIO_err_is_non_fatal()instead (discussed below).- Socket errors β OS-level socket errors are reported using an error with library code
ERR_LIB_SYS; for a packed error codeerrcodewhereERR_SYSTEM_ERROR(errcode) == 1, the OS-level socket error code can be retrieved usingERR_GET_REASON(errcode). The packed error code can be retrieved by callingERR_peek_last_error(3)after the call toBIO_sendmmsg()orBIO_recvmmsg()returns0. - 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.
Third parties implementing custom BIOs supporting the BIO_sendmmsg() or BIO_recvmmsg() methods should note that it is a required part of the API contract that an error is always raised when either of these functions return 0.
BIO_dgram_set_local_addr_enable()returns1if local address support was successfully enabled or disabled and0otherwise.BIO_dgram_get_local_addr_enable()returns1if the local address support enable flag was successfully retrieved.BIO_dgram_get_local_addr_cap()returns1if the BIO can support local addresses.BIO_err_is_non_fatal()returns1if the passed packed error code represents an error which is transient in nature.
πΈ HISTORY πΈ
These functions were added in OpenSSL 3.2.
π COPYRIGHT π
Copyright 2000-2023 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 <https://www.openssl.org/source/license.html>.
β¨ source/version vibes: OpenSSL 3.5.0, dated 2026-09-25 β this was the BIO_SENDMMSG(3ossl) page. Bye bestie, go process those messages π
π«Άπ
π¦ where this page comes from
- opensuse-leap 16.0: openssl-3-doc 3.5.0-160000.11.1 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms