BIO_CTRL(3)
πΈ NAME πΈ
BIO_ctrl, BIO_callback_ctrl, BIO_ptr_ctrl, BIO_int_ctrl, BIO_reset, BIO_seek, BIO_tell, BIO_flush, BIO_eof, BIO_set_close, BIO_get_close, BIO_pending, BIO_wpending, BIO_ctrl_pending, BIO_ctrl_wpending, BIO_get_info_callback, BIO_set_info_callback, BIO_info_cb, bio_info_cb β bestie, these are the BIO control operations π
Ok so real talk, this is the <openssl/bio.h> girlies' whole control-operation situation, and we're gonna go through it together, no gatekeeping β¨
π¦ SYNOPSIS π¦
#include <openssl/bio.h>
long
BIO_ctrl(BIO *b, int cmd, long larg, void *parg);
long
BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *cb);
char *
BIO_ptr_ctrl(BIO *b, int cmd, long larg);
long
BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg);
int
BIO_reset(BIO *b);
int
BIO_seek(BIO *b, int ofs);
int
BIO_tell(BIO *b);
int
BIO_flush(BIO *b);
int
BIO_eof(BIO *b);
int
BIO_set_close(BIO *b, long flag);
int
BIO_get_close(BIO *b);
int
BIO_pending(BIO *b);
int
BIO_wpending(BIO *b);
size_t
BIO_ctrl_pending(BIO *b);
size_t
BIO_ctrl_wpending(BIO *b);
int
BIO_get_info_callback(BIO *b, BIO_info_cb **cbp);
int
BIO_set_info_callback(BIO *b, BIO_info_cb *cb);
typedef int
BIO_info_cb(BIO *b, int state, int res);
typedef int
bio_info_cb(BIO *b, int state, int res);
π DESCRIPTION π
So BIO_ctrl(), BIO_callback_ctrl(), BIO_ptr_ctrl(), and BIO_int_ctrl() are the BIO "control" operations, and they take arguments of various types. Like, different types, bestie. But ngl you don't normally call these directly β the various macros are what you use instead, and those standard macros are described down below. π Macros that are specific to one particular type of BIO get documented in that BIO's own manual page, along with any special features the standard calls have for it. iykyk.
Depending on the cmd and on the type of b, BIO_ctrl() might have a read-only effect on b, or it might actually change data in b or in its sub-structures. It may also have the side effect of changing the memory that parg points to. π So yeah, keep an eye on that.
BIO_callback_ctrl() does not call BIO_ctrl(). Shocking, I know. Instead it requires that the BIO type of b provides a dedicated callback_ctrl function pointer β that's built into the library for some standard BIO types, and you can supply it with BIO_meth_set_callback_ctrl(3) for application-defined BIO types. The only cmd supported by BIO_callback_ctrl() is BIO_CTRL_SET_CALLBACK.
BIO_ptr_ctrl() calls BIO_ctrl() with parg pointing to the location of a temporary pointer variable that was initialized to NULL.
BIO_int_ctrl() calls BIO_ctrl() with parg pointing to the location of a temporary int variable initialized to iarg. And here's the vibe check: if BIO_ctrl() changes the value stored at *parg, the new value is literally ignored. π
BIO_reset() typically resets a BIO to some initial state. For file related BIOs, for example, it rewinds the file pointer to the start of the file. Rewind slay. π
BIO_seek() resets a file related BIO's (that's file descriptor BIOs and FILE BIOs) file position pointer to ofs bytes from the start of the file.
BIO_tell() returns the current file position of a file related BIO.
BIO_flush() normally writes out any internally buffered data. In some cases it's used to signal EOF, and that no more data will be written.
BIO_eof() returns 1 if the BIO has read EOF. The precise meaning of "EOF" varies according to the BIO type β it's giving "depends on your type" energy, fr fr.
BIO_set_close() sets the BIO b close flag to flag. And flag can take the value BIO_CLOSE or BIO_NOCLOSE. Typically BIO_CLOSE is used in a source/sink BIO to indicate that the underlying I/O stream should be closed when the BIO is freed. β¨
BIO_get_close() returns the BIO's close flag.
BIO_pending(), BIO_ctrl_pending(), BIO_wpending(), and BIO_ctrl_wpending() return the number of pending characters in the BIO's read and write buffers. Not all BIOs support these calls, sorry bestie π β and just so you know, BIO_ctrl_pending() and BIO_ctrl_wpending() return a size_t type and are functions. Yes, the others are macros. Iconic behavior.
BIO_set_info_callback() installs the function pointer cb as an info callback in b by calling BIO_callback_ctrl() with a command of BIO_CTRL_SET_CALLBACK. Among the BIO types built into the library, only BIO_s_connect(3) and BIO_f_ssl(3) support this functionality. π And some filter BIO types forward this control call to the next BIO in the chain instead of processing it themselves. Main character filter energy.
BIO_get_info_callback() places the function pointer to the info callback into *cbp if any was installed using BIO_set_info_callback() or BIO_callback_ctrl(). If the type of b supports setting an info callback but none was installed, it stores a NULL pointer in *cbp.
The function type name bio_info_cb is a deprecated synonym for BIO_info_cb, provided for backward compatibility with some existing application software. So like, it's there for the old-heads. Use the pretty one. π
π§ the cmd constants that correspond to macros π§
Here's the full mapping, every single one, no skipping:
BIO_C_DESTROY_BIO_PAIRβBIO_destroy_bio_pair(3)BIO_C_DO_STATE_MACHINEβBIO_do_handshake(3)BIO_C_FILE_SEEKβBIO_seek()BIO_C_FILE_TELLβBIO_tell()BIO_C_GET_ACCEPTβBIO_get_accept_port(3)BIO_C_GET_BIND_MODEβBIO_get_bind_mode(3)BIO_C_GET_BUF_MEM_PTRβBIO_get_mem_ptr(3)BIO_C_GET_BUFF_NUM_LINESβBIO_get_buffer_num_lines(3)BIO_C_GET_CIPHER_CTXβBIO_get_cipher_ctx(3)BIO_C_GET_CIPHER_STATUSβBIO_get_cipher_status(3)BIO_C_GET_FDβBIO_get_fd(3)BIO_C_GET_FILE_PTRβBIO_get_fp(3)BIO_C_GET_MDβBIO_get_md(3)BIO_C_GET_MD_CTXβBIO_get_md_ctx(3)BIO_C_GET_READ_REQUESTβBIO_get_read_request(3)BIO_C_GET_SSLβBIO_get_ssl(3)BIO_C_GET_SSL_NUM_RENEGOTIATESβBIO_get_num_renegotiates(3)BIO_C_GET_WRITE_BUF_SIZEβBIO_get_write_buf_size(3)BIO_C_GET_WRITE_GUARANTEEβBIO_get_write_guarantee(3)BIO_C_MAKE_BIO_PAIRβBIO_make_bio_pair(3)BIO_C_RESET_READ_REQUESTβBIO_ctrl_reset_read_request(3)BIO_C_SET_BIND_MODEβBIO_set_bind_mode(3)BIO_C_SET_BUF_MEMβBIO_set_mem_buf(3)BIO_C_SET_BUF_MEM_EOF_RETURNβBIO_set_mem_eof_return(3)BIO_C_SET_BUFF_READ_DATAβBIO_set_buffer_read_data(3)BIO_C_SET_FDβBIO_set_fd(3)BIO_C_SET_FILE_PTRβBIO_set_fp(3)BIO_C_SET_MDβBIO_set_md(3)BIO_C_SET_MD_CTXβBIO_set_md_ctx(3)BIO_C_SET_NBIOβBIO_set_nbio(3)BIO_C_SET_SSLβBIO_set_ssl(3)BIO_C_SET_SSL_RENEGOTIATE_BYTESβBIO_set_ssl_renegotiate_bytes(3)BIO_C_SET_SSL_RENEGOTIATE_TIMEOUTβBIO_set_ssl_renegotiate_timeout(3)BIO_C_SET_WRITE_BUF_SIZEβBIO_set_write_buf_size(3)BIO_C_SHUTDOWN_WRβBIO_shutdown_wr(3)BIO_C_SSL_MODEβBIO_set_ssl_mode(3)BIO_CTRL_DGRAM_CONNECTβBIO_ctrl_dgram_connect(3)BIO_CTRL_DGRAM_GET_PEERβBIO_dgram_get_peer(3)BIO_CTRL_DGRAM_GET_RECV_TIMER_EXPβBIO_dgram_recv_timedout(3)BIO_CTRL_DGRAM_GET_SEND_TIMER_EXPβBIO_dgram_send_timedout(3)BIO_CTRL_DGRAM_SET_CONNECTEDβBIO_ctrl_set_connected(3)BIO_CTRL_DGRAM_SET_PEERβBIO_dgram_set_peer(3)BIO_CTRL_DUPβBIO_dup_state(3)BIO_CTRL_EOFβBIO_eof()BIO_CTRL_FLUSHβBIO_flush()BIO_CTRL_GET_CALLBACKβBIO_get_info_callback()BIO_CTRL_GET_CLOSEβBIO_get_close()BIO_CTRL_INFOβBIO_get_mem_data(3)BIO_CTRL_PENDINGβBIO_pending()BIO_CTRL_RESETβBIO_reset()BIO_CTRL_SET_CALLBACKβBIO_set_info_callback()BIO_CTRL_SET_CLOSEβBIO_set_close()BIO_CTRL_WPENDINGβBIO_wpending()
π the cmd constants that are lowkey shared π
A few cmd constants serve more than one macro each (overachievers π), and they're documented in these manual pages:
BIO_C_GET_CONNECTβBIO_s_connect(3)BIO_C_SET_ACCEPTβBIO_s_accept(3)BIO_C_SET_BUFF_SIZEβBIO_f_buffer(3)BIO_C_SET_CONNECTβBIO_s_connect(3)BIO_C_SET_FILENAMEβBIO_s_file(3)
π the cmd constants with no macro at all π
Some cmd constants are not associated with any macros. They're still valid and everything, they just don't have a macro baddie to hang out with. Documented here:
BIO_CTRL_DGRAM_GET_FALLBACK_MTUβBIO_dgram_set_peer(3)BIO_CTRL_DGRAM_GET_MTUβBIO_dgram_set_peer(3)BIO_CTRL_DGRAM_GET_RECV_TIMEOUTβBIO_dgram_recv_timedout(3)BIO_CTRL_DGRAM_GET_SEND_TIMEOUTβBIO_dgram_send_timedout(3)BIO_CTRL_DGRAM_SET_MTUβBIO_dgram_set_peer(3)BIO_CTRL_DGRAM_SET_NEXT_TIMEOUTβBIO_dgram_recv_timedout(3)BIO_CTRL_DGRAM_SET_RECV_TIMEOUTβBIO_dgram_recv_timedout(3)BIO_CTRL_DGRAM_SET_SEND_TIMEOUTβBIO_dgram_send_timedout(3)BIO_CTRL_DGRAM_MTU_EXCEEDEDβBIO_s_datagram(3)BIO_CTRL_POPβBIO_pop(3)BIO_CTRL_PUSHβBIO_push(3)
π₯ RETURN VALUES π₯
Ok so the meaning of the return values of BIO_ctrl(), BIO_callback_ctrl(), and BIO_int_ctrl() depends on both the type of b and on the cmd. Like, it's contextual, bestie. But some ground rules:
- If
bis aNULLpointer, no action occurs and0is returned. π«Ά - The return value
-2usually indicates a fatal error. In particular, it's returned if thecmdis unsupported by the type ofb. So if you see-2, that's your sign π
BIO_callback_ctrl() and BIO_set_info_callback() return 1 on success, 0 if b is NULL or to indicate failure of a valid cmd, or -2 if the cmd is not supported by b.
BIO_ptr_ctrl() returns NULL if the BIO_ctrl() call returns a negative value or does not change *parg, or the pointer it puts into *parg otherwise.
BIO_int_ctrl() returns the return value of BIO_ctrl(). Simple. Clean. We love a delegation moment. β¨
BIO_reset() normally returns 1 for success and 0 or -1 for failure. File BIOs are the exception β they return 0 for success and -1 for failure. Yes that's backwards from the rest, no I don't know why, it's just the vibes π€‘
BIO_seek() and BIO_tell() both return the current file position on success and -1 for failure β except file BIOs, which for BIO_seek() always return 0 for success and -1 for failure.
BIO_flush() returns 1 for success and 0 or -1 for failure.
BIO_eof() returns 1 if EOF has been reached or 0 otherwise.
BIO_set_close() always returns 1. King behavior, never misses. π
BIO_get_close() returns the close flag value BIO_CLOSE or BIO_NOCLOSE.
BIO_pending(), BIO_ctrl_pending(), BIO_wpending(), and BIO_ctrl_wpending() return the amount of pending data.
BIO_get_info_callback() returns 1 on success β including when the type of b supports an info callback but none is installed β 0 if b is NULL or -2 if the type of b does not support an info callback.
β οΈ heads up bestie: if a callback was installed inbusingBIO_set_callback_ex(3)orBIO_set_callback(3), it can modify the return values of all these functions. So the numbers above are the default storyline, not a promise. π
β¨ NOTES β¨ (the tea you actually need β)
Okay bestie, listen β BIO_flush() can literally write data, so it's not just a chill little housekeeping call. That means it may return 0 or -1 to tell you "hey, retry this later," in basically the same way BIO_write(3) does. So you gotta call BIO_should_retry(3) and take the appropriate action if the call fails. No ignoring it, fr fr. π
Also, a vibe check on BIO_pending() and BIO_wpending(): their return values may not reliably tell you how much pending data there actually is in all cases. Like, for a file BIO, some data may be sitting there in the FILE structure's internal buffers and it's just not possible to determine that in a portable way. And for other types of BIO, these calls may not even be supported. π So don't @ them for answers they can't give.
Now for the filter BIO glow-up: if a filter BIO doesn't internally handle a particular BIO_ctrl() operation, it usually passes that operation along to the next BIO in the chain. That's iconic because it often means you don't have to go locate the exact BIO you need for a particular operation β you can just call it on a chain and it automatically gets passed to the relevant BIO. Slay. π
But be careful, because this can also cause unexpected results. For example, no current filter BIOs implementBIO_seek(), but the call may still succeed if the chain ends in aFILEor file descriptor BIO. Sneaky little plot twist. π
And the source/sink BIOs? They return 0 if they don't recognize the BIO_ctrl() operation. Simple as that, no cap.
π SEE ALSO π
Go read those too, bestie, they're part of the lore π«Ά
π¦ HISTORY π¦ (aka the origin story)
BIO_ctrl(), BIO_reset(), BIO_flush(), BIO_eof(), BIO_set_close(), BIO_get_close(), and BIO_pending() first appeared in SSLeay 0.6.0. π
BIO_wpending() first appeared in SSLeay 0.8.1. πΈ
BIO_ptr_ctrl(), BIO_int_ctrl(), BIO_get_info_callback() and BIO_set_info_callback() first appeared in SSLeay 0.9.0. β¨
All these functions have been available since OpenBSD 2.4. π
Then we level up:
BIO_seek()andBIO_tell()first appeared in SSLeay 0.9.1. βBIO_ctrl_pending()andBIO_ctrl_wpending()first appeared in OpenSSL 0.9.4. π¦- These functions have been available since OpenBSD 2.6. π
More history, because she's been around forever:
BIO_callback_ctrl()first appeared in OpenSSL 0.9.5 and has been available since OpenBSD 2.7. πbio_info_cb()first appeared with a more complicated prototype in OpenSSL 0.9.6 and has been available since OpenBSD 2.9. πBIO_info_cb()first appeared in OpenSSL 1.1.0h and has been available since OpenBSD 6.3. π
Honestly? Legacy queen behavior. Periodt. π
π BUGS π (read this or perish)
Some of the return values are ambiguous, so care should be taken β this is your warning, bestie, do not skip it. In particular, a return value of 0 can be returned:
- if an operation is not supported,
- if an error occurred,
- if EOF has not been reached,
- and in the case of
BIO_seek()on a file BIO for a successful operation.
Yeah. 0 means like four different things depending on the situation. π It's giving "choose your own adventure" and honestly it's a lot. Stay safe out there. π«Άβ¨π
And that's a wrap bestie! This page came from Debian, dated November 16, 2023, and it's the BIO_CTRL(3) page β go forth and call your BIOs correctly, mwah πππ¦
π¦ where this page comes from
- opensuse-leap 16.0: libressl-devel-doc 4.1.0-bp160.1.1 Β· OpenSSL
- Copyright (c) 2023 Ingo Schwarze <schwarze@openbsd.org>
- Copyright (c) 2000, 2016 The OpenSSL Project. All rights reserved
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms