Refactoring BIO: new socket-handling functions, deprecate older ones
authorRichard Levitte <levitte@openssl.org>
Tue, 2 Feb 2016 20:04:54 +0000 (21:04 +0100)
committerRichard Levitte <levitte@openssl.org>
Wed, 3 Feb 2016 18:38:07 +0000 (19:38 +0100)
Added functions:

BIO_socket
BIO_connect
BIO_listen
BIO_accept_ex
BIO_closesocket
BIO_sock_info

These get deprecated:

BIO_gethostbyname
BIO_get_port
BIO_get_host_ip
BIO_get_accept_socket
BIO_accept

Reviewed-by: Kurt Roeckx <kurt@openssl.org>
crypto/bio/Makefile.in
crypto/bio/b_sock.c
crypto/bio/b_sock2.c [new file with mode: 0644]
crypto/err/err.c
doc/crypto/BIO_connect.pod [new file with mode: 0644]
include/openssl/bio.h
include/openssl/err.h

index 9bcc17eef874bdaf28230fcee7584694375ca590..4ad411e78ff6a165928fae7ad28e1c89a569b5cd 100644 (file)
@@ -19,14 +19,14 @@ LIBSRC= bio_lib.c bio_cb.c bio_err.c \
        bss_mem.c bss_null.c bss_fd.c \
        bss_file.c bss_sock.c bss_conn.c \
        bf_null.c bf_buff.c b_print.c b_dump.c b_addr.c \
        bss_mem.c bss_null.c bss_fd.c \
        bss_file.c bss_sock.c bss_conn.c \
        bf_null.c bf_buff.c b_print.c b_dump.c b_addr.c \
-       b_sock.c bss_acpt.c bf_nbio.c bss_log.c bss_bio.c \
+       b_sock.c b_sock2.c bss_acpt.c bf_nbio.c bss_log.c bss_bio.c \
        bss_dgram.c
 #      bf_lbuf.c
 LIBOBJ= bio_lib.o bio_cb.o bio_err.o \
        bss_mem.o bss_null.o bss_fd.o \
        bss_file.o bss_sock.o bss_conn.o \
        bf_null.o bf_buff.o b_print.o b_dump.o b_addr.o \
        bss_dgram.c
 #      bf_lbuf.c
 LIBOBJ= bio_lib.o bio_cb.o bio_err.o \
        bss_mem.o bss_null.o bss_fd.o \
        bss_file.o bss_sock.o bss_conn.o \
        bf_null.o bf_buff.o b_print.o b_dump.o b_addr.o \
-       b_sock.o bss_acpt.o bf_nbio.o bss_log.o bss_bio.o \
+       b_sock.o b_sock2.o bss_acpt.o bf_nbio.o bss_log.o bss_bio.o \
        bss_dgram.o
 #      bf_lbuf.o
 
        bss_dgram.o
 #      bf_lbuf.o
 
index 5a502514dafeb78c1cbd9c2a8242fdb724ae2702..af40454e5c90ae23123d84f49abc595b44c1e069 100644 (file)
@@ -88,6 +88,7 @@ static int wsa_init_done = 0;
 #  define WSAAPI
 # endif
 
 #  define WSAAPI
 # endif
 
+# if OPENSSL_API_COMPAT < 0x10100000L
 static int get_ip(const char *str, unsigned char *ip);
 int BIO_get_host_ip(const char *str, unsigned char *ip)
 {
 static int get_ip(const char *str, unsigned char *ip);
 int BIO_get_host_ip(const char *str, unsigned char *ip)
 {
@@ -194,6 +195,7 @@ int BIO_get_port(const char *str, unsigned short *port_ptr)
     }
     return (1);
 }
     }
     return (1);
 }
+# endif
 
 int BIO_sock_error(int sock)
 {
 
 int BIO_sock_error(int sock)
 {
@@ -218,6 +220,7 @@ int BIO_sock_error(int sock)
         return (j);
 }
 
         return (j);
 }
 
+# if OPENSSL_API_COMPAT < 0x10100000L
 struct hostent *BIO_gethostbyname(const char *name)
 {
     /*
 struct hostent *BIO_gethostbyname(const char *name)
 {
     /*
@@ -230,6 +233,7 @@ struct hostent *BIO_gethostbyname(const char *name)
     return gethostbyname(name);
 # endif
 }
     return gethostbyname(name);
 # endif
 }
+# endif
 
 int BIO_sock_init(void)
 {
 
 int BIO_sock_init(void)
 {
@@ -338,6 +342,7 @@ int BIO_socket_ioctl(int fd, long type, void *arg)
 }
 # endif                         /* __VMS_VER */
 
 }
 # endif                         /* __VMS_VER */
 
