1.\" $OpenBSD: BIO_accept.3,v 1.1 2022/12/22 21:05:48 schwarze Exp $ 2.\" 3.\" Copyright (c) 2022 Ingo Schwarze <schwarze@openbsd.org> 4.\" 5.\" Permission to use, copy, modify, and distribute this software for any 6.\" purpose with or without fee is hereby granted, provided that the above 7.\" copyright notice and this permission notice appear in all copies. 8.\" 9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16.\" 17.Dd $Mdocdate: December 22 2022 $ 18.Dt BIO_ACCEPT 3 19.Os 20.Sh NAME 21.\" mentioned in OpenSSL documentation and still used internally in LibreSSL 22.Nm BIO_get_host_ip , 23.Nm BIO_get_port , 24.Nm BIO_get_accept_socket , 25.Nm BIO_accept , 26.Nm BIO_sock_error , 27.Nm BIO_sock_non_fatal_error , 28.Nm BIO_sock_should_retry , 29.\" used internally in LibreSSL and OpenSSL and not deprecated in OpenSSL 30.Nm BIO_socket_nbio , 31.\" mentioned in OpenSSL documentation and not deprecated in OpenSSL 32.Nm BIO_set_tcp_ndelay 33.\" deprecated in OpenSSL and unused anywhere, hence intentionally undocumented 34.\" .Nm BIO_gethostbyname 35.\" .Nm BIO_socket_ioctl 36.\" does almost nothing and used very rarely, hence intentionally undocumented 37.\" .Nm BIO_sock_init 38.\" .Nm BIO_sock_cleanup 39.Nd wrappers for socket operations 40.Sh SYNOPSIS 41.In openssl/bio.h 42.Ft int 43.Fo BIO_get_host_ip 44.Fa "const char *hostname" 45.Fa "unsigned char *in_addr_buffer" 46.Fc 47.Ft int 48.Fo BIO_get_port 49.Fa "const char *servname" 50.Fa "unsigned short *port" 51.Fc 52.Ft int 53.Fo BIO_get_accept_socket 54.Fa "char *host_port" 55.Fa "int bind_mode" 56.Fc 57.Ft int 58.Fo BIO_accept 59.Fa "int socket" 60.Fa "char **addr" 61.Fc 62.Ft int 63.Fn BIO_sock_error "int socket" 64.Ft int 65.Fn BIO_sock_non_fatal_error "int errnum" 66.Ft int 67.Fn BIO_sock_should_retry "int retval" 68.Ft int 69.Fn BIO_socket_nbio "int socket" "int mode" 70.Ft int 71.Fn BIO_set_tcp_ndelay "int socket" "int on" 72.Sh DESCRIPTION 73.Fn BIO_get_host_ip 74looks up one IPv4 address for the given 75.Fa hostname 76using 77.Xr getaddrinfo 3 78and writes the first returned IPv4 address into 79.Pf * Fa in_addr_buffer . 80The caller is responsible for providing a buffer that is at least 81.Fn sizeof in_addr_t 82bytes long. 83After a successful call, the caller needs to cast 84.Fa in_addr_buffer 85to 86.Pq Vt in_addr_t * . 87.Pp 88.Fn BIO_get_port 89looks up 90.Fa servname 91in the 92.Xr services 5 93database using 94.Xr getaddrinfo 3 95and stores the associated port number at the location specified by the 96.Fa port 97argument. 98.Pp 99.Fn BIO_get_accept_socket 100creates an IPv4 TCP socket and 101.Xr listen 2 Ns s 102for incoming connections. 103The string 104.Fa host_port 105is parsed. 106If it contains a colon, the substring before the colon is interpreted 107as a local hostname of the interface to 108.Xr bind 2 109to. 110If the hostname is empty, consists of a single asterisk 111.Pq Qq *:... , 112or if there is no colon, 113.Dv INADDR_ANY 114is used instead of a local hostname. 115The rest of the string 116.Fa host_port , 117or the whole string if it contains no colon, 118is treated as a service name. 119The hostname and the service name are converted to a local IP address 120and port number using 121.Xr getaddrinfo 3 . 122If 123.Fa bind_mode 124is the constant 125.Dv BIO_BIND_REUSEADDR , 126allowing local address reuse is attempted using 127.Xr setsockopt 2 128with an argument of 129.Dv SO_REUSEADDR 130before calling 131.Xr bind 2 . 132.Pp 133.Fn BIO_accept 134calls 135.Xr accept 2 136to receive one connection on the 137.Fa socket . 138When it receives a connection, it 139.Xr free 3 Ns s 140.Pf * Fa addr , 141and if it is an IPv4 connection, it allocates a new string, 142writes the peer IP address in dotted decimal form, a colon, 143and the decimal port number into the string, and stores a pointer 144to the string in 145.Pf * Fa addr . 146For other address families or if 147.Xr getnameinfo 3 148or memory allocation fails, 149.Pf * Fa addr 150is set to 151.Dv NULL 152but 153.Fn BIO_accept 154succeeds anyway. 155.Pp 156.Fn BIO_sock_error 157retrieves, clears, and returns the error status code of the 158.Fa socket 159by calling 160.Xr getsockopt 2 161with arguments 162.Dv SOL_SOCKET 163and 164.Dv SO_ERROR . 165.Pp 166.Fn BIO_sock_non_fatal_error 167determines whether the error status code 168.Fa errnum 169represents a recoverable error. 170.Pp 171.Fn BIO_sock_should_retry 172determines whether a recoverable error occurred by inspecting both 173.Xr errno 2 174and 175.Fa retval , 176which is supposed to usually be 177the return value of a previously called function like 178.Fn BIO_accept , 179.Xr BIO_read 3 , 180or 181.Xr BIO_write 3 . 182.Pp 183If 184.Fa mode 185is non-zero, 186.Fn BIO_socket_nbio 187switches the 188.Fa socket 189to non-blocking mode using 190.Xr fcntl 2 . 191If 192.Fa mode 193is 0, it switches to blocking mode. 194.Pp 195.Fn BIO_set_tcp_ndelay 196sets the 197.Dv TCP_NODELAY 198option on the 199.Fa socket 200if 201.Fa on 202is 1 or clears it if 203.Fa on 204is 0; see 205.Xr tcp 4 206for details. 207.Sh RETURN VALUES 208.Fn BIO_get_host_ip , 209.Fn BIO_get_port , 210and 211.Fn BIO_socket_nbio 212return 1 on success or 0 on failure. 213.Pp 214.Fn BIO_get_accept_socket 215returns the file descriptor of the newly created listening socket or \-1 if 216.Fa host_port 217is 218.Dv NULL , 219no service is specified, or 220.Xr getaddrinfo 3 , 221.Xr socket 2 , 222.Xr bind 2 , 223.Xr listen 2 , 224or memory allocation fails. 225.Pp 226.Fn BIO_accept 227returns the file descriptor of the received connection, 228\-1 on fatal errors, that is, when 229.Fa addr 230is 231.Dv NULL 232or 233.Xr accept 2 234fails fatally, or \-2 when 235.Xr accept 2 236fails in a non-fatal way and might succeed when retried later. 237.Pp 238.Fn BIO_sock_error 239returns an error status code like 240.Dv EAGAIN , 241.Dv ECONNABORTED , 242.Dv ECONNREFUSED , 243.Dv ECONNRESET , 244.Dv ELOOP , 245.Dv EMSGSIZE , 246.Dv ENOBUFS , 247.Dv ENOTCONN , 248.Dv EPIPE , 249.Dv ETIMEDOUT , 250or others, 0 if the 251.Fa socket 252is not in an error state, or 1 if 253.Xr getsockopt 2 254fails. 255.Pp 256.Fn BIO_sock_non_fatal_error 257returns 1 if 258.Fa errnum 259is 260.Dv EAGAIN , 261.Dv EALREADY , 262.Dv EINPROGRESS , 263.Dv EINTR , 264or 265.Dv ENOTCONN 266and 0 otherwise, even if 267.Fa errnum 268is 0. 269.Pp 270.Fn BIO_sock_should_retry 271returns 1 if 272.Fn BIO_sock_non_fatal_error errno 273is 1 and 274.Fa retval 275is either 0 or \-1, or 0 otherwise. 276.Pp 277.Fn BIO_set_tcp_ndelay 278returns 0 on success or \-1 on failure. 279.Sh ERRORS 280If 281.Fn BIO_get_host_ip , 282.Fn BIO_get_port , 283or 284.Fn BIO_get_accept_socket 285fail or 286.Fn BIO_accept 287fails fatally, the following diagnostics can be retrieved with 288.Xr ERR_get_error 3 , 289.Xr ERR_GET_REASON 3 , 290and 291.Xr ERR_reason_error_string 3 : 292.Bl -tag -width Ds 293.It Dv BIO_R_ACCEPT_ERROR Qq "accept error" 294.Xr accept 2 295failed fatally in 296.Fn BIO_accept . 297.It Dv BIO_R_BAD_HOSTNAME_LOOKUP Qq "bad hostname lookup" 298.Xr getaddrinfo 3 299failed or 300.Fa hostname 301was 302.Dv NULL 303in 304.Fn BIO_get_host_ip , 305or 306.Xr getaddrinfo 3 307failed in 308.Fn BIO_get_accept_socket . 309.It Dv BIO_R_INVALID_ARGUMENT Qq "invalid argument" 310.Xr getaddrinfo 3 311failed in 312.Fn BIO_get_port . 313.It Dv ERR_R_MALLOC_FAILURE Qq "malloc failure" 314Memory allocation failed in 315.Fn BIO_get_accept_socket , 316or 317.Fn BIO_accept 318.Em succeeded 319but was unable to allocate memory for 320.Pf * Fa addr . 321For 322.Fn BIO_accept , 323the returned file descriptor is valid, 324and communication with the peer can be attempted using it. 325.It Dv BIO_R_NO_PORT_SPECIFIED Qq "no port specified" 326The 327.Fa servname 328argument was 329.Dv NULL 330in 331.Fn BIO_get_port , 332or 333.Fa host_port 334was 335.Dv NULL 336or ended after the first colon in 337.Fn BIO_get_accept_socket . 338.It Dv BIO_R_NULL_PARAMETER Qq "null parameter" 339The 340.Fa addr 341argument was 342.Dv NULL 343in 344.Fn BIO_accept . 345.It Dv BIO_R_UNABLE_TO_BIND_SOCKET Qq "unable to bind socket" 346.Xr bind 2 347failed in 348.Fn BIO_get_accept_socket . 349.It Dv BIO_R_UNABLE_TO_CREATE_SOCKET Qq "unable to create socket" 350.Xr socket 2 351failed in 352.Fn BIO_get_accept_socket . 353.It Dv BIO_R_UNABLE_TO_LISTEN_SOCKET Qq "unable to listen socket" 354.Xr listen 2 355failed in 356.Fn BIO_get_accept_socket . 357.El 358.Sh SEE ALSO 359.Xr bind 2 , 360.Xr connect 2 , 361.Xr errno 2 , 362.Xr fcntl 2 , 363.Xr getsockopt 2 , 364.Xr listen 2 , 365.Xr sigaction 2 , 366.Xr socket 2 , 367.Xr BIO_new 3 , 368.Xr BIO_read 3 , 369.Xr getaddrinfo 3 , 370.Xr ip 4 , 371.Xr tcp 4 372.Sh HISTORY 373.Fn BIO_sock_should_retry 374first appeared in SSLeay 0.6.5 and the other functions except 375.Fn BIO_socket_nbio 376in SSLeay 0.8.0. 377They have all been available since 378.Ox 2.4 . 379.Pp 380.Fn BIO_socket_nbio 381first appeared in SSLeay 0.9.1 and has been available since 382.Ox 2.6 . 383