BIO_METH_NEW(3SSL)

πŸ’– BIO_METH_NEW πŸ’–

okay bestie, welcome to the BIO_METHOD builder page β€” this is the OpenSSL one, BIO_METH_NEW(3SSL), and it's literally the whole toolkit for making your own custom BIO type from scratch. it's a long one so buckle up, we're doing this in parts πŸŽ€


✨ NAME ✨

BIO_get_new_index, BIO_meth_new, BIO_meth_free, BIO_meth_get_read_ex, BIO_meth_set_read_ex, BIO_meth_get_write_ex, BIO_meth_set_write_ex, BIO_meth_get_write, 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, BIO_meth_set_sendmmsg, BIO_meth_get_sendmmsg, BIO_meth_set_recvmmsg, BIO_meth_get_recvmmsg β€” all the routines you need to build up BIO methods 🫢


✨ SYNOPSIS ✨

        #include <openssl/bio.h>

        int BIO_get_new_index(void);

        BIO_METHOD *BIO_meth_new(int type, const char *name);

        void BIO_meth_free(BIO_METHOD *biom);

        int BIO_meth_set_write_ex(BIO_METHOD *biom,
                                  int (*bwrite)(BIO *, const char *, size_t, size_t *));
        int BIO_meth_set_write(BIO_METHOD *biom,
                               int (*write)(BIO *, const char *, int));

        int BIO_meth_set_read_ex(BIO_METHOD *biom,
                                 int (*bread)(BIO *, char *, size_t, size_t *));
        int BIO_meth_set_read(BIO_METHOD *biom, int (*read)(BIO *, char *, int));

        int BIO_meth_set_puts(BIO_METHOD *biom, int (*puts)(BIO *, const char *));
        int BIO_meth_set_gets(BIO_METHOD *biom,
                              int (*gets)(BIO *, char *, int));

        int BIO_meth_set_ctrl(BIO_METHOD *biom,
                              long (*ctrl)(BIO *, int, long, void *));

        int BIO_meth_set_create(BIO_METHOD *biom, int (*create)(BIO *));
        int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy)(BIO *));

        int BIO_meth_set_callback_ctrl(BIO_METHOD *biom,
                                       long (*callback_ctrl)(BIO *, int, BIO_info_cb *));

        int BIO_meth_set_sendmmsg(BIO_METHOD *biom,
                                  ossl_ssize_t (*f) (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));

and now the plot twist 😭 β€” the following functions have been deprecated since OpenSSL 3.5:

        int (*BIO_meth_get_write_ex(const BIO_METHOD *biom))(BIO *, const char *, size_t,
                                                       size_t *);
        int (*BIO_meth_get_write(const BIO_METHOD *biom))(BIO *, const char *, int);

        int (*BIO_meth_get_read_ex(const BIO_METHOD *biom))(BIO *, char *, size_t, size_t *);
        int (*BIO_meth_get_read(const BIO_METHOD *biom))(BIO *, char *, int);

        int (*BIO_meth_get_puts(const BIO_METHOD *biom))(BIO *, const char *);
        int (*BIO_meth_get_gets(const BIO_METHOD *biom))(BIO *, char *, int);

        long (*BIO_meth_get_ctrl(const BIO_METHOD *biom))(BIO *, int, long, void *);

        int (*BIO_meth_get_create(const BIO_METHOD *bion))(BIO *);
        int (*BIO_meth_get_destroy(const BIO_METHOD *biom))(BIO *);

        long (*BIO_meth_get_callback_ctrl(const BIO_METHOD *biom))(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);
        ossl_ssize_t (*BIO_meth_get_recvmmsg(const BIO_METHOD *biom))(BIO *,
                                                                      BIO_MSG *,
                                                                      size_t,
                                                                      size_t,
                                                                      uint64_t);

πŸ’… DESCRIPTION πŸ’…

ok so the BIO_METHOD type is a structure, right, and it's what you use to implement brand-new BIO types. it's basically a lil bundle of function pointers that OpenSSL calls into when it wants to do BIO-ish stuff β€” the whole capability set. if you want the full lore on BIOs themselves, go read bio(7). πŸ¦‹

