BIO_ACCEPT(3)
β¨ NAME β¨
okay so this is the BIO_ACCEPT(3) page from the Library Functions Manual, and it's serving all the socket-operation wrapper cuties: BIO_get_host_ip, BIO_get_port, BIO_get_accept_socket, BIO_accept, BIO_sock_error, BIO_sock_non_fatal_error, BIO_sock_should_retry, BIO_socket_nbio, and BIO_set_tcp_ndelay β literally wrappers for socket operations π
.
π SYNOPSIS π
bestie, they all come from this include, no cap:
#include <openssl/bio.h>
int
BIO_get_host_ip(const char *hostname, unsigned char *in_addr_buffer);
int
BIO_get_port(const char *servname, unsigned short *port);
int
BIO_get_accept_socket(char *host_port, int bind_mode);
int
BIO_accept(int socket, char **addr);
int
BIO_sock_error(int socket);
int
BIO_sock_non_fatal_error(int errnum);
int
BIO_sock_should_retry(int retval);
int
BIO_socket_nbio(int socket, int mode);
int
BIO_set_tcp_ndelay(int socket, int on);
π DESCRIPTION π
okay, here's the tea per function, fr fr:
BIO_get_host_ip()β looks up one IPv4 address for the givenhostnameusinggetaddrinfo(3)and writes the first returned IPv4 address into*in_addr_buffer. The caller is responsible for providing a buffer that is at leastsizeof(in_addr_t)bytes long. After a successful call, the caller needs to castin_addr_bufferto(in_addr_t *). buffer sizing is not a vibe to skip πBIO_get_port()β looks upservnamein theservices(5)database usinggetaddrinfo(3)and stores the associated port number at the location specified by theportargument. cute and to the point πBIO_get_accept_socket()β creates an IPv4 TCP socket andlisten(2)s for incoming connections. The stringhost_portis parsed. If it contains a colon, the substring before the colon is interpreted as a local hostname of the interface tobind(2)to. If the hostname is empty, consists of a single asterisk ("*:..."), or if there is no colon,INADDR_ANYis used instead of a local hostname. The rest of the stringhost_port, or the whole string if it contains no colon, is treated as a service name. The hostname and the service name are converted to a local IP address and port number usinggetaddrinfo(3). Ifbind_modeis the constantBIO_BIND_REUSEADDR, allowing local address reuse is attempted usingsetsockopt(2)with an argument ofSO_REUSEADDRbefore callingbind(2). that's a lot of parsing, but she ate πBIO_accept()β callsaccept(2)to receive one connection on thesocket. When it receives a connection, itfree(3)s *addr, and if it is an IPv4 connection, it allocates a new string, writes the peer IP address in dotted decimal form, a colon, and the decimal port number into the string, and stores a pointer to the string in*addr. For other address families or ifgetnameinfo(3)or memory allocation fails,*addris set toNULLbutBIO_accept()succeeds anyway. iconic behavior, tbh β¨BIO_sock_error()β retrieves, clears, and returns the error status code of the socket by callinggetsockopt(2)with argumentsSOL_SOCKETandSO_ERROR. very "check the vibes, then clear the vibes" πBIO_sock_non_fatal_error()β determines whether the error status codeerrnumrepresents a recoverable error. lowkey important π¦BIO_sock_should_retry()β determines whether a recoverable error occurred by inspecting botherrno(2)andretval, which is supposed to usually be the return value of a previously called function likeBIO_accept(),BIO_read(3), orBIO_write(3). retry energy, but make it informed π₯BIO_socket_nbio()β ifmodeis non-zero, switches the socket to non-blocking mode usingfcntl(2). Ifmodeis 0, it switches to blocking mode. choose your fighter π«ΆBIO_set_tcp_ndelay()β sets theTCP_NODELAYoption on the socket ifonis 1 or clears it ifonis 0; seetcp(4)for details. tiny flag, big mood β
π RETURN VALUES π
BIO_get_host_ip(),BIO_get_port(), andBIO_socket_nbio()return 1 on success or 0 on failure. simple queen math πBIO_get_accept_socket()returns the file descriptor of the newly created listening socket or -1 ifhost_portisNULL, no service is specified, orgetaddrinfo(3),socket(2),bind(2),listen(2), or memory allocation fails. yeah, that's a whole list of possible Ls πBIO_accept()returns the file descriptor of the received connection, -1 on fatal errors, that is, whenaddrisNULLoraccept(2)fails fatally, or -2 whenaccept(2)fails in a non-fatal way and might succeed when retried later. bestie,-2means "try again later", don't panic πBIO_sock_error()returns an error status code likeEAGAIN,ECONNABORTED,ECONNREFUSED,ECONNRESET,ELOOP,EMSGSIZE,ENOBUFS,ENOTCONN,EPIPE,ETIMEDOUT, or others, 0 if the socket is not in an error state, or 1 ifgetsockopt(2)fails. not me memorizing the whole error alphabet π€πBIO_sock_non_fatal_error()returns 1 iferrnumisEAGAIN,EALREADY,EINPROGRESS,EINTR, orENOTCONNand 0 otherwise, even iferrnumis 0. yes, even if it's 0 β she said what she said πBIO_sock_should_retry()returns 1 ifBIO_sock_non_fatal_error(errno)is 1 andretvalis either 0 or -1, or 0 otherwise. retry check: passed or not passed, no in-between πΈBIO_set_tcp_ndelay()returns 0 on success or -1 on failure. short king energy π«‘
π¨ ERRORS π¨
If BIO_get_host_ip(), BIO_get_port(), or BIO_get_accept_socket() fail or BIO_accept() fails fatally, the following diagnostics can be retrieved with ERR_get_error(3), ERR_GET_REASON(3), and ERR_reason_error_string(3):
BIO_R_ACCEPT_ERRORβ"accept error":accept(2)failed fatally inBIO_accept(). πBIO_R_BAD_HOSTNAME_LOOKUPβ"bad hostname lookup":getaddrinfo(3)failed orhostnamewasNULLinBIO_get_host_ip(), orgetaddrinfo(3)failed inBIO_get_accept_socket(). π«BIO_R_INVALID_ARGUMENTβ"invalid argument":getaddrinfo(3)failed inBIO_get_port(). πERR_R_MALLOC_FAILUREβ"malloc failure": Memory allocation failed inBIO_get_accept_socket(), orBIO_accept()succeeded but was unable to allocate memory for*addr. ForBIO_accept(), the returned file descriptor is valid, and communication with the peer can be attempted using it. okay but the fd still works, so don't spiral πβ¨BIO_R_NO_PORT_SPECIFIEDβ"no port specified": Theservnameargument wasNULLinBIO_get_port(), orhost_portwasNULLor ended after the first colon inBIO_get_accept_socket(). no port, no party πBIO_R_NULL_PARAMETERβ"null parameter": Theaddrargument wasNULLinBIO_accept(). bestie WHERE is the addr πBIO_R_UNABLE_TO_BIND_SOCKETβ"unable to bind socket":bind(2)failed inBIO_get_accept_socket(). πBIO_R_UNABLE_TO_CREATE_SOCKETβ"unable to create socket":socket(2)failed inBIO_get_accept_socket(). πBIO_R_UNABLE_TO_LISTEN_SOCKETβ"unable to listen socket":listen(2)failed inBIO_get_accept_socket(). not listening, literally π
π SEE ALSO π
go say hi to bind(2), connect(2), errno(2), fcntl(2), getsockopt(2), listen(2), sigaction(2), socket(2), BIO_new(3), BIO_read(3), getaddrinfo(3), ip(4), and tcp(4) β the whole linked universe is right there ππ
π HISTORY π
BIO_sock_should_retry()first appeared in SSLeay 0.6.5, and the other functions exceptBIO_socket_nbio()in SSLeay 0.8.0. They have all been available since OpenBSD 2.4. vintage but still relevant, iykyk π¦BIO_socket_nbio()first appeared in SSLeay 0.9.1 and has been available since OpenBSD 2.6. late arrival, main character energy π
mwah π this page is brought to you by Debian, dated April 30, 2023 β BIO_ACCEPT(3), signing off π«Άβ¨
π¦ where this page comes from
- opensuse-leap 16.0: libressl-devel-doc 4.1.0-bp160.1.1 Β· OpenSSL
- Copyright (c) 2022 Ingo Schwarze <schwarze@openbsd.org>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms