BIO_SHOULD_RETRY(3ossl)

πŸ’– BIO_SHOULD_RETRY πŸ’–

okay bestie, welcome to BIO_SHOULD_RETRY(3ossl) β€” that's the OpenSSL manual, section 3, and this page is entirely about the BIO retry functions. if your read or write just flopped and you're sitting there like "why tho 😭", this is your page. let's get into it. πŸ¦‹


✨ NAME ✨

BIO_should_read, BIO_should_write, BIO_should_io_special, BIO_retry_type, BIO_should_retry, BIO_get_retry_BIO, BIO_get_retry_reason, BIO_set_retry_reason β€” the BIO retry functions, aka the "so... should we try that again?" squad πŸ’…


✨ SYNOPSIS ✨

#include <openssl/bio.h>

int BIO_should_read(BIO *b);
int BIO_should_write(BIO *b);
int BIO_should_io_special(iBIO *b);
int BIO_retry_type(BIO *b);
int BIO_should_retry(BIO *b);

BIO *BIO_get_retry_BIO(BIO *bio, int *reason);
int BIO_get_retry_reason(BIO *bio);
void BIO_set_retry_reason(BIO *bio, int reason);
not me side-eyeing that iBIO *b in BIO_should_io_special β€” that's literally what the original says, so we're keeping it exactly as-is, no editing, periodt. πŸ‘‘

✨ DESCRIPTION ✨

so these functions are the ones that tell you why a BIO couldn't read or write data. you'd normally call them right after a BIO_read_ex() or BIO_write_ex() call failed. it's giving detective energy. πŸ”

BIO_should_retry() is true if the call that caused this whole situation should just... be tried again later. lowkey the chillest option.

but if BIO_should_retry() is false? bestie that's not a retry, that's an error condition. 😭

BIO_should_read() is true when the cause is that the BIO doesn't have enough data to return. so: check for readability and/or retry the last operation.

BIO_should_write() is true when the cause is that the BIO has pending data it still needs to write. so: check for writability and/or retry the last operation.

BIO_should_io_special() is true when some "special" condition is the cause β€” meaning it's a reason that's not reading and not writing. it's the mysterious one. πŸ™ˆ

BIO_retry_type() returns a mask of what caused the retry condition, made up of the values BIO_FLAGS_READ, BIO_FLAGS_WRITE, BIO_FLAGS_IO_SPECIAL β€” though heads up, current BIO types will only set one of these.

BIO_get_retry_BIO() figures out the precise reason for the special condition: it returns the BIO that caused the condition, and if reason is not NULL, it'll hold the reason code. what that reason code means, and what you're supposed to do about it, depends on the type of BIO that caused it. iykyk. πŸ’…

BIO_get_retry_reason() gives you the reason for a special condition, as long as you hand it the relevant BIO β€” for example, the one you got back from BIO_get_retry_BIO().

BIO_set_retry_reason() sets the retry reason for a special condition on a given BIO. ngl, this is usually only called by BIO implementations themselves. that's their job, not yours. 🫢


✨ NOTES ✨

so BIO_should_read(), BIO_should_write(), BIO_should_io_special(), BIO_retry_type(), and BIO_should_retry() are all implemented as macros. ✨

if BIO_should_retry() comes back false, then the exact "error condition" depends on the BIO type that caused it and the return code of the BIO operation. for example: if a call to BIO_read_ex() on a socket BIO returns 0 and BIO_should_retry() is false, then the cause is that the connection closed. a similar situation on a file BIO means it hit EOF. some BIO types may drop extra info onto the error queue. for the full tea, go read the individual BIO type manual pages. πŸ“

if the underlying I/O structure is in blocking mode, almost all current BIO types won't request a retry, because the underlying I/O calls won't either. and if your application already knows the BIO type will never signal a retry, it doesn't need to call BIO_should_retry() after a failed BIO I/O call at all. this is typically what happens with file BIOs.

SSL BIOs are the only current exception to that rule: they can request a retry even when the underlying I/O structure is blocking, if a handshake happens during a call to BIO_read(). your app can either retry the failed call immediately, or dodge the whole situation by setting SSL_MODE_AUTO_RETRY on the underlying SSL structure. slay. πŸ’–

now β€” an application may retry a failed non blocking call immediately, but bestie that's likely to be very inefficient, because the call will just fail over and over until data can be processed or becomes available. an application will normally wait until the necessary condition is satisfied. how you do that depends on the underlying I/O structure.

for example: if the cause is ultimately a socket and BIO_should_read() is true, then you can call select() to wait until data is available, and then retry the BIO operation. and by combining the retry conditions of several non blocking BIOs into a single select() call, you can service several BIOs in a single thread β€” though performance may be poor if SSL BIOs are present, because long delays can occur during the initial handshake process. 😬

also, it is possible for a BIO to block indefinitely if the underlying I/O structure can't process or return any data. this depends on the behaviour of the platform's I/O functions. and that's often not what you want: one solution is to use non blocking I/O and put a timeout on the select() (or equivalent) call. ⏰


✨ BUGS ✨

the OpenSSL ASN1 functions cannot gracefully deal with non blocking I/O β€” that is, they cannot retry after a partial read or write. πŸ’€

the usual workaround is to only pass the relevant data to ASN1 functions when the entire structure can be read or written. no partial sends, no chaos. πŸ™ˆ


✨ RETURN VALUES ✨

  • BIO_should_read(), BIO_should_write(), BIO_should_io_special(), and BIO_should_retry() return either 1 or 0, based on the actual conditions of the BIO. ⭐
  • BIO_retry_type() returns a flag combination showing the cause of a retry condition, or false if there's no retry condition at all.
  • BIO_get_retry_BIO() returns a valid BIO structure.
  • BIO_get_retry_reason() returns the reason for a special condition.

✨ SEE ALSO ✨

bio(7) β€” go read it, bestie, it's the whole vibe. 🌈


✨ HISTORY ✨

the BIO_get_retry_reason() and BIO_set_retry_reason() functions were added in OpenSSL 1.1.0. glow-up era. πŸ‘‘


Copyright 2000-2018 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>.


and that's the whole page, gorgeous. πŸ’œ this was BIO_SHOULD_RETRY(3ossl) from the OpenSSL manual, version 3.5.9, dated 2026-09-29 β€” mwah, go retry something responsibly. πŸŽ€βœ¨

πŸ“¦ where this page comes from