+# if OPENSSL_API_COMPAT < 0x10100000L
 /*
  * The reason I have implemented this instead of using sscanf is because
  * Visual C 1.52c gives an unresolved external when linking a DLL :-(
 /*
  * The reason I have implemented this instead of using sscanf is because
  * Visual C 1.52c gives an unresolved external when linking a DLL :-(
@@ -697,6 +702,7 @@ int BIO_accept(int sock, char **addr)
  end:
     return (ret);
 }
  end:
     return (ret);
 }
+# endif
 
 int BIO_set_tcp_ndelay(int s, int on)
 {
 
 int BIO_set_tcp_ndelay(int s, int on)
 {
@@ -728,4 +734,34 @@ int BIO_socket_nbio(int s, int mode)
 # endif
     return (ret == 0);
 }
 # endif
     return (ret == 0);
 }
+
+int BIO_sock_info(int sock,
+                  enum BIO_sock_info_type type, union BIO_sock_info_u *info)
+{
+    switch (type) {
+    case BIO_SOCK_INFO_ADDRESS:
+        {
+            socklen_t addr_len;
+            int ret = 0;
+            addr_len = sizeof(*info->addr);
+            ret = getsockname(sock, BIO_ADDR_sockaddr_noconst(info->addr),
+                              &addr_len);
+            if (ret == -1) {
+                SYSerr(SYS_F_GETSOCKNAME, get_last_socket_error());
+                BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_GETSOCKNAME_ERROR);
+                return 0;
+            }
+            if (addr_len > sizeof(*info->addr)) {
+                BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS);
+                return 0;
+            }
+        }
+        break;
+    default:
+        BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_UNKNOWN_INFO_TYPE);
+        return 0;
+    }
+    return 1;
+}
+
 #endif
 #endif
diff --git a/crypto/bio/b_sock2.c b/crypto/bio/b_sock2.c
new file mode 100644 (file)
index 0000000..4bf5cf3
--- /dev/null
@@ -0,0 +1,307 @@
+/* ====================================================================
+ * Copyright (c) 2015 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "bio_lcl.h"
+
+#include <openssl/err.h>
+
+#ifndef OPENSSL_NO_SOCK
+# ifdef SO_MAXCONN
+#  define MAX_LISTEN  SO_MAXCONN
+# elif defined(SOMAXCONN)
+#  define MAX_LISTEN  SOMAXCONN
+# else
+#  define MAX_LISTEN  32
+# endif
+
+/*-
+ * BIO_socket - create a socket
+ * @domain: the socket domain (AF_INET, AF_INET6, AF_UNIX, ...)
+ * @socktype: the socket type (SOCK_STEAM, SOCK_DGRAM)
+ * @protocol: the protocol to use (IPPROTO_TCP, IPPROTO_UDP)
+ * @options: BIO socket options (currently unused)
+ *
+ * Creates a socket.  This should be called before calling any
+ * of BIO_connect and BIO_listen.
+ *
+ * Returns the file descriptor on success or INVALID_SOCKET on failure.  On
+ * failure errno is set, and a status is added to the OpenSSL error stack.
+ */
+int BIO_socket(int domain, int socktype, int protocol, int options)
+{
+    int sock = -1;
+
+    if (BIO_sock_init() != 1)
+        return INVALID_SOCKET;
+
+    sock = socket(domain, socktype, protocol);
+    if (sock == -1) {
+        SYSerr(SYS_F_SOCKET, get_last_socket_error());
+        BIOerr(BIO_F_BIO_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET);
+        return INVALID_SOCKET;
+    }
+
+    return sock;
+}
+
+/*-
+ * BIO_connect - connect to an address
+ * @sock: the socket to connect with
+ * @addr: the address to connect to
+ * @options: BIO socket options
+ *
+ * Connects to the address using the given socket and options.
+ *
+ * Options can be a combination of the following:
+ * - BIO_SOCK_KEEPALIVE: enable regularly sending keep-alive messages.
+ * - BIO_SOCK_NONBLOCK: Make the socket non-blocking.
+ * - BIO_SOCK_NODELAY: don't delay small messages.
+ *
+ * options holds BIO socket options that can be used
+ * You should call this for every address returned by BIO_lookup
+ * until the connection is succesful.
+ *
+ * Returns 1 on success or 0 on failure.  On failure errno is set
+ * and an error status is added to the OpenSSL error stack.
+ */
+int BIO_connect(int sock, const BIO_ADDR *addr, int options)
+{
+    int on = 1;
+
+    if (sock == -1) {
+        BIOerr(BIO_F_BIO_CONNECT, BIO_R_INVALID_SOCKET);
+        return 0;
+    }
+
+    if (!BIO_socket_nbio(sock, (options & BIO_SOCK_NONBLOCK) != 0))
+        return 0;
+
+    if (options & BIO_SOCK_KEEPALIVE) {
+        if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) != 0) {
+            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
+            BIOerr(BIO_F_BIO_CONNECT, BIO_R_UNABLE_TO_KEEPALIVE);
+            return 0;
+        }
+    }
+
+    if (options & BIO_SOCK_NODELAY) {
+        if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) != 0) {
+            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
+            BIOerr(BIO_F_BIO_CONNECT, BIO_R_UNABLE_TO_NODELAY);
+            return 0;
+        }
+    }
+
+    if (connect(sock, BIO_ADDR_sockaddr(addr),
+                BIO_ADDR_sockaddr_size(addr)) == -1) {
+        SYSerr(SYS_F_CONNECT, get_last_socket_error());
+        BIOerr(BIO_F_BIO_CONNECT, BIO_R_CONNECT_ERROR);
+        return 0;
+    }
+    return 1;
+}
+
+/*-
+ * BIO_listen - Creates a listen socket
+ * @sock: the socket to listen with
+ * @addr: local address to bind to
+ * @options: BIO socket options
+ *
+ * Binds to the address using the given socket and options, then
+ * starts listening for incoming connections.
+ *
+ * Options can be a combination of the following:
+ * - BIO_SOCK_KEEPALIVE: enable regularly sending keep-alive messages.
+ * - BIO_SOCK_NONBLOCK: Make the socket non-blocking.
+ * - BIO_SOCK_NODELAY: don't delay small messages.
+ * - BIO_SOCK_REUSEADDR: Try to reuse the address and port combination
+ *   for a recently closed port.
+ * - BIO_SOCK_V6_ONLY: When creating an IPv6 socket, make it listen only
+ *   for IPv6 addresses and not IPv4 addresses mapped to IPv6.
+ *
+ * It's recommended that you set up both an IPv6 and IPv4 listen socket, and
+ * then check both for new clients that connect to it.  You want to set up
+ * the socket as non-blocking in that case since else it could hang.
+ *
+ * Not all operating systems support IPv4 addresses on an IPv6 socket, and for
+ * others it's an option.  If you pass the BIO_LISTEN_V6_ONLY it will try to
+ * create the IPv6 sockets to only listen for IPv6 connection.
+ *
+ * It could be that the first BIO_listen() call will listen to all the IPv6
+ * and IPv4 addresses and that then trying to bind to the IPv4 address will
+ * fail.  We can't tell the difference between already listening ourself to
+ * it and someone else listening to it when failing and errno is EADDRINUSE, so
+ * it's recommended to not give an error in that case if the first call was
+ * succesful.
+ *
+ * When restarting the program it could be that the port is still in use.  If
+ * you set to BIO_SOCK_REUSEADDR option it will try to reuse the port anyway.
+ * It's recommended that you use this.
+ */
+int BIO_listen(int sock, const BIO_ADDR *addr, int options)
+{
+    int on = 1;
+    int socktype;
+    socklen_t socktype_len = sizeof(socktype);
+
+    if (sock == -1) {
+        BIOerr(BIO_F_BIO_LISTEN, BIO_R_INVALID_SOCKET);
+        return 0;
+    }
+
+    if (getsockopt(sock, SOL_SOCKET, SO_TYPE, &socktype, &socktype_len) != 0
+        || socktype_len != sizeof(socktype)) {
+        SYSerr(SYS_F_GETSOCKOPT, get_last_socket_error());
+        BIOerr(BIO_F_BIO_LISTEN, BIO_R_GETTING_SOCKTYPE);
+        return 0;
+    }
+
+    if (!BIO_socket_nbio(sock, (options & BIO_SOCK_NONBLOCK) != 0))
+        return 0;
+
+# ifndef OPENSSL_SYS_WINDOWS
+    /* SO_REUSEADDR has different behavior on Windows than on
+     * other operating systems, don't set it there. */
+    if (options & BIO_SOCK_REUSEADDR) {
+        if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) {
+            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
+            BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_REUSEADDR);
+            return 0;
+        }
+    }
+# endif
+
+    if (options & BIO_SOCK_KEEPALIVE) {
+        if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) != 0) {
+            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
+            BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_KEEPALIVE);
+            return 0;
+        }
+    }
+
+    if (options & BIO_SOCK_NODELAY) {
+        if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) != 0) {
+            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
+            BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_NODELAY);
+            return 0;
+        }
+    }
+
+# ifdef IPV6_V6ONLY
+    if ((options & BIO_SOCK_V6_ONLY) && BIO_ADDR_family(addr) == AF_INET6) {
+        if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) != 0) {
+            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
+            BIOerr(BIO_F_BIO_LISTEN, BIO_R_LISTEN_V6_ONLY);
+            return 0;
+        }
+    }
+# endif
+
+    if (bind(sock, BIO_ADDR_sockaddr(addr), BIO_ADDR_sockaddr_size(addr)) != 0) {
+        SYSerr(SYS_F_BIND, get_last_socket_error());
+        BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_BIND_SOCKET);
+        return 0;
+    }
+
+    if (socktype != SOCK_DGRAM && listen(sock, MAX_LISTEN) == -1) {
+        SYSerr(SYS_F_LISTEN, get_last_socket_error());
+        BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_LISTEN_SOCKET);
+        return 0;
+    }
+
+    return 1;
+}
+
+/*-
+ * BIO_accept_ex - Accept new incoming connections
+ * @sock: the listening socket
+ * @addr: the BIO_ADDR to store the peer address in
+ * @options: BIO socket options, applied on the accepted socket.
+ *
+ */
+int BIO_accept_ex(int accept_sock, BIO_ADDR *addr, int options)
+{
+    socklen_t len;
+    int accepted_sock;
+
+    len = sizeof(*addr);
+    accepted_sock = accept(accept_sock,
+                           BIO_ADDR_sockaddr_noconst(addr), &len);
+    if (accepted_sock == -1) {
+        SYSerr(SYS_F_ACCEPT, get_last_socket_error());
+        BIOerr(BIO_F_BIO_ACCEPT_EX, BIO_R_ACCEPT_ERROR);
+        return INVALID_SOCKET;
+    }
+
+    if (!BIO_socket_nbio(accepted_sock, (options & BIO_SOCK_NONBLOCK) != 0))
+        return INVALID_SOCKET;
+
+    return accepted_sock;
+}
+
+/*-
+ * BIO_closesocket - Close a socket
+ * @sock: the socket to close
+ */
+int BIO_closesocket(int sock)
+{
+    if (closesocket(sock) < 0)
+        return 0;
+    return 1;
+}
+#endif
index 13757c2b21397296af066854df22d2461d5eee73..6cb582debee0d4a87613d3cff92d30acfae78a46 100644 (file)
@@ -175,6 +175,9 @@ static ERR_STRING_DATA ERR_str_functs[] = {
     {ERR_PACK(0, SYS_F_FREAD, 0), "fread"},
     {ERR_PACK(0, SYS_F_GETADDRINFO, 0), "getaddrinfo"},
     {ERR_PACK(0, SYS_F_GETNAMEINFO, 0), "getnameinfo"},
     {ERR_PACK(0, SYS_F_FREAD, 0), "fread"},
     {ERR_PACK(0, SYS_F_GETADDRINFO, 0), "getaddrinfo"},
     {ERR_PACK(0, SYS_F_GETNAMEINFO, 0), "getnameinfo"},
+    {ERR_PACK(0, SYS_F_SETSOCKOPT, 0), "setsockopt"},
+    {ERR_PACK(0, SYS_F_GETSOCKOPT, 0), "getsockopt"},
+    {ERR_PACK(0, SYS_F_GETSOCKNAME, 0), "getsockname"},
     {0, NULL},
 };
 
     {0, NULL},
 };
 