BIO_meth_new() builds you a fresh BIO_METHOD structure holding a type identifier called type and a string that's its name. for type you can pass BIO_TYPE_NONE, or you can get a unique one from BIO_get_new_index() if you need it to actually be searchable β€” that's the BIO_find_type(3) situation. πŸ‘€

ngl there's a hard limit here: BIO_get_new_index() can only be used 127 times before it starts returning an error. so like, don't be greedy with it bestie πŸ’€

all the standard OpenSSL-provided BIO types live in <openssl/bio.h>. some iconic examples: BIO_TYPE_BUFFER and BIO_TYPE_CIPHER. and here's the vibe check on type bits:

  • Filter BIOs should have a type with the "filter" bit set: BIO_TYPE_FILTER.
  • Source/sink BIOs should have the "source/sink" bit set: BIO_TYPE_SOURCE_SINK.
  • File-descriptor-based BIOs (socket, fd, connect, accept, etc.) should additionally have the "descriptor" bit set: BIO_TYPE_DESCRIPTOR.

head to the BIO_find_type(3) page if you want more on all that. ✨

BIO_meth_free() destroys a BIO_METHOD structure and frees up all the memory hanging off it. and if you hand it NULL? nothing happens. it just minds its business. πŸ™ˆ


🌸 the write situation

BIO_meth_get_write_ex() and BIO_meth_set_write_ex() get and set (respectively, obviously) the function used to write arbitrary length data to the BIO. this function gets called when the application calls BIO_write_ex() or BIO_write(). the parameters mean the same thing as they do for BIO_write_ex(), and it has to return values like BIO_write_ex() does. πŸ“

older code might call BIO_meth_get_write() and BIO_meth_set_write() instead, to set an old-style write function. those parameters mean the same thing as they do for BIO_write(), and it returns values like BIO_write() does.

important!! functions set by BIO_meth_set_write_ex() and BIO_meth_set_write() must call BIO_set_flags() to set the BIO_FLAGS_SHOULD_RETRY flag in the relevant situations. don't skip this, it's giving main-character energy for a reason. πŸ”₯
also: applications should not call both BIO_meth_set_write_ex() and BIO_meth_set_write(), and should not call BIO_meth_get_write() when the function was set with BIO_meth_set_write_ex(). pick a lane bestie 😭

🌈 the read situation

