Home | History | Annotate | Line # | Download | only in lib
      1  1.1  christos /*
      2  1.3  christos  * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
      3  1.1  christos  *
      4  1.1  christos  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  1.1  christos  * this file except in compliance with the License.  You can obtain a copy
      6  1.1  christos  * in the file LICENSE in the source distribution or at
      7  1.1  christos  * https://www.openssl.org/source/license.html
      8  1.1  christos  */
      9  1.1  christos 
     10  1.1  christos /* socket-related functions used by s_client and s_server */
     11  1.1  christos #include <stdio.h>
     12  1.1  christos #include <stdlib.h>
     13  1.1  christos #include <string.h>
     14  1.1  christos #include <errno.h>
     15  1.1  christos #include <signal.h>
     16  1.1  christos #include <openssl/opensslconf.h>
     17  1.1  christos 
     18  1.1  christos /*
     19  1.1  christos  * With IPv6, it looks like Digital has mixed up the proper order of
     20  1.1  christos  * recursive header file inclusion, resulting in the compiler complaining
     21  1.1  christos  * that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which is
     22  1.1  christos  * needed to have fileno() declared correctly...  So let's define u_int
     23  1.1  christos  */
     24  1.1  christos #if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
     25  1.1  christos # define __U_INT
     26  1.1  christos typedef unsigned int u_int;
     27  1.1  christos #endif
     28  1.1  christos 
     29  1.1  christos #ifdef _WIN32
     30  1.1  christos # include <process.h>
     31  1.1  christos 
     32  1.1  christos /* MSVC renamed some POSIX functions to have an underscore prefix. */
     33  1.1  christos # ifdef _MSC_VER
     34  1.1  christos #  define getpid _getpid
     35  1.1  christos # endif
     36  1.1  christos #endif
     37  1.1  christos 
     38  1.1  christos #ifndef OPENSSL_NO_SOCK
     39  1.1  christos 
     40  1.1  christos # include "apps.h"
     41  1.1  christos # include "s_apps.h"
     42  1.1  christos # include "internal/sockets.h"
     43  1.1  christos 
     44  1.1  christos # if defined(__TANDEM)
     45  1.1  christos #  if defined(OPENSSL_TANDEM_FLOSS)
     46  1.1  christos #   include <floss.h(floss_read)>
     47  1.1  christos #  endif
     48  1.1  christos # endif
     49  1.1  christos 
     50  1.1  christos # include <openssl/bio.h>
     51  1.1  christos # include <openssl/err.h>
     52  1.1  christos 
     53  1.1  christos /* Keep track of our peer's address for the cookie callback */
     54  1.1  christos BIO_ADDR *ourpeer = NULL;
     55  1.1  christos 
     56  1.1  christos /*
     57  1.1  christos  * init_client - helper routine to set up socket communication
     58  1.1  christos  * @sock: pointer to storage of resulting socket.
     59  1.1  christos  * @host: the host name or path (for AF_UNIX) to connect to.
     60  1.1  christos  * @port: the port to connect to (ignored for AF_UNIX).
     61  1.1  christos  * @bindhost: source host or path (for AF_UNIX).
     62  1.1  christos  * @bindport: source port (ignored for AF_UNIX).
     63  1.1  christos  * @family: desired socket family, may be AF_INET, AF_INET6, AF_UNIX or
     64  1.1  christos  *  AF_UNSPEC
     65  1.1  christos  * @type: socket type, must be SOCK_STREAM or SOCK_DGRAM
     66  1.1  christos  * @protocol: socket protocol, e.g. IPPROTO_TCP or IPPROTO_UDP (or 0 for any)
     67  1.1  christos  *
     68  1.1  christos  * This will create a socket and use it to connect to a host:port, or if
     69  1.1  christos  * family == AF_UNIX, to the path found in host.
     70  1.1  christos  *
     71  1.1  christos  * If the host has more than one address, it will try them one by one until
     72  1.1  christos  * a successful connection is established.  The resulting socket will be
     73  1.1  christos  * found in *sock on success, it will be given INVALID_SOCKET otherwise.
     74  1.1  christos  *
     75  1.1  christos  * Returns 1 on success, 0 on failure.
     76  1.1  christos  */
     77  1.1  christos int init_client(int *sock, const char *host, const char *port,
     78  1.1  christos                 const char *bindhost, const char *bindport,
     79  1.1  christos                 int family, int type, int protocol)
     80  1.1  christos {
     81  1.1  christos     BIO_ADDRINFO *res = NULL;
     82  1.1  christos     BIO_ADDRINFO *bindaddr = NULL;
     83  1.1  christos     const BIO_ADDRINFO *ai = NULL;
     84  1.1  christos     const BIO_ADDRINFO *bi = NULL;
     85  1.1  christos     int found = 0;
     86  1.1  christos     int ret;
     87  1.1  christos 
     88  1.1  christos     if (BIO_sock_init() != 1)
     89  1.1  christos         return 0;
     90  1.1  christos 
     91  1.1  christos     ret = BIO_lookup_ex(host, port, BIO_LOOKUP_CLIENT, family, type, protocol,
     92  1.1  christos                         &res);
     93  1.1  christos     if (ret == 0) {
     94  1.1  christos         ERR_print_errors(bio_err);
     95  1.1  christos         return 0;
     96  1.1  christos     }
     97  1.1  christos 
     98  1.1  christos     if (bindhost != NULL || bindport != NULL) {
     99  1.1  christos         ret = BIO_lookup_ex(bindhost, bindport, BIO_LOOKUP_CLIENT,
    100  1.1  christos                             family, type, protocol, &bindaddr);
    101  1.1  christos         if (ret == 0) {
    102  1.1  christos             ERR_print_errors (bio_err);
    103  1.1  christos             goto out;
    104  1.1  christos         }
    105  1.1  christos     }
    106  1.1  christos 
    107  1.1  christos     ret = 0;
    108  1.1  christos     for (ai = res; ai != NULL; ai = BIO_ADDRINFO_next(ai)) {
    109  1.1  christos         /* Admittedly, these checks are quite paranoid, we should not get
    110  1.1  christos          * anything in the BIO_ADDRINFO chain that we haven't
    111  1.1  christos          * asked for. */
    112  1.1  christos         OPENSSL_assert((family == AF_UNSPEC
    113  1.1  christos                         || family == BIO_ADDRINFO_family(ai))
    114  1.1  christos                        && (type == 0 || type == BIO_ADDRINFO_socktype(ai))
    115  1.1  christos                        && (protocol == 0
    116  1.1  christos                            || protocol == BIO_ADDRINFO_protocol(ai)));
    117  1.1  christos 
    118  1.1  christos         if (bindaddr != NULL) {
    119  1.1  christos             for (bi = bindaddr; bi != NULL; bi = BIO_ADDRINFO_next(bi)) {
    120  1.1  christos                 if (BIO_ADDRINFO_family(bi) == BIO_ADDRINFO_family(ai))
    121  1.1  christos                     break;
    122  1.1  christos             }
    123  1.1  christos             if (bi == NULL)
    124  1.1  christos                 continue;
    125  1.1  christos             ++found;
    126  1.1  christos         }
    127  1.1  christos 
    128  1.1  christos         *sock = BIO_socket(BIO_ADDRINFO_family(ai), BIO_ADDRINFO_socktype(ai),
    129  1.1  christos                            BIO_ADDRINFO_protocol(ai), 0);
    130  1.1  christos         if (*sock == INVALID_SOCKET) {
    131  1.1  christos             /* Maybe the kernel doesn't support the socket family, even if
    132  1.1  christos              * BIO_lookup() added it in the returned result...
    133  1.1  christos              */
    134  1.1  christos             continue;
    135  1.1  christos         }
    136  1.1  christos 
    137  1.1  christos         if (bi != NULL) {
    138  1.1  christos             if (!BIO_bind(*sock, BIO_ADDRINFO_address(bi),
    139  1.1  christos                           BIO_SOCK_REUSEADDR)) {
    140  1.1  christos                 BIO_closesocket(*sock);
    141  1.1  christos                 *sock = INVALID_SOCKET;
    142  1.1  christos                 break;
    143  1.1  christos             }
    144  1.1  christos         }
    145  1.1  christos 
    146  1.1  christos #ifndef OPENSSL_NO_SCTP
    147  1.1  christos         if (protocol == IPPROTO_SCTP) {
    148  1.1  christos             /*
    149  1.1  christos              * For SCTP we have to set various options on the socket prior to
    150  1.1  christos              * connecting. This is done automatically by BIO_new_dgram_sctp().
    151  1.1  christos              * We don't actually need the created BIO though so we free it again
    152  1.1  christos              * immediately.
    153  1.1  christos              */
    154  1.1  christos             BIO *tmpbio = BIO_new_dgram_sctp(*sock, BIO_NOCLOSE);
    155  1.1  christos 
    156  1.1  christos             if (tmpbio == NULL) {
    157  1.1  christos                 ERR_print_errors(bio_err);
    158  1.1  christos                 return 0;
    159  1.1  christos             }
    160  1.1  christos             BIO_free(tmpbio);
    161  1.1  christos         }
    162  1.1  christos #endif
    163  1.1  christos 
    164  1.1  christos         if (!BIO_connect(*sock, BIO_ADDRINFO_address(ai),
    165  1.1  christos                          BIO_ADDRINFO_protocol(ai) == IPPROTO_TCP ? BIO_SOCK_NODELAY : 0)) {
    166  1.1  christos             BIO_closesocket(*sock);
    167  1.1  christos             *sock = INVALID_SOCKET;
    168  1.1  christos             continue;
    169  1.1  christos         }
    170  1.1  christos 
    171  1.1  christos         /* Success, don't try any more addresses */
    172  1.1  christos         break;
    173  1.1  christos     }
    174  1.1  christos 
    175  1.1  christos     if (*sock == INVALID_SOCKET) {
    176  1.1  christos         if (bindaddr != NULL && !found) {
    177  1.1  christos             BIO_printf(bio_err, "Can't bind %saddress for %s%s%s\n",
    178  1.1  christos #ifdef AF_INET6
    179  1.1  christos                        BIO_ADDRINFO_family(res) == AF_INET6 ? "IPv6 " :
    180  1.1  christos #endif
    181  1.1  christos                        BIO_ADDRINFO_family(res) == AF_INET ? "IPv4 " :
    182  1.1  christos                        BIO_ADDRINFO_family(res) == AF_UNIX ? "unix " : "",
    183  1.1  christos                        bindhost != NULL ? bindhost : "",
    184  1.1  christos                        bindport != NULL ? ":" : "",
    185  1.1  christos                        bindport != NULL ? bindport : "");
    186  1.1  christos             ERR_clear_error();
    187  1.1  christos             ret = 0;
    188  1.1  christos         }
    189  1.1  christos         ERR_print_errors(bio_err);
    190  1.1  christos     } else {
    191  1.1  christos         /* Remove any stale errors from previous connection attempts */
    192  1.1  christos         ERR_clear_error();
    193  1.1  christos         ret = 1;
    194  1.1  christos     }
    195  1.1  christos out:
    196  1.1  christos     if (bindaddr != NULL) {
    197  1.1  christos         BIO_ADDRINFO_free (bindaddr);
    198  1.1  christos     }
    199  1.1  christos     BIO_ADDRINFO_free(res);
    200  1.1  christos     return ret;
    201  1.1  christos }
    202  1.1  christos 
    203  1.1  christos int report_server_accept(BIO *out, int asock, int with_address, int with_pid)
    204  1.1  christos {
    205  1.1  christos     int success = 1;
    206  1.1  christos 
    207  1.1  christos     if (BIO_printf(out, "ACCEPT") <= 0)
    208  1.1  christos         return 0;
    209  1.1  christos     if (with_address) {
    210  1.1  christos         union BIO_sock_info_u info;
    211  1.1  christos         char *hostname = NULL;
    212  1.1  christos         char *service = NULL;
    213  1.1  christos 
    214  1.1  christos         if ((info.addr = BIO_ADDR_new()) != NULL
    215  1.1  christos             && BIO_sock_info(asock, BIO_SOCK_INFO_ADDRESS, &info)
    216  1.1  christos             && (hostname = BIO_ADDR_hostname_string(info.addr, 1)) != NULL
    217  1.1  christos             && (service = BIO_ADDR_service_string(info.addr, 1)) != NULL) {
    218  1.1  christos             success = BIO_printf(out,
    219  1.1  christos                                  strchr(hostname, ':') == NULL
    220  1.1  christos                                  ? /* IPv4 */ " %s:%s"
    221  1.1  christos                                  : /* IPv6 */ " [%s]:%s",
    222  1.1  christos                                  hostname, service) > 0;
    223  1.1  christos         } else {
    224  1.1  christos             (void)BIO_printf(out, "unknown:error\n");
    225  1.1  christos             success = 0;
    226  1.1  christos         }
    227  1.1  christos         OPENSSL_free(hostname);
    228  1.1  christos         OPENSSL_free(service);
    229  1.1  christos         BIO_ADDR_free(info.addr);
    230  1.1  christos     }
    231  1.1  christos     if (with_pid)
    232  1.1  christos         success = success && BIO_printf(out, " PID=%d", getpid()) > 0;
    233  1.1  christos     success = success && BIO_printf(out, "\n") > 0;
    234  1.1  christos     (void)BIO_flush(out);
    235  1.1  christos 
    236  1.1  christos     return success;
    237  1.1  christos }
    238  1.1  christos 
    239  1.1  christos /*
    240  1.1  christos  * do_server - helper routine to perform a server operation
    241  1.1  christos  * @accept_sock: pointer to storage of resulting socket.
    242  1.1  christos  * @host: the host name or path (for AF_UNIX) to connect to.
    243  1.1  christos  * @port: the port to connect to (ignored for AF_UNIX).
    244  1.1  christos  * @family: desired socket family, may be AF_INET, AF_INET6, AF_UNIX or
    245  1.1  christos  *  AF_UNSPEC
    246  1.1  christos  * @type: socket type, must be SOCK_STREAM or SOCK_DGRAM
    247  1.1  christos  * @cb: pointer to a function that receives the accepted socket and
    248  1.1  christos  *  should perform the communication with the connecting client.
    249  1.1  christos  * @context: pointer to memory that's passed verbatim to the cb function.
    250  1.1  christos  * @naccept: number of times an incoming connect should be accepted.  If -1,
    251  1.1  christos  *  unlimited number.
    252  1.1  christos  *
    253  1.1  christos  * This will create a socket and use it to listen to a host:port, or if
    254  1.1  christos  * family == AF_UNIX, to the path found in host, then start accepting
    255  1.1  christos  * incoming connections and run cb on the resulting socket.
    256  1.1  christos  *
    257  1.1  christos  * 0 on failure, something other on success.
    258  1.1  christos  */
    259  1.1  christos int do_server(int *accept_sock, const char *host, const char *port,
    260  1.1  christos               int family, int type, int protocol, do_server_cb cb,
    261  1.1  christos               unsigned char *context, int naccept, BIO *bio_s_out)
    262  1.1  christos {
    263  1.1  christos     int asock = 0;
    264  1.1  christos     int sock;
    265  1.1  christos     int i;
    266  1.1  christos     BIO_ADDRINFO *res = NULL;
    267  1.1  christos     const BIO_ADDRINFO *next;
    268  1.1  christos     int sock_family, sock_type, sock_protocol, sock_port;
    269  1.1  christos     const BIO_ADDR *sock_address;
    270  1.1  christos     int sock_family_fallback = AF_UNSPEC;
    271  1.1  christos     const BIO_ADDR *sock_address_fallback = NULL;
    272  1.1  christos     int sock_options = BIO_SOCK_REUSEADDR;
    273  1.1  christos     int ret = 0;
    274  1.1  christos 
    275  1.1  christos     if (BIO_sock_init() != 1)
    276  1.1  christos         return 0;
    277  1.1  christos 
    278  1.1  christos     if (!BIO_lookup_ex(host, port, BIO_LOOKUP_SERVER, family, type, protocol,
    279  1.1  christos                        &res)) {
    280  1.1  christos         ERR_print_errors(bio_err);
    281  1.1  christos         return 0;
    282  1.1  christos     }
    283  1.1  christos 
    284  1.1  christos     /* Admittedly, these checks are quite paranoid, we should not get
    285  1.1  christos      * anything in the BIO_ADDRINFO chain that we haven't asked for */
    286  1.1  christos     OPENSSL_assert((family == AF_UNSPEC || family == BIO_ADDRINFO_family(res))
    287  1.1  christos                    && (type == 0 || type == BIO_ADDRINFO_socktype(res))
    288  1.1  christos                    && (protocol == 0 || protocol == BIO_ADDRINFO_protocol(res)));
    289  1.1  christos 
    290  1.1  christos     sock_family = BIO_ADDRINFO_family(res);
    291  1.1  christos     sock_type = BIO_ADDRINFO_socktype(res);
    292  1.1  christos     sock_protocol = BIO_ADDRINFO_protocol(res);
    293  1.1  christos     sock_address = BIO_ADDRINFO_address(res);
    294  1.1  christos     next = BIO_ADDRINFO_next(res);
    295  1.1  christos #ifdef AF_INET6
    296  1.1  christos     if (sock_family == AF_INET6)
    297  1.1  christos         sock_options |= BIO_SOCK_V6_ONLY;
    298  1.1  christos     if (next != NULL
    299  1.1  christos             && BIO_ADDRINFO_socktype(next) == sock_type
    300  1.1  christos             && BIO_ADDRINFO_protocol(next) == sock_protocol) {
    301  1.1  christos         if (sock_family == AF_INET
    302  1.1  christos                 && BIO_ADDRINFO_family(next) == AF_INET6) {
    303  1.1  christos             /* In case AF_INET6 is returned but not supported by the
    304  1.1  christos              * kernel, retry with the first detected address family */
    305  1.1  christos             sock_family_fallback = sock_family;
    306  1.1  christos             sock_address_fallback = sock_address;
    307  1.1  christos             sock_family = AF_INET6;
    308  1.1  christos             sock_address = BIO_ADDRINFO_address(next);
    309  1.1  christos         } else if (sock_family == AF_INET6
    310  1.1  christos                    && BIO_ADDRINFO_family(next) == AF_INET) {
    311  1.1  christos             sock_options &= ~BIO_SOCK_V6_ONLY;
    312  1.1  christos         }
    313  1.1  christos     }
    314  1.1  christos #endif
    315  1.1  christos 
    316  1.1  christos     asock = BIO_socket(sock_family, sock_type, sock_protocol, 0);
    317  1.1  christos     if (asock == INVALID_SOCKET && sock_family_fallback != AF_UNSPEC) {
    318  1.1  christos         asock = BIO_socket(sock_family_fallback, sock_type, sock_protocol, 0);
    319  1.1  christos         sock_address = sock_address_fallback;
    320  1.1  christos     }
    321  1.1  christos     if (asock == INVALID_SOCKET
    322  1.1  christos         || !BIO_listen(asock, sock_address, sock_options)) {
    323  1.1  christos         BIO_ADDRINFO_free(res);
    324  1.1  christos         ERR_print_errors(bio_err);
    325  1.1  christos         if (asock != INVALID_SOCKET)
    326  1.1  christos             BIO_closesocket(asock);
    327  1.1  christos         goto end;
    328  1.1  christos     }
    329  1.1  christos 
    330  1.1  christos #ifndef OPENSSL_NO_SCTP
    331  1.1  christos     if (protocol == IPPROTO_SCTP) {
    332  1.1  christos         /*
    333  1.1  christos          * For SCTP we have to set various options on the socket prior to
    334  1.1  christos          * accepting. This is done automatically by BIO_new_dgram_sctp().
    335  1.1  christos          * We don't actually need the created BIO though so we free it again
    336  1.1  christos          * immediately.
    337  1.1  christos          */
    338  1.1  christos         BIO *tmpbio = BIO_new_dgram_sctp(asock, BIO_NOCLOSE);
    339  1.1  christos 
    340  1.1  christos         if (tmpbio == NULL) {
    341  1.1  christos             BIO_closesocket(asock);
    342  1.1  christos             ERR_print_errors(bio_err);
    343  1.1  christos             goto end;
    344  1.1  christos         }
    345  1.1  christos         BIO_free(tmpbio);
    346  1.1  christos     }
    347  1.1  christos #endif
    348  1.1  christos 
    349  1.1  christos     sock_port = BIO_ADDR_rawport(sock_address);
    350  1.1  christos 
    351  1.1  christos     BIO_ADDRINFO_free(res);
    352  1.1  christos     res = NULL;
    353  1.1  christos 
    354  1.1  christos     if (!report_server_accept(bio_s_out, asock, sock_port == 0, 0)) {
    355  1.1  christos         BIO_closesocket(asock);
    356  1.1  christos         ERR_print_errors(bio_err);
    357  1.1  christos         goto end;
    358  1.1  christos     }
    359  1.1  christos 
    360  1.1  christos     if (accept_sock != NULL)
    361  1.1  christos         *accept_sock = asock;
    362  1.1  christos     for (;;) {
    363  1.1  christos         char sink[64];
    364  1.1  christos         struct timeval timeout;
    365  1.1  christos         fd_set readfds;
    366  1.1  christos 
    367  1.1  christos         if (type == SOCK_STREAM) {
    368  1.1  christos             BIO_ADDR_free(ourpeer);
    369  1.1  christos             ourpeer = BIO_ADDR_new();
    370  1.1  christos             if (ourpeer == NULL) {
    371  1.1  christos                 BIO_closesocket(asock);
    372  1.1  christos                 ERR_print_errors(bio_err);
    373  1.1  christos                 goto end;
    374  1.1  christos             }
    375  1.1  christos             do {
    376  1.1  christos                 sock = BIO_accept_ex(asock, ourpeer, 0);
    377  1.1  christos             } while (sock < 0 && BIO_sock_should_retry(sock));
    378  1.1  christos             if (sock < 0) {
    379  1.1  christos                 ERR_print_errors(bio_err);
    380  1.1  christos                 BIO_closesocket(asock);
    381  1.1  christos                 break;
    382  1.1  christos             }
    383  1.3  christos 
    384  1.3  christos             if (naccept != -1)
    385  1.3  christos                 naccept--;
    386  1.3  christos             if (naccept == 0)
    387  1.3  christos                 BIO_closesocket(asock);
    388  1.3  christos 
    389  1.1  christos             BIO_set_tcp_ndelay(sock, 1);
    390  1.1  christos             i = (*cb)(sock, type, protocol, context);
    391  1.1  christos 
    392  1.1  christos             /*
    393  1.1  christos              * If we ended with an alert being sent, but still with data in the
    394  1.1  christos              * network buffer to be read, then calling BIO_closesocket() will
    395  1.1  christos              * result in a TCP-RST being sent. On some platforms (notably
    396  1.1  christos              * Windows) then this will result in the peer immediately abandoning
    397  1.1  christos              * the connection including any buffered alert data before it has
    398  1.1  christos              * had a chance to be read. Shutting down the sending side first,
    399  1.1  christos              * and then closing the socket sends TCP-FIN first followed by
    400  1.1  christos              * TCP-RST. This seems to allow the peer to read the alert data.
    401  1.1  christos              */
    402  1.1  christos             shutdown(sock, 1); /* SHUT_WR */
    403  1.1  christos             /*
    404  1.1  christos              * We just said we have nothing else to say, but it doesn't mean
    405  1.1  christos              * that the other side has nothing. It's even recommended to
    406  1.1  christos              * consume incoming data. [In testing context this ensures that
    407  1.1  christos              * alerts are passed on...]
    408  1.1  christos              */
    409  1.1  christos             timeout.tv_sec = 0;
    410  1.1  christos             timeout.tv_usec = 500000;  /* some extreme round-trip */
    411  1.1  christos             do {
    412  1.1  christos                 FD_ZERO(&readfds);
    413  1.1  christos                 openssl_fdset(sock, &readfds);
    414  1.1  christos             } while (select(sock + 1, &readfds, NULL, NULL, &timeout) > 0
    415  1.1  christos                      && readsocket(sock, sink, sizeof(sink)) > 0);
    416  1.1  christos 
    417  1.1  christos             BIO_closesocket(sock);
    418  1.1  christos         } else {
    419  1.3  christos             if (naccept != -1)
    420  1.3  christos                 naccept--;
    421  1.3  christos 
    422  1.1  christos             i = (*cb)(asock, type, protocol, context);
    423  1.1  christos         }
    424  1.1  christos 
    425  1.1  christos         if (i < 0 || naccept == 0) {
    426  1.1  christos             BIO_closesocket(asock);
    427  1.1  christos             ret = i;
    428  1.1  christos             break;
    429  1.1  christos         }
    430  1.1  christos     }
    431  1.1  christos  end:
    432  1.1  christos # ifdef AF_UNIX
    433  1.1  christos     if (family == AF_UNIX)
    434  1.1  christos         unlink(host);
    435  1.1  christos # endif
    436  1.1  christos     BIO_ADDR_free(ourpeer);
    437  1.1  christos     ourpeer = NULL;
    438  1.1  christos     return ret;
    439  1.1  christos }
    440  1.1  christos 
    441  1.1  christos void do_ssl_shutdown(SSL *ssl)
    442  1.1  christos {
    443  1.1  christos     int ret;
    444  1.1  christos 
    445  1.1  christos     do {
    446  1.1  christos         /* We only do unidirectional shutdown */
    447  1.1  christos         ret = SSL_shutdown(ssl);
    448  1.1  christos         if (ret < 0) {
    449  1.1  christos             switch (SSL_get_error(ssl, ret)) {
    450  1.1  christos             case SSL_ERROR_WANT_READ:
    451  1.1  christos             case SSL_ERROR_WANT_WRITE:
    452  1.1  christos             case SSL_ERROR_WANT_ASYNC:
    453  1.1  christos             case SSL_ERROR_WANT_ASYNC_JOB:
    454  1.1  christos                 /* We just do busy waiting. Nothing clever */
    455  1.1  christos                 continue;
    456  1.1  christos             }
    457  1.1  christos             ret = 0;
    458  1.1  christos         }
    459  1.1  christos     } while (ret < 0);
    460  1.1  christos }
    461  1.1  christos 
    462  1.1  christos #endif  /* OPENSSL_NO_SOCK */
    463