diff --git a/doc/crypto/BIO_connect.pod b/doc/crypto/BIO_connect.pod
new file mode 100644 (file)
index 0000000..4edb8ba
--- /dev/null
@@ -0,0 +1,101 @@
+=pod
+
+=head1 NAME
+
+BIO_socket, BIO_connect, BIO_listen, BIO_accept_ex, BIO_closesocket - BIO
+socket communication setup routines
+
+=head1 SYNOPSIS
+
+ #include <openssl/bio.h>
+
+ int BIO_socket(int domain, int socktype, int protocol, int options);
+ int BIO_connect(int sock, const BIO_ADDR *addr, int options);
+ int BIO_listen(int sock, const BIO_ADDR *addr, int options);
+ int BIO_accept_ex(int accept_sock, BIO_ADDR *peer, int options);
+ int BIO_closesocket(int sock);
+
+=head1 DESCRIPTION
+
+BIO_socket() creates a socket in the domain B<domain>, of type
+B<socktype> and B<protocol>.  Socket B<options> are currently unused,
+but is present for future use.
+
+BIO_connect() connects B<sock> to the address and service given by
+B<addr>.  Connection B<options> may be zero or any combination of
+B<BIO_SOCK_KEEPALIVE>, B<BIO_SOCK_NONBLOCK> and B<BIO_SOCK_NODELAY>.
+The flags are described in L</FLAGS> below.
+
+BIO_listen() has B<sock> start listening on the address and service
+given by B<addr>.  Connection B<options> may be zero or any
+combination of B<BIO_SOCK_KEEPALIVE>, B<BIO_SOCK_NONBLOCK>,
+B<BIO_SOCK_NODELAY>, B<BIO_SOCK_REUSEADDR> and B<BIO_SOCK_V6_ONLY>.
+The flags are described in L</FLAGS> below.
+
+BIO_accept_ex() waits for an incoming connections on the given
+socket B<accept_sock>.  When it gets a connection, the address and
+port of the peer gets stored in B<peer> if that one is non-NULL.
+Accept B<options> may be zero or B<BIO_SOCK_NONBLOCK>, and is applied
+on the accepted socket.  The flags are described in L</FLAGS> below.
+
+BIO_closesocket() closes B<sock>.
+
+=head1 FLAGS
+
+=over 4
+
+=item BIO_SOCK_KEEPALIVE
+
+Enables regular sending of keep-alive messages.
+
+=item BIO_SOCK_NONBLOCK
+
+Sets the socket to non-blocking mode.
+
+=item BIO_SOCK_NODELAY
+
+Corresponds to B<TCP_NODELAY>, and disables the Nagle algorithm.  With
+this set, any data will be sent as soon as possible instead of being
+buffered until there's enough for the socket to send out in one go.
+
+=item BIO_SOCK_REUSEADDR
+
+Try to reuse the address and port combination for a recently closed
+port.
+
+=item BIO_SOCK_V6_ONLY
+
+When creating an IPv6 socket, make it only listen for IPv6 addresses
+and not IPv4 addresses mapped to IPv6.
+
+=back
+
+These flags are bit flags, so they are to be combined with the
+C<|> operator, for example:
+
+  BIO_connect(sock, addr, BIO_SOCK_KEEPALIVE | BIO_SOCK_NONBLOCK);
+
+=head1 RETURN VALUES
+
+BIO_socket() returns the socket number on success or B<INVALID_SOCKET>
+(-1) on error.  When an error has occured, the OpenSSL error stack
+will hold the error data and errno has the system error.
+
+BIO_connect() and BIO_listen() return 1 on success or 0 on error.
+When an error has occured, the OpenSSL error stack will hold the error
+data and errno has the system error.
+
+BIO_accept_ex() returns the accepted socket on success or
+B<INVALID_SOCKET> (-1) on error.  When an error has occured, the
+OpenSSL error stack will hold the error data and errno has the system
+error.
+
+=head1 HISTORY
+
+BIO_gethostname(), BIO_get_port(), BIO_get_host_ip(),
+BIO_get_accept_socket() and BIO_accept() are deprecated since OpenSSL
+1.1.  Use the functions described above instead.
+
+=head1 SEE ALSO
+
+L<BIO_ADDR(3)>
index 82d48450f17e96829f554ca6c5b59490a276149d..be659c7c7aeecaab2e77bb70d5bb43e3dd4c8dc4 100644 (file)
@@ -731,27 +731,43 @@ enum BIO_lookup_type {
 int BIO_lookup(const char *host, const char *service,
                enum BIO_lookup_type lookup_type,
                int family, int socktype, BIO_ADDRINFO **res);
 int BIO_lookup(const char *host, const char *service,
                enum BIO_lookup_type lookup_type,
                int family, int socktype, BIO_ADDRINFO **res);
-struct hostent *BIO_gethostbyname(const char *name);
-/*-
- * We might want a thread-safe interface too:
- * struct hostent *BIO_gethostbyname_r(const char *name,
- *     struct hostent *result, void *buffer, size_t buflen);
- * or something similar (caller allocates a struct hostent,
- * pointed to by "result", and additional buffer space for the various
- * substructures; if the buffer does not suffice, NULL is returned
- * and an appropriate error code is set).
- */
 int BIO_sock_error(int sock);
 int BIO_socket_ioctl(int fd, long type, void *arg);
 int BIO_socket_nbio(int fd, int mode);
 int BIO_sock_error(int sock);
 int BIO_socket_ioctl(int fd, long type, void *arg);
 int BIO_socket_nbio(int fd, int mode);
-int BIO_get_port(const char *str, unsigned short *port_ptr);
-int BIO_get_host_ip(const char *str, unsigned char *ip);
-int BIO_get_accept_socket(char *host_port, int mode);
-int BIO_accept(int sock, char **ip_port);
 int BIO_sock_init(void);
 void BIO_sock_cleanup(void);
 int BIO_set_tcp_ndelay(int sock, int turn_on);
 
 int BIO_sock_init(void);
 void BIO_sock_cleanup(void);
 int BIO_set_tcp_ndelay(int sock, int turn_on);
 
+DEPRECATEDIN_1_1_0(struct hostent *BIO_gethostbyname(const char *name))
+DEPRECATEDIN_1_1_0(int BIO_get_port(const char *str, unsigned short *port_ptr))
+DEPRECATEDIN_1_1_0(int BIO_get_host_ip(const char *str, unsigned char *ip))
+DEPRECATEDIN_1_1_0(int BIO_get_accept_socket(char *host_port, int mode))
+DEPRECATEDIN_1_1_0(int BIO_accept(int sock, char **ip_port))
+
+union BIO_sock_info_u {
+    BIO_ADDR *addr;
+};
+enum BIO_sock_info_type {
+    BIO_SOCK_INFO_ADDRESS
+};
+int BIO_sock_info(int sock,
+                  enum BIO_sock_info_type type, union BIO_sock_info_u *info);
+
+# define BIO_SOCK_REUSEADDR    0x01
+# define BIO_SOCK_V6_ONLY      0x02
+# define BIO_SOCK_KEEPALIVE    0x04
+# define BIO_SOCK_NONBLOCK     0x08
+# define BIO_SOCK_NODELAY      0x10
+
+int BIO_socket(int domain, int socktype, int protocol, int options);
+int BIO_connect(int sock, const BIO_ADDR *addr, int options);
+int BIO_listen(int sock, const BIO_ADDR *addr, int options);
+int BIO_accept_ex(int accept_sock, BIO_ADDR *addr, int options);
+# if OPENSSL_API_COMPAT >= 0x10100000L
+#  define BIO_accept(as,s,a) BIO_accept_ex((as),(s),(a))
+# endif
+int BIO_closesocket(int sock);
+
 BIO *BIO_new_socket(int sock, int close_flag);
 BIO *BIO_new_dgram(int fd, int close_flag);
 # ifndef OPENSSL_NO_SCTP
 BIO *BIO_new_socket(int sock, int close_flag);
 BIO *BIO_new_dgram(int fd, int close_flag);
 # ifndef OPENSSL_NO_SCTP
index 0214e68c8764bbbe64d51c40682b9aca5140551a..370763c35ff0e2105574083c6f785abd3d34c9f6 100644 (file)
@@ -259,6 +259,9 @@ typedef struct err_state_st {
 # define SYS_F_FREAD             11
 # define SYS_F_GETADDRINFO       12
 # define SYS_F_GETNAMEINFO       13
 # define SYS_F_FREAD             11
 # define SYS_F_GETADDRINFO       12
 # define SYS_F_GETNAMEINFO       13
+# define SYS_F_SETSOCKOPT        14
+# define SYS_F_GETSOCKOPT        15
+# define SYS_F_GETSOCKNAME       16
 
 /* reasons */
 # define ERR_R_SYS_LIB   ERR_LIB_SYS/* 2 */
 
 /* reasons */
 # define ERR_R_SYS_LIB   ERR_LIB_SYS/* 2 */