BIO_meth_get_read_ex() and BIO_meth_set_read_ex() get and set the function used to read arbitrary length data from the BIO. this gets called when the application calls BIO_read_ex() or BIO_read(). parameters mean the same as for BIO_read_ex(), returns values as described for BIO_read_ex(). and β€” key point β€” the function has to handle the end-of-file condition (if that's applicable to it) and return 0 in that case. πŸ“–

older code may call BIO_meth_get_read() and BIO_meth_set_read() instead, for an old-style read function. parameters mean the same as for BIO_read(), returns like BIO_read().

again!! functions set by BIO_meth_set_read_ex() and BIO_meth_set_read() must call BIO_set_flags() to set the BIO_FLAGS_SHOULD_RETRY flag in the relevant situations. ⭐
and again: applications should not call both BIO_meth_set_read_ex() and BIO_meth_set_read(), or call BIO_meth_get_read() when the function was set with BIO_meth_set_read_ex(). periodt. πŸ’…

πŸŽ€ puts & gets

BIO_meth_get_puts() and BIO_meth_set_puts() get and set the function used for writing a NULL terminated string to the BIO. it gets called when the application calls BIO_puts(). parameters mean the same thing as for BIO_puts(). πŸ“

BIO_meth_get_gets() and BIO_meth_set_gets() get and set the function typically used for reading a line of data from the BIO. (check the BIO_gets(3) page for the deets.) it gets called when the application calls BIO_gets(). parameters mean the same thing as for BIO_gets(). 🧚


πŸ‘‘ ctrl

BIO_meth_get_ctrl() and BIO_meth_set_ctrl() get and set the function used for processing ctrl messages in the BIO. see BIO_ctrl(3) for more. it gets called when the application calls BIO_ctrl(), and the parameters mean the same as for BIO_ctrl().

okay this next bit is lowkey important so pay attention:

if the concept of end-of-file is meaningful for your BIO and the read method was set using BIO_meth_set_read_ex(), then your ctrl function must handle the BIO_CTRL_EOF command and return an appropriate value β€” 1 if EOF has been reached, 0 if not, or a negative value on failure β€” at least immediately after a read operation. no cap.
if instead the read method was set using BIO_meth_set_read(), handling BIO_CTRL_EOF is not mandatory. but if you do implement it, it must return 1 if the read function returned 0 when it was attempting to read a nonzero number of bytes. ✨

πŸ’œ create & destroy

BIO_meth_get_create() and BIO_meth_set_create() get and set the function used for creating a new instance of the BIO. it gets called when the application calls BIO_new() and passes in a pointer to the current BIO_METHOD. here's the flow: BIO_new() allocates the memory for the new BIO, and a pointer to that freshly allocated structure gets passed as a parameter to your function.

and this is the spicy bit πŸ”₯ β€” if a create function is set, BIO_new() will not mark the BIO as initialised on allocation. so BIO_set_init(3) must then be called β€” either by the create function itself, or later by a BIO ctrl function β€” once BIO initialisation is complete. don't leave it uninitialised, that's not the vibe.

BIO_meth_get_destroy() and BIO_meth_set_destroy() get and set the function used for destroying an instance of a BIO. it gets called when the application calls BIO_free(), and a pointer to the BIO being destroyed is passed as a parameter. use the destroy function for BIO-specific clean up. important: the memory for the BIO itself should NOT be freed by this function. that's not your job, bestie. πŸ™…β™€οΈ


πŸ¦‹ callback_ctrl

BIO_meth_get_callback_ctrl() and BIO_meth_set_callback_ctrl() get and set the function used for processing callback ctrl messages in the BIO. see the BIO_callback_ctrl(3) page for more info. it gets called when the application calls BIO_callback_ctrl(), and the parameters mean the same as for BIO_callback_ctrl(). πŸ’–


🫢 sendmmsg & recvmmsg

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 BIO_sendmmsg(3) for more. 🌟


⭐ RETURN VALUES ⭐

  • BIO_get_new_index() β€” returns the new BIO type value, or -1 if an error occurred. 😬
  • BIO_meth_new(int type, const char *name) β€” returns a valid BIO_METHOD, or NULL if an error occurred.
  • the BIO_meth_set functions β€” return 1 on success or 0 on error. ✨
  • the BIO_meth_get functions β€” return the corresponding function pointers. πŸ‘‘

πŸ’€ BUGS πŸ’€

okay bestie, real talk β€” this one is not safe and we do not play about it 🚨

It is not safe to use BIO_meth_get_ functions to reuse the BIO implementation of BIOs implemented by OpenSSL itself with application-implemented BIOs. Instead, either the applications ought to implement these functions themselves, or they should implement a filter BIO.

For more details, please see <https://github.com/openssl/openssl/issues/26047>.


πŸ‘‘ SEE ALSO πŸ‘‘

If you're still hungry for more docs, go sip on these, bestie:


πŸ¦‹ HISTORY πŸ¦‹

storytime, bestie ✨

  • The functions BIO_meth_get_sendmmsg(), BIO_meth_set_sendmmsg(), BIO_meth_get_recvmmsg() and BIO_meth_set_recvmmsg() were added in OpenSSL 3.2.
  • All the other functions described here were added in OpenSSL 1.1.0.
  • The functions BIO_meth_get_read_ex(), BIO_meth_get_write_ex(), BIO_meth_get_write(), BIO_meth_get_read(), BIO_meth_get_puts(), BIO_meth_get_gets(), BIO_meth_get_ctrl(), BIO_meth_get_create(), BIO_meth_get_destroy(), BIO_meth_get_callback_ctrl(), BIO_meth_get_sendmmsg() and BIO_meth_get_recvmmsg() are deprecated since OpenSSL 3.5.

Legal tea, don't skip it πŸ’…

Copyright 2016-2026 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, bestie 🫢 this was OpenSSL 4.0.3, dated 2026-09-29, manual page BIO_METH_NEW(3SSL). periodt πŸ’–

πŸ“¦ where this page comes from