BIO_ACCEPT(3)

NAME
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, BIO_set_tcp_ndelay - wrappers for socket operations

SYNOPSIS
libcrypto
#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
BIO_get_host_ip() looks up one IPv4 address for the given hostname using getaddrinfo(3) and writes the first returned IPv4 address into *in_addr_buffer. The caller is responsible for providing a buffer that is at least sizeof(in_addr_t) bytes long. After a successful call, the caller needs to cast in_addr_buffer to (in_addr_t *).

BIO_get_port() looks up servname in the services(5) database using getaddrinfo(3) and stores the associated port number at the location specified by the port argument.

BIO_get_accept_socket() creates an IPv4 TCP socket and listen(2)s for incoming connections. The string host_port is parsed. If it contains a colon, the substring before the colon is interpreted as a local hostname of the interface to bind(2) to. If the hostname is empty, consists of a single asterisk ("*:..."), or if there is no colon, INADDR_ANY is used instead of a local hostname. The rest of the string host_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 using getaddrinfo(3). If bind_mode is the constant BIO_BIND_REUSEADDR, allowing local address reuse is attempted using setsockopt(2) with an argument of SO_REUSEADDR before calling bind(2).

BIO_accept() calls accept(2) to receive one connection on the socket. When it receives a connection, it free(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 if getnameinfo(3) or memory allocation fails, *addr is set to NULL but BIO_accept() succeeds anyway.

BIO_sock_error() retrieves, clears, and returns the error status code of the socket by calling getsockopt(2) with arguments SOL_SOCKET and SO_ERROR.

BIO_sock_non_fatal_error() determines whether the error status code errnum represents a recoverable error.

BIO_sock_should_retry() determines whether a recoverable error occurred by inspecting both errno(2) and retval, which is supposed to usually be the return value of a previously called function like BIO_accept(), BIO_read(3), or BIO_write(3).

If mode is non-zero, BIO_socket_nbio() switches the socket to non-blocking mode using fcntl(2). If mode is 0, it switches to blocking mode.

BIO_set_tcp_ndelay() sets the TCP_NODELAY option on the socket if on is 1 or clears it if on is 0; see tcp(4) for details.

RETURN VALUES
BIO_get_host_ip(), BIO_get_port(), and BIO_socket_nbio() return 1 on success or 0 on failure.

BIO_get_accept_socket() returns the file descriptor of the newly created listening socket or -1 if host_port is NULL, no service is specified, or getaddrinfo(3), socket(2), bind(2), listen(2), or memory allocation fails.

BIO_accept() returns the file descriptor of the received connection, -1 on fatal errors, that is, when addr is NULL or accept(2) fails fatally, or -2 when accept(2) fails in a non-fatal way and might succeed when retried later.

BIO_sock_error() returns an error status code like EAGAIN, ECONNABORTED, ECONNREFUSED, ECONNRESET, ELOOP, EMSGSIZE, ENOBUFS, ENOTCONN, EPIPE, ETIMEDOUT, or others, 0 if the socket is not in an error state, or 1 if getsockopt(2) fails.

BIO_sock_non_fatal_error() returns 1 if errnum is EAGAIN, EALREADY, EINPROGRESS, EINTR, or ENOTCONN and 0 otherwise, even if errnum is 0.

BIO_sock_should_retry() returns 1 if BIO_sock_non_fatal_error(errno) is 1 and retval is either 0 or -1, or 0 otherwise.

BIO_set_tcp_ndelay() returns 0 on success or -1 on failure.

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 in BIO_accept().

BIO_R_BAD_HOSTNAME_LOOKUP "bad hostname lookup"
    getaddrinfo(3) failed or hostname was NULL in BIO_get_host_ip(), or getaddrinfo(3) failed in BIO_get_accept_socket().

BIO_R_INVALID_ARGUMENT "invalid argument"
    getaddrinfo(3) failed in BIO_get_port().

ERR_R_MALLOC_FAILURE "malloc failure"
    Memory allocation failed in BIO_get_accept_socket(), or BIO_accept() succeeded but was unable to allocate memory for *addr. For BIO_accept(), the returned file descriptor is valid, and communication with the peer can be attempted using it.

BIO_R_NO_PORT_SPECIFIED "no port specified"
    The servname argument was NULL in BIO_get_port(), or host_port was NULL or ended after the first colon in BIO_get_accept_socket().

BIO_R_NULL_PARAMETER "null parameter"
    The addr argument was NULL in BIO_accept().

BIO_R_UNABLE_TO_BIND_SOCKET "unable to bind socket"
    bind(2) failed in BIO_get_accept_socket().

BIO_R_UNABLE_TO_CREATE_SOCKET "unable to create socket"
    socket(2) failed in BIO_get_accept_socket().

BIO_R_UNABLE_TO_LISTEN_SOCKET "unable to listen socket"
    listen(2) failed in BIO_get_accept_socket().

SEE ALSO
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), tcp(4)

HISTORY
BIO_sock_should_retry() first appeared in SSLeay 0.6.5 and the other functions except BIO_socket_nbio() in SSLeay 0.8.0. They have all been available since OpenBSD 2.4.

BIO_socket_nbio() first appeared in SSLeay 0.9.1 and has been available since OpenBSD 2.6.