aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/openssl/crypto/bio
diff options
context:
space:
mode:
authordeshevoy <deshevoy@yandex-team.ru>2022-02-10 16:46:57 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:46:57 +0300
commit28148f76dbfcc644d96427d41c92f36cbf2fdc6e (patch)
treeb83306b6e37edeea782e9eed673d89286c4fef35 /contrib/libs/openssl/crypto/bio
parente988f30484abe5fdeedcc7a5d3c226c01a21800c (diff)
downloadydb-28148f76dbfcc644d96427d41c92f36cbf2fdc6e.tar.gz
Restoring authorship annotation for <deshevoy@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/openssl/crypto/bio')
-rw-r--r--contrib/libs/openssl/crypto/bio/b_addr.c1792
-rw-r--r--contrib/libs/openssl/crypto/bio/b_dump.c290
-rw-r--r--contrib/libs/openssl/crypto/bio/b_print.c1854
-rw-r--r--contrib/libs/openssl/crypto/bio/b_sock.c736
-rw-r--r--contrib/libs/openssl/crypto/bio/b_sock2.c628
-rw-r--r--contrib/libs/openssl/crypto/bio/bf_buff.c948
-rw-r--r--contrib/libs/openssl/crypto/bio/bf_lbuf.c650
-rw-r--r--contrib/libs/openssl/crypto/bio/bf_nbio.c398
-rw-r--r--contrib/libs/openssl/crypto/bio/bf_null.c242
-rw-r--r--contrib/libs/openssl/crypto/bio/bio_cb.c194
-rw-r--r--contrib/libs/openssl/crypto/bio/bio_err.c290
-rw-r--r--contrib/libs/openssl/crypto/bio/bio_lib.c1570
-rw-r--r--contrib/libs/openssl/crypto/bio/bio_meth.c438
-rw-r--r--contrib/libs/openssl/crypto/bio/bss_acpt.c1098
-rw-r--r--contrib/libs/openssl/crypto/bio/bss_bio.c1614
-rw-r--r--contrib/libs/openssl/crypto/bio/bss_conn.c1060
-rw-r--r--contrib/libs/openssl/crypto/bio/bss_dgram.c3844
-rw-r--r--contrib/libs/openssl/crypto/bio/bss_fd.c556
-rw-r--r--contrib/libs/openssl/crypto/bio/bss_file.c788
-rw-r--r--contrib/libs/openssl/crypto/bio/bss_log.c830
-rw-r--r--contrib/libs/openssl/crypto/bio/bss_mem.c688
-rw-r--r--contrib/libs/openssl/crypto/bio/bss_null.c172
-rw-r--r--contrib/libs/openssl/crypto/bio/bss_sock.c462
23 files changed, 10571 insertions, 10571 deletions
diff --git a/contrib/libs/openssl/crypto/bio/b_addr.c b/contrib/libs/openssl/crypto/bio/b_addr.c
index f836b64103..8ea32bce40 100644
--- a/contrib/libs/openssl/crypto/bio/b_addr.c
+++ b/contrib/libs/openssl/crypto/bio/b_addr.c
@@ -1,724 +1,724 @@
-/*
+/*
* Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
-#include <assert.h>
-#include <string.h>
-
+#include <assert.h>
+#include <string.h>
+
#include "bio_local.h"
-#include <openssl/crypto.h>
-
-#ifndef OPENSSL_NO_SOCK
-#include <openssl/err.h>
-#include <openssl/buffer.h>
-#include "internal/thread_once.h"
-
-CRYPTO_RWLOCK *bio_lookup_lock;
-static CRYPTO_ONCE bio_lookup_init = CRYPTO_ONCE_STATIC_INIT;
-
-/*
+#include <openssl/crypto.h>
+
+#ifndef OPENSSL_NO_SOCK
+#include <openssl/err.h>
+#include <openssl/buffer.h>
+#include "internal/thread_once.h"
+
+CRYPTO_RWLOCK *bio_lookup_lock;
+static CRYPTO_ONCE bio_lookup_init = CRYPTO_ONCE_STATIC_INIT;
+
+/*
* Throughout this file and bio_local.h, the existence of the macro
- * AI_PASSIVE is used to detect the availability of struct addrinfo,
- * getnameinfo() and getaddrinfo(). If that macro doesn't exist,
- * we use our own implementation instead, using gethostbyname,
- * getservbyname and a few other.
- */
-
-/**********************************************************************
- *
- * Address structure
- *
- */
-
-BIO_ADDR *BIO_ADDR_new(void)
-{
- BIO_ADDR *ret = OPENSSL_zalloc(sizeof(*ret));
-
- if (ret == NULL) {
- BIOerr(BIO_F_BIO_ADDR_NEW, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
-
- ret->sa.sa_family = AF_UNSPEC;
- return ret;
-}
-
-void BIO_ADDR_free(BIO_ADDR *ap)
-{
- OPENSSL_free(ap);
-}
-
-void BIO_ADDR_clear(BIO_ADDR *ap)
-{
- memset(ap, 0, sizeof(*ap));
- ap->sa.sa_family = AF_UNSPEC;
-}
-
-/*
- * BIO_ADDR_make - non-public routine to fill a BIO_ADDR with the contents
- * of a struct sockaddr.
- */
-int BIO_ADDR_make(BIO_ADDR *ap, const struct sockaddr *sa)
-{
- if (sa->sa_family == AF_INET) {
- memcpy(&(ap->s_in), sa, sizeof(struct sockaddr_in));
- return 1;
- }
-#ifdef AF_INET6
- if (sa->sa_family == AF_INET6) {
- memcpy(&(ap->s_in6), sa, sizeof(struct sockaddr_in6));
- return 1;
- }
-#endif
-#ifdef AF_UNIX
- if (sa->sa_family == AF_UNIX) {
- memcpy(&(ap->s_un), sa, sizeof(struct sockaddr_un));
- return 1;
- }
-#endif
-
- return 0;
-}
-
-int BIO_ADDR_rawmake(BIO_ADDR *ap, int family,
- const void *where, size_t wherelen,
- unsigned short port)
-{
-#ifdef AF_UNIX
- if (family == AF_UNIX) {
- if (wherelen + 1 > sizeof(ap->s_un.sun_path))
- return 0;
- memset(&ap->s_un, 0, sizeof(ap->s_un));
- ap->s_un.sun_family = family;
- strncpy(ap->s_un.sun_path, where, sizeof(ap->s_un.sun_path) - 1);
- return 1;
- }
-#endif
- if (family == AF_INET) {
- if (wherelen != sizeof(struct in_addr))
- return 0;
- memset(&ap->s_in, 0, sizeof(ap->s_in));
- ap->s_in.sin_family = family;
- ap->s_in.sin_port = port;
- ap->s_in.sin_addr = *(struct in_addr *)where;
- return 1;
- }
-#ifdef AF_INET6
- if (family == AF_INET6) {
- if (wherelen != sizeof(struct in6_addr))
- return 0;
- memset(&ap->s_in6, 0, sizeof(ap->s_in6));
- ap->s_in6.sin6_family = family;
- ap->s_in6.sin6_port = port;
- ap->s_in6.sin6_addr = *(struct in6_addr *)where;
- return 1;
- }
-#endif
-
- return 0;
-}
-
-int BIO_ADDR_family(const BIO_ADDR *ap)
-{
- return ap->sa.sa_family;
-}
-
-int BIO_ADDR_rawaddress(const BIO_ADDR *ap, void *p, size_t *l)
-{
- size_t len = 0;
- const void *addrptr = NULL;
-
- if (ap->sa.sa_family == AF_INET) {
- len = sizeof(ap->s_in.sin_addr);
- addrptr = &ap->s_in.sin_addr;
- }
-#ifdef AF_INET6
- else if (ap->sa.sa_family == AF_INET6) {
- len = sizeof(ap->s_in6.sin6_addr);
- addrptr = &ap->s_in6.sin6_addr;
- }
-#endif
-#ifdef AF_UNIX
- else if (ap->sa.sa_family == AF_UNIX) {
- len = strlen(ap->s_un.sun_path);
- addrptr = &ap->s_un.sun_path;
- }
-#endif
-
- if (addrptr == NULL)
- return 0;
-
- if (p != NULL) {
- memcpy(p, addrptr, len);
- }
- if (l != NULL)
- *l = len;
-
- return 1;
-}
-
-unsigned short BIO_ADDR_rawport(const BIO_ADDR *ap)
-{
- if (ap->sa.sa_family == AF_INET)
- return ap->s_in.sin_port;
-#ifdef AF_INET6
- if (ap->sa.sa_family == AF_INET6)
- return ap->s_in6.sin6_port;
-#endif
- return 0;
-}
-
-/*-
- * addr_strings - helper function to get host and service names
- * @ap: the BIO_ADDR that has the input info
- * @numeric: 0 if actual names should be returned, 1 if the numeric
- * representation should be returned.
- * @hostname: a pointer to a pointer to a memory area to store the
- * host name or numeric representation. Unused if NULL.
- * @service: a pointer to a pointer to a memory area to store the
- * service name or numeric representation. Unused if NULL.
- *
- * The return value is 0 on failure, with the error code in the error
- * stack, and 1 on success.
- */
-static int addr_strings(const BIO_ADDR *ap, int numeric,
- char **hostname, char **service)
-{
- if (BIO_sock_init() != 1)
- return 0;
-
- if (1) {
-#ifdef AI_PASSIVE
- int ret = 0;
- char host[NI_MAXHOST] = "", serv[NI_MAXSERV] = "";
- int flags = 0;
-
- if (numeric)
- flags |= NI_NUMERICHOST | NI_NUMERICSERV;
-
- if ((ret = getnameinfo(BIO_ADDR_sockaddr(ap),
- BIO_ADDR_sockaddr_size(ap),
- host, sizeof(host), serv, sizeof(serv),
- flags)) != 0) {
-# ifdef EAI_SYSTEM
- if (ret == EAI_SYSTEM) {
- SYSerr(SYS_F_GETNAMEINFO, get_last_socket_error());
- BIOerr(BIO_F_ADDR_STRINGS, ERR_R_SYS_LIB);
- } else
-# endif
- {
- BIOerr(BIO_F_ADDR_STRINGS, ERR_R_SYS_LIB);
- ERR_add_error_data(1, gai_strerror(ret));
- }
- return 0;
- }
-
- /* VMS getnameinfo() has a bug, it doesn't fill in serv, which
- * leaves it with whatever garbage that happens to be there.
- * However, we initialise serv with the empty string (serv[0]
- * is therefore NUL), so it gets real easy to detect when things
- * didn't go the way one might expect.
- */
- if (serv[0] == '\0') {
- BIO_snprintf(serv, sizeof(serv), "%d",
- ntohs(BIO_ADDR_rawport(ap)));
- }
-
- if (hostname != NULL)
- *hostname = OPENSSL_strdup(host);
- if (service != NULL)
- *service = OPENSSL_strdup(serv);
- } else {
-#endif
- if (hostname != NULL)
- *hostname = OPENSSL_strdup(inet_ntoa(ap->s_in.sin_addr));
- if (service != NULL) {
- char serv[6]; /* port is 16 bits => max 5 decimal digits */
- BIO_snprintf(serv, sizeof(serv), "%d", ntohs(ap->s_in.sin_port));
- *service = OPENSSL_strdup(serv);
- }
- }
-
- if ((hostname != NULL && *hostname == NULL)
- || (service != NULL && *service == NULL)) {
- if (hostname != NULL) {
- OPENSSL_free(*hostname);
- *hostname = NULL;
- }
- if (service != NULL) {
- OPENSSL_free(*service);
- *service = NULL;
- }
- BIOerr(BIO_F_ADDR_STRINGS, ERR_R_MALLOC_FAILURE);
- return 0;
- }
-
- return 1;
-}
-
-char *BIO_ADDR_hostname_string(const BIO_ADDR *ap, int numeric)
-{
- char *hostname = NULL;
-
- if (addr_strings(ap, numeric, &hostname, NULL))
- return hostname;
-
- return NULL;
-}
-
-char *BIO_ADDR_service_string(const BIO_ADDR *ap, int numeric)
-{
- char *service = NULL;
-
- if (addr_strings(ap, numeric, NULL, &service))
- return service;
-
- return NULL;
-}
-
-char *BIO_ADDR_path_string(const BIO_ADDR *ap)
-{
-#ifdef AF_UNIX
- if (ap->sa.sa_family == AF_UNIX)
- return OPENSSL_strdup(ap->s_un.sun_path);
-#endif
- return NULL;
-}
-
-/*
- * BIO_ADDR_sockaddr - non-public routine to return the struct sockaddr
- * for a given BIO_ADDR. In reality, this is simply a type safe cast.
- * The returned struct sockaddr is const, so it can't be tampered with.
- */
-const struct sockaddr *BIO_ADDR_sockaddr(const BIO_ADDR *ap)
-{
- return &(ap->sa);
-}
-
-/*
- * BIO_ADDR_sockaddr_noconst - non-public function that does the same
- * as BIO_ADDR_sockaddr, but returns a non-const. USE WITH CARE, as
- * it allows you to tamper with the data (and thereby the contents
- * of the input BIO_ADDR).
- */
-struct sockaddr *BIO_ADDR_sockaddr_noconst(BIO_ADDR *ap)
-{
- return &(ap->sa);
-}
-
-/*
- * BIO_ADDR_sockaddr_size - non-public function that returns the size
- * of the struct sockaddr the BIO_ADDR is using. If the protocol family
- * isn't set or is something other than AF_INET, AF_INET6 or AF_UNIX,
- * the size of the BIO_ADDR type is returned.
- */
-socklen_t BIO_ADDR_sockaddr_size(const BIO_ADDR *ap)
-{
- if (ap->sa.sa_family == AF_INET)
- return sizeof(ap->s_in);
-#ifdef AF_INET6
- if (ap->sa.sa_family == AF_INET6)
- return sizeof(ap->s_in6);
-#endif
-#ifdef AF_UNIX
- if (ap->sa.sa_family == AF_UNIX)
- return sizeof(ap->s_un);
-#endif
- return sizeof(*ap);
-}
-
-/**********************************************************************
- *
- * Address info database
- *
- */
-
-const BIO_ADDRINFO *BIO_ADDRINFO_next(const BIO_ADDRINFO *bai)
-{
- if (bai != NULL)
- return bai->bai_next;
- return NULL;
-}
-
-int BIO_ADDRINFO_family(const BIO_ADDRINFO *bai)
-{
- if (bai != NULL)
- return bai->bai_family;
- return 0;
-}
-
-int BIO_ADDRINFO_socktype(const BIO_ADDRINFO *bai)
-{
- if (bai != NULL)
- return bai->bai_socktype;
- return 0;
-}
-
-int BIO_ADDRINFO_protocol(const BIO_ADDRINFO *bai)
-{
- if (bai != NULL) {
- if (bai->bai_protocol != 0)
- return bai->bai_protocol;
-
-#ifdef AF_UNIX
- if (bai->bai_family == AF_UNIX)
- return 0;
-#endif
-
- switch (bai->bai_socktype) {
- case SOCK_STREAM:
- return IPPROTO_TCP;
- case SOCK_DGRAM:
- return IPPROTO_UDP;
- default:
- break;
- }
- }
- return 0;
-}
-
-/*
- * BIO_ADDRINFO_sockaddr_size - non-public function that returns the size
- * of the struct sockaddr inside the BIO_ADDRINFO.
- */
-socklen_t BIO_ADDRINFO_sockaddr_size(const BIO_ADDRINFO *bai)
-{
- if (bai != NULL)
- return bai->bai_addrlen;
- return 0;
-}
-
-/*
- * BIO_ADDRINFO_sockaddr - non-public function that returns bai_addr
- * as the struct sockaddr it is.
- */
-const struct sockaddr *BIO_ADDRINFO_sockaddr(const BIO_ADDRINFO *bai)
-{
- if (bai != NULL)
- return bai->bai_addr;
- return NULL;
-}
-
-const BIO_ADDR *BIO_ADDRINFO_address(const BIO_ADDRINFO *bai)
-{
- if (bai != NULL)
- return (BIO_ADDR *)bai->bai_addr;
- return NULL;
-}
-
-void BIO_ADDRINFO_free(BIO_ADDRINFO *bai)
-{
- if (bai == NULL)
- return;
-
-#ifdef AI_PASSIVE
-# ifdef AF_UNIX
-# define _cond bai->bai_family != AF_UNIX
-# else
-# define _cond 1
-# endif
- if (_cond) {
- freeaddrinfo(bai);
- return;
- }
-#endif
-
- /* Free manually when we know that addrinfo_wrap() was used.
- * See further comment above addrinfo_wrap()
- */
- while (bai != NULL) {
- BIO_ADDRINFO *next = bai->bai_next;
- OPENSSL_free(bai->bai_addr);
- OPENSSL_free(bai);
- bai = next;
- }
-}
-
-/**********************************************************************
- *
- * Service functions
- *
- */
-
-/*-
- * The specs in hostserv can take these forms:
- *
- * host:service => *host = "host", *service = "service"
- * host:* => *host = "host", *service = NULL
- * host: => *host = "host", *service = NULL
- * :service => *host = NULL, *service = "service"
- * *:service => *host = NULL, *service = "service"
- *
- * in case no : is present in the string, the result depends on
- * hostserv_prio, as follows:
- *
- * when hostserv_prio == BIO_PARSE_PRIO_HOST
- * host => *host = "host", *service untouched
- *
- * when hostserv_prio == BIO_PARSE_PRIO_SERV
- * service => *host untouched, *service = "service"
- *
- */
-int BIO_parse_hostserv(const char *hostserv, char **host, char **service,
- enum BIO_hostserv_priorities hostserv_prio)
-{
- const char *h = NULL; size_t hl = 0;
- const char *p = NULL; size_t pl = 0;
-
- if (*hostserv == '[') {
- if ((p = strchr(hostserv, ']')) == NULL)
- goto spec_err;
- h = hostserv + 1;
- hl = p - h;
- p++;
- if (*p == '\0')
- p = NULL;
- else if (*p != ':')
- goto spec_err;
- else {
- p++;
- pl = strlen(p);
- }
- } else {
- const char *p2 = strrchr(hostserv, ':');
- p = strchr(hostserv, ':');
-
- /*-
- * Check for more than one colon. There are three possible
- * interpretations:
- * 1. IPv6 address with port number, last colon being separator.
- * 2. IPv6 address only.
- * 3. IPv6 address only if hostserv_prio == BIO_PARSE_PRIO_HOST,
- * IPv6 address and port number if hostserv_prio == BIO_PARSE_PRIO_SERV
- * Because of this ambiguity, we currently choose to make it an
- * error.
- */
- if (p != p2)
- goto amb_err;
-
- if (p != NULL) {
- h = hostserv;
- hl = p - h;
- p++;
- pl = strlen(p);
- } else if (hostserv_prio == BIO_PARSE_PRIO_HOST) {
- h = hostserv;
- hl = strlen(h);
- } else {
- p = hostserv;
- pl = strlen(p);
- }
- }
-
- if (p != NULL && strchr(p, ':'))
- goto spec_err;
-
- if (h != NULL && host != NULL) {
- if (hl == 0
- || (hl == 1 && h[0] == '*')) {
- *host = NULL;
- } else {
- *host = OPENSSL_strndup(h, hl);
- if (*host == NULL)
- goto memerr;
- }
- }
- if (p != NULL && service != NULL) {
- if (pl == 0
- || (pl == 1 && p[0] == '*')) {
- *service = NULL;
- } else {
- *service = OPENSSL_strndup(p, pl);
- if (*service == NULL)
- goto memerr;
- }
- }
-
- return 1;
- amb_err:
- BIOerr(BIO_F_BIO_PARSE_HOSTSERV, BIO_R_AMBIGUOUS_HOST_OR_SERVICE);
- return 0;
- spec_err:
- BIOerr(BIO_F_BIO_PARSE_HOSTSERV, BIO_R_MALFORMED_HOST_OR_SERVICE);
- return 0;
- memerr:
- BIOerr(BIO_F_BIO_PARSE_HOSTSERV, ERR_R_MALLOC_FAILURE);
- return 0;
-}
-
-/* addrinfo_wrap is used to build our own addrinfo "chain".
- * (it has only one entry, so calling it a chain may be a stretch)
- * It should ONLY be called when getaddrinfo() and friends
- * aren't available, OR when dealing with a non IP protocol
- * family, such as AF_UNIX
- *
- * the return value is 1 on success, or 0 on failure, which
- * only happens if a memory allocation error occurred.
- */
-static int addrinfo_wrap(int family, int socktype,
- const void *where, size_t wherelen,
- unsigned short port,
- BIO_ADDRINFO **bai)
-{
- if ((*bai = OPENSSL_zalloc(sizeof(**bai))) == NULL) {
- BIOerr(BIO_F_ADDRINFO_WRAP, ERR_R_MALLOC_FAILURE);
- return 0;
- }
-
- (*bai)->bai_family = family;
- (*bai)->bai_socktype = socktype;
- if (socktype == SOCK_STREAM)
- (*bai)->bai_protocol = IPPROTO_TCP;
- if (socktype == SOCK_DGRAM)
- (*bai)->bai_protocol = IPPROTO_UDP;
-#ifdef AF_UNIX
- if (family == AF_UNIX)
- (*bai)->bai_protocol = 0;
-#endif
- {
- /* Magic: We know that BIO_ADDR_sockaddr_noconst is really
- just an advanced cast of BIO_ADDR* to struct sockaddr *
- by the power of union, so while it may seem that we're
- creating a memory leak here, we are not. It will be
- all right. */
- BIO_ADDR *addr = BIO_ADDR_new();
- if (addr != NULL) {
- BIO_ADDR_rawmake(addr, family, where, wherelen, port);
- (*bai)->bai_addr = BIO_ADDR_sockaddr_noconst(addr);
- }
- }
- (*bai)->bai_next = NULL;
- if ((*bai)->bai_addr == NULL) {
- BIO_ADDRINFO_free(*bai);
- *bai = NULL;
- return 0;
- }
- return 1;
-}
-
-DEFINE_RUN_ONCE_STATIC(do_bio_lookup_init)
-{
- if (!OPENSSL_init_crypto(0, NULL))
- return 0;
- bio_lookup_lock = CRYPTO_THREAD_lock_new();
- return bio_lookup_lock != NULL;
-}
-
-int BIO_lookup(const char *host, const char *service,
- enum BIO_lookup_type lookup_type,
- int family, int socktype, BIO_ADDRINFO **res)
-{
- return BIO_lookup_ex(host, service, lookup_type, family, socktype, 0, res);
-}
-
-/*-
- * BIO_lookup_ex - look up the node and service you want to connect to.
- * @node: the node you want to connect to.
- * @service: the service you want to connect to.
- * @lookup_type: declare intent with the result, client or server.
- * @family: the address family you want to use. Use AF_UNSPEC for any, or
- * AF_INET, AF_INET6 or AF_UNIX.
- * @socktype: The socket type you want to use. Can be SOCK_STREAM, SOCK_DGRAM
- * or 0 for all.
- * @protocol: The protocol to use, e.g. IPPROTO_TCP or IPPROTO_UDP or 0 for all.
- * Note that some platforms may not return IPPROTO_SCTP without
- * explicitly requesting it (i.e. IPPROTO_SCTP may not be returned
- * with 0 for the protocol)
- * @res: Storage place for the resulting list of returned addresses
- *
- * This will do a lookup of the node and service that you want to connect to.
- * It returns a linked list of different addresses you can try to connect to.
- *
- * When no longer needed you should call BIO_ADDRINFO_free() to free the result.
- *
- * The return value is 1 on success or 0 in case of error.
- */
-int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
- int family, int socktype, int protocol, BIO_ADDRINFO **res)
-{
- int ret = 0; /* Assume failure */
-
- switch(family) {
- case AF_INET:
-#ifdef AF_INET6
- case AF_INET6:
-#endif
-#ifdef AF_UNIX
- case AF_UNIX:
-#endif
-#ifdef AF_UNSPEC
- case AF_UNSPEC:
-#endif
- break;
- default:
- BIOerr(BIO_F_BIO_LOOKUP_EX, BIO_R_UNSUPPORTED_PROTOCOL_FAMILY);
- return 0;
- }
-
-#ifdef AF_UNIX
- if (family == AF_UNIX) {
- if (addrinfo_wrap(family, socktype, host, strlen(host), 0, res))
- return 1;
- else
- BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_MALLOC_FAILURE);
- return 0;
- }
-#endif
-
- if (BIO_sock_init() != 1)
- return 0;
-
- if (1) {
-#ifdef AI_PASSIVE
+ * AI_PASSIVE is used to detect the availability of struct addrinfo,
+ * getnameinfo() and getaddrinfo(). If that macro doesn't exist,
+ * we use our own implementation instead, using gethostbyname,
+ * getservbyname and a few other.
+ */
+
+/**********************************************************************
+ *
+ * Address structure
+ *
+ */
+
+BIO_ADDR *BIO_ADDR_new(void)
+{
+ BIO_ADDR *ret = OPENSSL_zalloc(sizeof(*ret));
+
+ if (ret == NULL) {
+ BIOerr(BIO_F_BIO_ADDR_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ ret->sa.sa_family = AF_UNSPEC;
+ return ret;
+}
+
+void BIO_ADDR_free(BIO_ADDR *ap)
+{
+ OPENSSL_free(ap);
+}
+
+void BIO_ADDR_clear(BIO_ADDR *ap)
+{
+ memset(ap, 0, sizeof(*ap));
+ ap->sa.sa_family = AF_UNSPEC;
+}
+
+/*
+ * BIO_ADDR_make - non-public routine to fill a BIO_ADDR with the contents
+ * of a struct sockaddr.
+ */
+int BIO_ADDR_make(BIO_ADDR *ap, const struct sockaddr *sa)
+{
+ if (sa->sa_family == AF_INET) {
+ memcpy(&(ap->s_in), sa, sizeof(struct sockaddr_in));
+ return 1;
+ }
+#ifdef AF_INET6
+ if (sa->sa_family == AF_INET6) {
+ memcpy(&(ap->s_in6), sa, sizeof(struct sockaddr_in6));
+ return 1;
+ }
+#endif
+#ifdef AF_UNIX
+ if (sa->sa_family == AF_UNIX) {
+ memcpy(&(ap->s_un), sa, sizeof(struct sockaddr_un));
+ return 1;
+ }
+#endif
+
+ return 0;
+}
+
+int BIO_ADDR_rawmake(BIO_ADDR *ap, int family,
+ const void *where, size_t wherelen,
+ unsigned short port)
+{
+#ifdef AF_UNIX
+ if (family == AF_UNIX) {
+ if (wherelen + 1 > sizeof(ap->s_un.sun_path))
+ return 0;
+ memset(&ap->s_un, 0, sizeof(ap->s_un));
+ ap->s_un.sun_family = family;
+ strncpy(ap->s_un.sun_path, where, sizeof(ap->s_un.sun_path) - 1);
+ return 1;
+ }
+#endif
+ if (family == AF_INET) {
+ if (wherelen != sizeof(struct in_addr))
+ return 0;
+ memset(&ap->s_in, 0, sizeof(ap->s_in));
+ ap->s_in.sin_family = family;
+ ap->s_in.sin_port = port;
+ ap->s_in.sin_addr = *(struct in_addr *)where;
+ return 1;
+ }
+#ifdef AF_INET6
+ if (family == AF_INET6) {
+ if (wherelen != sizeof(struct in6_addr))
+ return 0;
+ memset(&ap->s_in6, 0, sizeof(ap->s_in6));
+ ap->s_in6.sin6_family = family;
+ ap->s_in6.sin6_port = port;
+ ap->s_in6.sin6_addr = *(struct in6_addr *)where;
+ return 1;
+ }
+#endif
+
+ return 0;
+}
+
+int BIO_ADDR_family(const BIO_ADDR *ap)
+{
+ return ap->sa.sa_family;
+}
+
+int BIO_ADDR_rawaddress(const BIO_ADDR *ap, void *p, size_t *l)
+{
+ size_t len = 0;
+ const void *addrptr = NULL;
+
+ if (ap->sa.sa_family == AF_INET) {
+ len = sizeof(ap->s_in.sin_addr);
+ addrptr = &ap->s_in.sin_addr;
+ }
+#ifdef AF_INET6
+ else if (ap->sa.sa_family == AF_INET6) {
+ len = sizeof(ap->s_in6.sin6_addr);
+ addrptr = &ap->s_in6.sin6_addr;
+ }
+#endif
+#ifdef AF_UNIX
+ else if (ap->sa.sa_family == AF_UNIX) {
+ len = strlen(ap->s_un.sun_path);
+ addrptr = &ap->s_un.sun_path;
+ }
+#endif
+
+ if (addrptr == NULL)
+ return 0;
+
+ if (p != NULL) {
+ memcpy(p, addrptr, len);
+ }
+ if (l != NULL)
+ *l = len;
+
+ return 1;
+}
+
+unsigned short BIO_ADDR_rawport(const BIO_ADDR *ap)
+{
+ if (ap->sa.sa_family == AF_INET)
+ return ap->s_in.sin_port;
+#ifdef AF_INET6
+ if (ap->sa.sa_family == AF_INET6)
+ return ap->s_in6.sin6_port;
+#endif
+ return 0;
+}
+
+/*-
+ * addr_strings - helper function to get host and service names
+ * @ap: the BIO_ADDR that has the input info
+ * @numeric: 0 if actual names should be returned, 1 if the numeric
+ * representation should be returned.
+ * @hostname: a pointer to a pointer to a memory area to store the
+ * host name or numeric representation. Unused if NULL.
+ * @service: a pointer to a pointer to a memory area to store the
+ * service name or numeric representation. Unused if NULL.
+ *
+ * The return value is 0 on failure, with the error code in the error
+ * stack, and 1 on success.
+ */
+static int addr_strings(const BIO_ADDR *ap, int numeric,
+ char **hostname, char **service)
+{
+ if (BIO_sock_init() != 1)
+ return 0;
+
+ if (1) {
+#ifdef AI_PASSIVE
+ int ret = 0;
+ char host[NI_MAXHOST] = "", serv[NI_MAXSERV] = "";
+ int flags = 0;
+
+ if (numeric)
+ flags |= NI_NUMERICHOST | NI_NUMERICSERV;
+
+ if ((ret = getnameinfo(BIO_ADDR_sockaddr(ap),
+ BIO_ADDR_sockaddr_size(ap),
+ host, sizeof(host), serv, sizeof(serv),
+ flags)) != 0) {
+# ifdef EAI_SYSTEM
+ if (ret == EAI_SYSTEM) {
+ SYSerr(SYS_F_GETNAMEINFO, get_last_socket_error());
+ BIOerr(BIO_F_ADDR_STRINGS, ERR_R_SYS_LIB);
+ } else
+# endif
+ {
+ BIOerr(BIO_F_ADDR_STRINGS, ERR_R_SYS_LIB);
+ ERR_add_error_data(1, gai_strerror(ret));
+ }
+ return 0;
+ }
+
+ /* VMS getnameinfo() has a bug, it doesn't fill in serv, which
+ * leaves it with whatever garbage that happens to be there.
+ * However, we initialise serv with the empty string (serv[0]
+ * is therefore NUL), so it gets real easy to detect when things
+ * didn't go the way one might expect.
+ */
+ if (serv[0] == '\0') {
+ BIO_snprintf(serv, sizeof(serv), "%d",
+ ntohs(BIO_ADDR_rawport(ap)));
+ }
+
+ if (hostname != NULL)
+ *hostname = OPENSSL_strdup(host);
+ if (service != NULL)
+ *service = OPENSSL_strdup(serv);
+ } else {
+#endif
+ if (hostname != NULL)
+ *hostname = OPENSSL_strdup(inet_ntoa(ap->s_in.sin_addr));
+ if (service != NULL) {
+ char serv[6]; /* port is 16 bits => max 5 decimal digits */
+ BIO_snprintf(serv, sizeof(serv), "%d", ntohs(ap->s_in.sin_port));
+ *service = OPENSSL_strdup(serv);
+ }
+ }
+
+ if ((hostname != NULL && *hostname == NULL)
+ || (service != NULL && *service == NULL)) {
+ if (hostname != NULL) {
+ OPENSSL_free(*hostname);
+ *hostname = NULL;
+ }
+ if (service != NULL) {
+ OPENSSL_free(*service);
+ *service = NULL;
+ }
+ BIOerr(BIO_F_ADDR_STRINGS, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ return 1;
+}
+
+char *BIO_ADDR_hostname_string(const BIO_ADDR *ap, int numeric)
+{
+ char *hostname = NULL;
+
+ if (addr_strings(ap, numeric, &hostname, NULL))
+ return hostname;
+
+ return NULL;
+}
+
+char *BIO_ADDR_service_string(const BIO_ADDR *ap, int numeric)
+{
+ char *service = NULL;
+
+ if (addr_strings(ap, numeric, NULL, &service))
+ return service;
+
+ return NULL;
+}
+
+char *BIO_ADDR_path_string(const BIO_ADDR *ap)
+{
+#ifdef AF_UNIX
+ if (ap->sa.sa_family == AF_UNIX)
+ return OPENSSL_strdup(ap->s_un.sun_path);
+#endif
+ return NULL;
+}
+
+/*
+ * BIO_ADDR_sockaddr - non-public routine to return the struct sockaddr
+ * for a given BIO_ADDR. In reality, this is simply a type safe cast.
+ * The returned struct sockaddr is const, so it can't be tampered with.
+ */
+const struct sockaddr *BIO_ADDR_sockaddr(const BIO_ADDR *ap)
+{
+ return &(ap->sa);
+}
+
+/*
+ * BIO_ADDR_sockaddr_noconst - non-public function that does the same
+ * as BIO_ADDR_sockaddr, but returns a non-const. USE WITH CARE, as
+ * it allows you to tamper with the data (and thereby the contents
+ * of the input BIO_ADDR).
+ */
+struct sockaddr *BIO_ADDR_sockaddr_noconst(BIO_ADDR *ap)
+{
+ return &(ap->sa);
+}
+
+/*
+ * BIO_ADDR_sockaddr_size - non-public function that returns the size
+ * of the struct sockaddr the BIO_ADDR is using. If the protocol family
+ * isn't set or is something other than AF_INET, AF_INET6 or AF_UNIX,
+ * the size of the BIO_ADDR type is returned.
+ */
+socklen_t BIO_ADDR_sockaddr_size(const BIO_ADDR *ap)
+{
+ if (ap->sa.sa_family == AF_INET)
+ return sizeof(ap->s_in);
+#ifdef AF_INET6
+ if (ap->sa.sa_family == AF_INET6)
+ return sizeof(ap->s_in6);
+#endif
+#ifdef AF_UNIX
+ if (ap->sa.sa_family == AF_UNIX)
+ return sizeof(ap->s_un);
+#endif
+ return sizeof(*ap);
+}
+
+/**********************************************************************
+ *
+ * Address info database
+ *
+ */
+
+const BIO_ADDRINFO *BIO_ADDRINFO_next(const BIO_ADDRINFO *bai)
+{
+ if (bai != NULL)
+ return bai->bai_next;
+ return NULL;
+}
+
+int BIO_ADDRINFO_family(const BIO_ADDRINFO *bai)
+{
+ if (bai != NULL)
+ return bai->bai_family;
+ return 0;
+}
+
+int BIO_ADDRINFO_socktype(const BIO_ADDRINFO *bai)
+{
+ if (bai != NULL)
+ return bai->bai_socktype;
+ return 0;
+}
+
+int BIO_ADDRINFO_protocol(const BIO_ADDRINFO *bai)
+{
+ if (bai != NULL) {
+ if (bai->bai_protocol != 0)
+ return bai->bai_protocol;
+
+#ifdef AF_UNIX
+ if (bai->bai_family == AF_UNIX)
+ return 0;
+#endif
+
+ switch (bai->bai_socktype) {
+ case SOCK_STREAM:
+ return IPPROTO_TCP;
+ case SOCK_DGRAM:
+ return IPPROTO_UDP;
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+/*
+ * BIO_ADDRINFO_sockaddr_size - non-public function that returns the size
+ * of the struct sockaddr inside the BIO_ADDRINFO.
+ */
+socklen_t BIO_ADDRINFO_sockaddr_size(const BIO_ADDRINFO *bai)
+{
+ if (bai != NULL)
+ return bai->bai_addrlen;
+ return 0;
+}
+
+/*
+ * BIO_ADDRINFO_sockaddr - non-public function that returns bai_addr
+ * as the struct sockaddr it is.
+ */
+const struct sockaddr *BIO_ADDRINFO_sockaddr(const BIO_ADDRINFO *bai)
+{
+ if (bai != NULL)
+ return bai->bai_addr;
+ return NULL;
+}
+
+const BIO_ADDR *BIO_ADDRINFO_address(const BIO_ADDRINFO *bai)
+{
+ if (bai != NULL)
+ return (BIO_ADDR *)bai->bai_addr;
+ return NULL;
+}
+
+void BIO_ADDRINFO_free(BIO_ADDRINFO *bai)
+{
+ if (bai == NULL)
+ return;
+
+#ifdef AI_PASSIVE
+# ifdef AF_UNIX
+# define _cond bai->bai_family != AF_UNIX
+# else
+# define _cond 1
+# endif
+ if (_cond) {
+ freeaddrinfo(bai);
+ return;
+ }
+#endif
+
+ /* Free manually when we know that addrinfo_wrap() was used.
+ * See further comment above addrinfo_wrap()
+ */
+ while (bai != NULL) {
+ BIO_ADDRINFO *next = bai->bai_next;
+ OPENSSL_free(bai->bai_addr);
+ OPENSSL_free(bai);
+ bai = next;
+ }
+}
+
+/**********************************************************************
+ *
+ * Service functions
+ *
+ */
+
+/*-
+ * The specs in hostserv can take these forms:
+ *
+ * host:service => *host = "host", *service = "service"
+ * host:* => *host = "host", *service = NULL
+ * host: => *host = "host", *service = NULL
+ * :service => *host = NULL, *service = "service"
+ * *:service => *host = NULL, *service = "service"
+ *
+ * in case no : is present in the string, the result depends on
+ * hostserv_prio, as follows:
+ *
+ * when hostserv_prio == BIO_PARSE_PRIO_HOST
+ * host => *host = "host", *service untouched
+ *
+ * when hostserv_prio == BIO_PARSE_PRIO_SERV
+ * service => *host untouched, *service = "service"
+ *
+ */
+int BIO_parse_hostserv(const char *hostserv, char **host, char **service,
+ enum BIO_hostserv_priorities hostserv_prio)
+{
+ const char *h = NULL; size_t hl = 0;
+ const char *p = NULL; size_t pl = 0;
+
+ if (*hostserv == '[') {
+ if ((p = strchr(hostserv, ']')) == NULL)
+ goto spec_err;
+ h = hostserv + 1;
+ hl = p - h;
+ p++;
+ if (*p == '\0')
+ p = NULL;
+ else if (*p != ':')
+ goto spec_err;
+ else {
+ p++;
+ pl = strlen(p);
+ }
+ } else {
+ const char *p2 = strrchr(hostserv, ':');
+ p = strchr(hostserv, ':');
+
+ /*-
+ * Check for more than one colon. There are three possible
+ * interpretations:
+ * 1. IPv6 address with port number, last colon being separator.
+ * 2. IPv6 address only.
+ * 3. IPv6 address only if hostserv_prio == BIO_PARSE_PRIO_HOST,
+ * IPv6 address and port number if hostserv_prio == BIO_PARSE_PRIO_SERV
+ * Because of this ambiguity, we currently choose to make it an
+ * error.
+ */
+ if (p != p2)
+ goto amb_err;
+
+ if (p != NULL) {
+ h = hostserv;
+ hl = p - h;
+ p++;
+ pl = strlen(p);
+ } else if (hostserv_prio == BIO_PARSE_PRIO_HOST) {
+ h = hostserv;
+ hl = strlen(h);
+ } else {
+ p = hostserv;
+ pl = strlen(p);
+ }
+ }
+
+ if (p != NULL && strchr(p, ':'))
+ goto spec_err;
+
+ if (h != NULL && host != NULL) {
+ if (hl == 0
+ || (hl == 1 && h[0] == '*')) {
+ *host = NULL;
+ } else {
+ *host = OPENSSL_strndup(h, hl);
+ if (*host == NULL)
+ goto memerr;
+ }
+ }
+ if (p != NULL && service != NULL) {
+ if (pl == 0
+ || (pl == 1 && p[0] == '*')) {
+ *service = NULL;
+ } else {
+ *service = OPENSSL_strndup(p, pl);
+ if (*service == NULL)
+ goto memerr;
+ }
+ }
+
+ return 1;
+ amb_err:
+ BIOerr(BIO_F_BIO_PARSE_HOSTSERV, BIO_R_AMBIGUOUS_HOST_OR_SERVICE);
+ return 0;
+ spec_err:
+ BIOerr(BIO_F_BIO_PARSE_HOSTSERV, BIO_R_MALFORMED_HOST_OR_SERVICE);
+ return 0;
+ memerr:
+ BIOerr(BIO_F_BIO_PARSE_HOSTSERV, ERR_R_MALLOC_FAILURE);
+ return 0;
+}
+
+/* addrinfo_wrap is used to build our own addrinfo "chain".
+ * (it has only one entry, so calling it a chain may be a stretch)
+ * It should ONLY be called when getaddrinfo() and friends
+ * aren't available, OR when dealing with a non IP protocol
+ * family, such as AF_UNIX
+ *
+ * the return value is 1 on success, or 0 on failure, which
+ * only happens if a memory allocation error occurred.
+ */
+static int addrinfo_wrap(int family, int socktype,
+ const void *where, size_t wherelen,
+ unsigned short port,
+ BIO_ADDRINFO **bai)
+{
+ if ((*bai = OPENSSL_zalloc(sizeof(**bai))) == NULL) {
+ BIOerr(BIO_F_ADDRINFO_WRAP, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ (*bai)->bai_family = family;
+ (*bai)->bai_socktype = socktype;
+ if (socktype == SOCK_STREAM)
+ (*bai)->bai_protocol = IPPROTO_TCP;
+ if (socktype == SOCK_DGRAM)
+ (*bai)->bai_protocol = IPPROTO_UDP;
+#ifdef AF_UNIX
+ if (family == AF_UNIX)
+ (*bai)->bai_protocol = 0;
+#endif
+ {
+ /* Magic: We know that BIO_ADDR_sockaddr_noconst is really
+ just an advanced cast of BIO_ADDR* to struct sockaddr *
+ by the power of union, so while it may seem that we're
+ creating a memory leak here, we are not. It will be
+ all right. */
+ BIO_ADDR *addr = BIO_ADDR_new();
+ if (addr != NULL) {
+ BIO_ADDR_rawmake(addr, family, where, wherelen, port);
+ (*bai)->bai_addr = BIO_ADDR_sockaddr_noconst(addr);
+ }
+ }
+ (*bai)->bai_next = NULL;
+ if ((*bai)->bai_addr == NULL) {
+ BIO_ADDRINFO_free(*bai);
+ *bai = NULL;
+ return 0;
+ }
+ return 1;
+}
+
+DEFINE_RUN_ONCE_STATIC(do_bio_lookup_init)
+{
+ if (!OPENSSL_init_crypto(0, NULL))
+ return 0;
+ bio_lookup_lock = CRYPTO_THREAD_lock_new();
+ return bio_lookup_lock != NULL;
+}
+
+int BIO_lookup(const char *host, const char *service,
+ enum BIO_lookup_type lookup_type,
+ int family, int socktype, BIO_ADDRINFO **res)
+{
+ return BIO_lookup_ex(host, service, lookup_type, family, socktype, 0, res);
+}
+
+/*-
+ * BIO_lookup_ex - look up the node and service you want to connect to.
+ * @node: the node you want to connect to.
+ * @service: the service you want to connect to.
+ * @lookup_type: declare intent with the result, client or server.
+ * @family: the address family you want to use. Use AF_UNSPEC for any, or
+ * AF_INET, AF_INET6 or AF_UNIX.
+ * @socktype: The socket type you want to use. Can be SOCK_STREAM, SOCK_DGRAM
+ * or 0 for all.
+ * @protocol: The protocol to use, e.g. IPPROTO_TCP or IPPROTO_UDP or 0 for all.
+ * Note that some platforms may not return IPPROTO_SCTP without
+ * explicitly requesting it (i.e. IPPROTO_SCTP may not be returned
+ * with 0 for the protocol)
+ * @res: Storage place for the resulting list of returned addresses
+ *
+ * This will do a lookup of the node and service that you want to connect to.
+ * It returns a linked list of different addresses you can try to connect to.
+ *
+ * When no longer needed you should call BIO_ADDRINFO_free() to free the result.
+ *
+ * The return value is 1 on success or 0 in case of error.
+ */
+int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
+ int family, int socktype, int protocol, BIO_ADDRINFO **res)
+{
+ int ret = 0; /* Assume failure */
+
+ switch(family) {
+ case AF_INET:
+#ifdef AF_INET6
+ case AF_INET6:
+#endif
+#ifdef AF_UNIX
+ case AF_UNIX:
+#endif
+#ifdef AF_UNSPEC
+ case AF_UNSPEC:
+#endif
+ break;
+ default:
+ BIOerr(BIO_F_BIO_LOOKUP_EX, BIO_R_UNSUPPORTED_PROTOCOL_FAMILY);
+ return 0;
+ }
+
+#ifdef AF_UNIX
+ if (family == AF_UNIX) {
+ if (addrinfo_wrap(family, socktype, host, strlen(host), 0, res))
+ return 1;
+ else
+ BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+#endif
+
+ if (BIO_sock_init() != 1)
+ return 0;
+
+ if (1) {
+#ifdef AI_PASSIVE
int gai_ret = 0, old_ret = 0;
- struct addrinfo hints;
-
- memset(&hints, 0, sizeof(hints));
-
- hints.ai_family = family;
- hints.ai_socktype = socktype;
- hints.ai_protocol = protocol;
+ struct addrinfo hints;
+
+ memset(&hints, 0, sizeof(hints));
+
+ hints.ai_family = family;
+ hints.ai_socktype = socktype;
+ hints.ai_protocol = protocol;
# ifdef AI_ADDRCONFIG
# ifdef AF_UNSPEC
if (host != NULL && family == AF_UNSPEC)
# endif
hints.ai_flags |= AI_ADDRCONFIG;
# endif
-
- if (lookup_type == BIO_LOOKUP_SERVER)
- hints.ai_flags |= AI_PASSIVE;
-
- /* Note that |res| SHOULD be a 'struct addrinfo **' thanks to
+
+ if (lookup_type == BIO_LOOKUP_SERVER)
+ hints.ai_flags |= AI_PASSIVE;
+
+ /* Note that |res| SHOULD be a 'struct addrinfo **' thanks to
* macro magic in bio_local.h
- */
+ */
# if defined(AI_ADDRCONFIG) && defined(AI_NUMERICHOST)
retry:
# endif
- switch ((gai_ret = getaddrinfo(host, service, &hints, res))) {
-# ifdef EAI_SYSTEM
- case EAI_SYSTEM:
- SYSerr(SYS_F_GETADDRINFO, get_last_socket_error());
- BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_SYS_LIB);
- break;
-# endif
+ switch ((gai_ret = getaddrinfo(host, service, &hints, res))) {
+# ifdef EAI_SYSTEM
+ case EAI_SYSTEM:
+ SYSerr(SYS_F_GETADDRINFO, get_last_socket_error());
+ BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_SYS_LIB);
+ break;
+# endif
# ifdef EAI_MEMORY
case EAI_MEMORY:
BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_MALLOC_FAILURE);
break;
# endif
- case 0:
- ret = 1; /* Success */
- break;
- default:
+ case 0:
+ ret = 1; /* Success */
+ break;
+ default:
# if defined(AI_ADDRCONFIG) && defined(AI_NUMERICHOST)
if (hints.ai_flags & AI_ADDRCONFIG) {
hints.ai_flags &= ~AI_ADDRCONFIG;
@@ -727,202 +727,202 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type,
goto retry;
}
# endif
- BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_SYS_LIB);
+ BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_SYS_LIB);
ERR_add_error_data(1, gai_strerror(old_ret ? old_ret : gai_ret));
- break;
- }
- } else {
-#endif
- const struct hostent *he;
-/*
- * Because struct hostent is defined for 32-bit pointers only with
- * VMS C, we need to make sure that '&he_fallback_address' and
- * '&he_fallback_addresses' are 32-bit pointers
- */
-#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
-# pragma pointer_size save
-# pragma pointer_size 32
-#endif
- /* Windows doesn't seem to have in_addr_t */
-#ifdef OPENSSL_SYS_WINDOWS
- static uint32_t he_fallback_address;
- static const char *he_fallback_addresses[] =
- { (char *)&he_fallback_address, NULL };
-#else
- static in_addr_t he_fallback_address;
- static const char *he_fallback_addresses[] =
- { (char *)&he_fallback_address, NULL };
-#endif
- static const struct hostent he_fallback =
- { NULL, NULL, AF_INET, sizeof(he_fallback_address),
- (char **)&he_fallback_addresses };
-#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
-# pragma pointer_size restore
-#endif
-
- struct servent *se;
- /* Apparently, on WIN64, s_proto and s_port have traded places... */
-#ifdef _WIN64
- struct servent se_fallback = { NULL, NULL, NULL, 0 };
-#else
- struct servent se_fallback = { NULL, NULL, 0, NULL };
-#endif
-
- if (!RUN_ONCE(&bio_lookup_init, do_bio_lookup_init)) {
- BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_MALLOC_FAILURE);
- ret = 0;
- goto err;
- }
-
- CRYPTO_THREAD_write_lock(bio_lookup_lock);
- he_fallback_address = INADDR_ANY;
- if (host == NULL) {
- he = &he_fallback;
- switch(lookup_type) {
- case BIO_LOOKUP_CLIENT:
- he_fallback_address = INADDR_LOOPBACK;
- break;
- case BIO_LOOKUP_SERVER:
- he_fallback_address = INADDR_ANY;
- break;
- default:
- /* We forgot to handle a lookup type! */
- assert("We forgot to handle a lookup type!" == NULL);
- BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_INTERNAL_ERROR);
- ret = 0;
- goto err;
- }
- } else {
- he = gethostbyname(host);
-
- if (he == NULL) {
-#ifndef OPENSSL_SYS_WINDOWS
- /*
- * This might be misleading, because h_errno is used as if
- * it was errno. To minimize mixup add 1000. Underlying
- * reason for this is that hstrerror is declared obsolete,
- * not to mention that a) h_errno is not always guaranteed
- * to be meaningless; b) hstrerror can reside in yet another
- * library, linking for sake of hstrerror is an overkill;
- * c) this path is not executed on contemporary systems
- * anyway [above getaddrinfo/gai_strerror is]. We just let
- * system administrator figure this out...
- */
-# if defined(OPENSSL_SYS_VXWORKS)
- /* h_errno doesn't exist on VxWorks */
- SYSerr(SYS_F_GETHOSTBYNAME, 1000 );
-# else
- SYSerr(SYS_F_GETHOSTBYNAME, 1000 + h_errno);
-# endif
-#else
- SYSerr(SYS_F_GETHOSTBYNAME, WSAGetLastError());
-#endif
- ret = 0;
- goto err;
- }
- }
-
- if (service == NULL) {
- se_fallback.s_port = 0;
- se_fallback.s_proto = NULL;
- se = &se_fallback;
- } else {
- char *endp = NULL;
- long portnum = strtol(service, &endp, 10);
-
-/*
- * Because struct servent is defined for 32-bit pointers only with
- * VMS C, we need to make sure that 'proto' is a 32-bit pointer.
- */
-#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
-# pragma pointer_size save
-# pragma pointer_size 32
-#endif
- char *proto = NULL;
-#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
-# pragma pointer_size restore
-#endif
-
- switch (socktype) {
- case SOCK_STREAM:
- proto = "tcp";
- break;
- case SOCK_DGRAM:
- proto = "udp";
- break;
- }
-
- if (endp != service && *endp == '\0'
- && portnum > 0 && portnum < 65536) {
- se_fallback.s_port = htons((unsigned short)portnum);
- se_fallback.s_proto = proto;
- se = &se_fallback;
- } else if (endp == service) {
- se = getservbyname(service, proto);
-
- if (se == NULL) {
-#ifndef OPENSSL_SYS_WINDOWS
- SYSerr(SYS_F_GETSERVBYNAME, errno);
-#else
- SYSerr(SYS_F_GETSERVBYNAME, WSAGetLastError());
-#endif
- goto err;
- }
- } else {
- BIOerr(BIO_F_BIO_LOOKUP_EX, BIO_R_MALFORMED_HOST_OR_SERVICE);
- goto err;
- }
- }
-
- *res = NULL;
-
- {
-/*
- * Because hostent::h_addr_list is an array of 32-bit pointers with VMS C,
- * we must make sure our iterator designates the same element type, hence
- * the pointer size dance.
- */
-#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
-# pragma pointer_size save
-# pragma pointer_size 32
-#endif
- char **addrlistp;
-#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
-# pragma pointer_size restore
-#endif
- size_t addresses;
- BIO_ADDRINFO *tmp_bai = NULL;
-
- /* The easiest way to create a linked list from an
- array is to start from the back */
- for(addrlistp = he->h_addr_list; *addrlistp != NULL;
- addrlistp++)
- ;
-
- for(addresses = addrlistp - he->h_addr_list;
- addrlistp--, addresses-- > 0; ) {
- if (!addrinfo_wrap(he->h_addrtype, socktype,
- *addrlistp, he->h_length,
- se->s_port, &tmp_bai))
- goto addrinfo_malloc_err;
- tmp_bai->bai_next = *res;
- *res = tmp_bai;
- continue;
- addrinfo_malloc_err:
- BIO_ADDRINFO_free(*res);
- *res = NULL;
- BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_MALLOC_FAILURE);
- ret = 0;
- goto err;
- }
-
- ret = 1;
- }
- err:
- CRYPTO_THREAD_unlock(bio_lookup_lock);
- }
-
- return ret;
-}
-
-#endif /* OPENSSL_NO_SOCK */
+ break;
+ }
+ } else {
+#endif
+ const struct hostent *he;
+/*
+ * Because struct hostent is defined for 32-bit pointers only with
+ * VMS C, we need to make sure that '&he_fallback_address' and
+ * '&he_fallback_addresses' are 32-bit pointers
+ */
+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
+# pragma pointer_size save
+# pragma pointer_size 32
+#endif
+ /* Windows doesn't seem to have in_addr_t */
+#ifdef OPENSSL_SYS_WINDOWS
+ static uint32_t he_fallback_address;
+ static const char *he_fallback_addresses[] =
+ { (char *)&he_fallback_address, NULL };
+#else
+ static in_addr_t he_fallback_address;
+ static const char *he_fallback_addresses[] =
+ { (char *)&he_fallback_address, NULL };
+#endif
+ static const struct hostent he_fallback =
+ { NULL, NULL, AF_INET, sizeof(he_fallback_address),
+ (char **)&he_fallback_addresses };
+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
+# pragma pointer_size restore
+#endif
+
+ struct servent *se;
+ /* Apparently, on WIN64, s_proto and s_port have traded places... */
+#ifdef _WIN64
+ struct servent se_fallback = { NULL, NULL, NULL, 0 };
+#else
+ struct servent se_fallback = { NULL, NULL, 0, NULL };
+#endif
+
+ if (!RUN_ONCE(&bio_lookup_init, do_bio_lookup_init)) {
+ BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_MALLOC_FAILURE);
+ ret = 0;
+ goto err;
+ }
+
+ CRYPTO_THREAD_write_lock(bio_lookup_lock);
+ he_fallback_address = INADDR_ANY;
+ if (host == NULL) {
+ he = &he_fallback;
+ switch(lookup_type) {
+ case BIO_LOOKUP_CLIENT:
+ he_fallback_address = INADDR_LOOPBACK;
+ break;
+ case BIO_LOOKUP_SERVER:
+ he_fallback_address = INADDR_ANY;
+ break;
+ default:
+ /* We forgot to handle a lookup type! */
+ assert("We forgot to handle a lookup type!" == NULL);
+ BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_INTERNAL_ERROR);
+ ret = 0;
+ goto err;
+ }
+ } else {
+ he = gethostbyname(host);
+
+ if (he == NULL) {
+#ifndef OPENSSL_SYS_WINDOWS
+ /*
+ * This might be misleading, because h_errno is used as if
+ * it was errno. To minimize mixup add 1000. Underlying
+ * reason for this is that hstrerror is declared obsolete,
+ * not to mention that a) h_errno is not always guaranteed
+ * to be meaningless; b) hstrerror can reside in yet another
+ * library, linking for sake of hstrerror is an overkill;
+ * c) this path is not executed on contemporary systems
+ * anyway [above getaddrinfo/gai_strerror is]. We just let
+ * system administrator figure this out...
+ */
+# if defined(OPENSSL_SYS_VXWORKS)
+ /* h_errno doesn't exist on VxWorks */
+ SYSerr(SYS_F_GETHOSTBYNAME, 1000 );
+# else
+ SYSerr(SYS_F_GETHOSTBYNAME, 1000 + h_errno);
+# endif
+#else
+ SYSerr(SYS_F_GETHOSTBYNAME, WSAGetLastError());
+#endif
+ ret = 0;
+ goto err;
+ }
+ }
+
+ if (service == NULL) {
+ se_fallback.s_port = 0;
+ se_fallback.s_proto = NULL;
+ se = &se_fallback;
+ } else {
+ char *endp = NULL;
+ long portnum = strtol(service, &endp, 10);
+
+/*
+ * Because struct servent is defined for 32-bit pointers only with
+ * VMS C, we need to make sure that 'proto' is a 32-bit pointer.
+ */
+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
+# pragma pointer_size save
+# pragma pointer_size 32
+#endif
+ char *proto = NULL;
+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
+# pragma pointer_size restore
+#endif
+
+ switch (socktype) {
+ case SOCK_STREAM:
+ proto = "tcp";
+ break;
+ case SOCK_DGRAM:
+ proto = "udp";
+ break;
+ }
+
+ if (endp != service && *endp == '\0'
+ && portnum > 0 && portnum < 65536) {
+ se_fallback.s_port = htons((unsigned short)portnum);
+ se_fallback.s_proto = proto;
+ se = &se_fallback;
+ } else if (endp == service) {
+ se = getservbyname(service, proto);
+
+ if (se == NULL) {
+#ifndef OPENSSL_SYS_WINDOWS
+ SYSerr(SYS_F_GETSERVBYNAME, errno);
+#else
+ SYSerr(SYS_F_GETSERVBYNAME, WSAGetLastError());
+#endif
+ goto err;
+ }
+ } else {
+ BIOerr(BIO_F_BIO_LOOKUP_EX, BIO_R_MALFORMED_HOST_OR_SERVICE);
+ goto err;
+ }
+ }
+
+ *res = NULL;
+
+ {
+/*
+ * Because hostent::h_addr_list is an array of 32-bit pointers with VMS C,
+ * we must make sure our iterator designates the same element type, hence
+ * the pointer size dance.
+ */
+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
+# pragma pointer_size save
+# pragma pointer_size 32
+#endif
+ char **addrlistp;
+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
+# pragma pointer_size restore
+#endif
+ size_t addresses;
+ BIO_ADDRINFO *tmp_bai = NULL;
+
+ /* The easiest way to create a linked list from an
+ array is to start from the back */
+ for(addrlistp = he->h_addr_list; *addrlistp != NULL;
+ addrlistp++)
+ ;
+
+ for(addresses = addrlistp - he->h_addr_list;
+ addrlistp--, addresses-- > 0; ) {
+ if (!addrinfo_wrap(he->h_addrtype, socktype,
+ *addrlistp, he->h_length,
+ se->s_port, &tmp_bai))
+ goto addrinfo_malloc_err;
+ tmp_bai->bai_next = *res;
+ *res = tmp_bai;
+ continue;
+ addrinfo_malloc_err:
+ BIO_ADDRINFO_free(*res);
+ *res = NULL;
+ BIOerr(BIO_F_BIO_LOOKUP_EX, ERR_R_MALLOC_FAILURE);
+ ret = 0;
+ goto err;
+ }
+
+ ret = 1;
+ }
+ err:
+ CRYPTO_THREAD_unlock(bio_lookup_lock);
+ }
+
+ return ret;
+}
+
+#endif /* OPENSSL_NO_SOCK */
diff --git a/contrib/libs/openssl/crypto/bio/b_dump.c b/contrib/libs/openssl/crypto/bio/b_dump.c
index 9bd61eaeb1..f175e244b2 100644
--- a/contrib/libs/openssl/crypto/bio/b_dump.c
+++ b/contrib/libs/openssl/crypto/bio/b_dump.c
@@ -1,148 +1,148 @@
-/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-/*
- * Stolen from tjh's ssl/ssl_trc.c stuff.
- */
-
-#include <stdio.h>
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * Stolen from tjh's ssl/ssl_trc.c stuff.
+ */
+
+#include <stdio.h>
#include "bio_local.h"
-
-#define DUMP_WIDTH 16
-#define DUMP_WIDTH_LESS_INDENT(i) (DUMP_WIDTH - ((i - (i > 6 ? 6 : i) + 3) / 4))
-
-#define SPACE(buf, pos, n) (sizeof(buf) - (pos) > (n))
-
-int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u),
- void *u, const char *s, int len)
-{
- return BIO_dump_indent_cb(cb, u, s, len, 0);
-}
-
-int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u),
- void *u, const char *s, int len, int indent)
-{
- int ret = 0;
- char buf[288 + 1];
- int i, j, rows, n;
- unsigned char ch;
- int dump_width;
-
- if (indent < 0)
- indent = 0;
+
+#define DUMP_WIDTH 16
+#define DUMP_WIDTH_LESS_INDENT(i) (DUMP_WIDTH - ((i - (i > 6 ? 6 : i) + 3) / 4))
+
+#define SPACE(buf, pos, n) (sizeof(buf) - (pos) > (n))
+
+int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u),
+ void *u, const char *s, int len)
+{
+ return BIO_dump_indent_cb(cb, u, s, len, 0);
+}
+
+int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u),
+ void *u, const char *s, int len, int indent)
+{
+ int ret = 0;
+ char buf[288 + 1];
+ int i, j, rows, n;
+ unsigned char ch;
+ int dump_width;
+
+ if (indent < 0)
+ indent = 0;
else if (indent > 64)
indent = 64;
-
- dump_width = DUMP_WIDTH_LESS_INDENT(indent);
- rows = len / dump_width;
- if ((rows * dump_width) < len)
- rows++;
- for (i = 0; i < rows; i++) {
- n = BIO_snprintf(buf, sizeof(buf), "%*s%04x - ", indent, "",
- i * dump_width);
- for (j = 0; j < dump_width; j++) {
- if (SPACE(buf, n, 3)) {
- if (((i * dump_width) + j) >= len) {
- strcpy(buf + n, " ");
- } else {
- ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff;
- BIO_snprintf(buf + n, 4, "%02x%c", ch,
- j == 7 ? '-' : ' ');
- }
- n += 3;
- }
- }
- if (SPACE(buf, n, 2)) {
- strcpy(buf + n, " ");
- n += 2;
- }
- for (j = 0; j < dump_width; j++) {
- if (((i * dump_width) + j) >= len)
- break;
- if (SPACE(buf, n, 1)) {
- ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff;
-#ifndef CHARSET_EBCDIC
- buf[n++] = ((ch >= ' ') && (ch <= '~')) ? ch : '.';
-#else
- buf[n++] = ((ch >= os_toascii[' ']) && (ch <= os_toascii['~']))
- ? os_toebcdic[ch]
- : '.';
-#endif
- buf[n] = '\0';
- }
- }
- if (SPACE(buf, n, 1)) {
- buf[n++] = '\n';
- buf[n] = '\0';
- }
- /*
- * if this is the last call then update the ddt_dump thing so that we
- * will move the selection point in the debug window
- */
- ret += cb((void *)buf, n, u);
- }
- return ret;
-}
-
-#ifndef OPENSSL_NO_STDIO
-static int write_fp(const void *data, size_t len, void *fp)
-{
- return UP_fwrite(data, len, 1, fp);
-}
-
-int BIO_dump_fp(FILE *fp, const char *s, int len)
-{
- return BIO_dump_cb(write_fp, fp, s, len);
-}
-
-int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent)
-{
- return BIO_dump_indent_cb(write_fp, fp, s, len, indent);
-}
-#endif
-
-static int write_bio(const void *data, size_t len, void *bp)
-{
- return BIO_write((BIO *)bp, (const char *)data, len);
-}
-
-int BIO_dump(BIO *bp, const char *s, int len)
-{
- return BIO_dump_cb(write_bio, bp, s, len);
-}
-
-int BIO_dump_indent(BIO *bp, const char *s, int len, int indent)
-{
- return BIO_dump_indent_cb(write_bio, bp, s, len, indent);
-}
-
-int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data,
- int datalen)
-{
- int i, j = 0;
-
- if (datalen < 1)
- return 1;
-
- for (i = 0; i < datalen - 1; i++) {
- if (i && !j)
- BIO_printf(out, "%*s", indent, "");
-
- BIO_printf(out, "%02X:", data[i]);
-
- j = (j + 1) % width;
- if (!j)
- BIO_printf(out, "\n");
- }
-
- if (i && !j)
- BIO_printf(out, "%*s", indent, "");
- BIO_printf(out, "%02X", data[datalen - 1]);
- return 1;
-}
+
+ dump_width = DUMP_WIDTH_LESS_INDENT(indent);
+ rows = len / dump_width;
+ if ((rows * dump_width) < len)
+ rows++;
+ for (i = 0; i < rows; i++) {
+ n = BIO_snprintf(buf, sizeof(buf), "%*s%04x - ", indent, "",
+ i * dump_width);
+ for (j = 0; j < dump_width; j++) {
+ if (SPACE(buf, n, 3)) {
+ if (((i * dump_width) + j) >= len) {
+ strcpy(buf + n, " ");
+ } else {
+ ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff;
+ BIO_snprintf(buf + n, 4, "%02x%c", ch,
+ j == 7 ? '-' : ' ');
+ }
+ n += 3;
+ }
+ }
+ if (SPACE(buf, n, 2)) {
+ strcpy(buf + n, " ");
+ n += 2;
+ }
+ for (j = 0; j < dump_width; j++) {
+ if (((i * dump_width) + j) >= len)
+ break;
+ if (SPACE(buf, n, 1)) {
+ ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff;
+#ifndef CHARSET_EBCDIC
+ buf[n++] = ((ch >= ' ') && (ch <= '~')) ? ch : '.';
+#else
+ buf[n++] = ((ch >= os_toascii[' ']) && (ch <= os_toascii['~']))
+ ? os_toebcdic[ch]
+ : '.';
+#endif
+ buf[n] = '\0';
+ }
+ }
+ if (SPACE(buf, n, 1)) {
+ buf[n++] = '\n';
+ buf[n] = '\0';
+ }
+ /*
+ * if this is the last call then update the ddt_dump thing so that we
+ * will move the selection point in the debug window
+ */
+ ret += cb((void *)buf, n, u);
+ }
+ return ret;
+}
+
+#ifndef OPENSSL_NO_STDIO
+static int write_fp(const void *data, size_t len, void *fp)
+{
+ return UP_fwrite(data, len, 1, fp);
+}
+
+int BIO_dump_fp(FILE *fp, const char *s, int len)
+{
+ return BIO_dump_cb(write_fp, fp, s, len);
+}
+
+int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent)
+{
+ return BIO_dump_indent_cb(write_fp, fp, s, len, indent);
+}
+#endif
+
+static int write_bio(const void *data, size_t len, void *bp)
+{
+ return BIO_write((BIO *)bp, (const char *)data, len);
+}
+
+int BIO_dump(BIO *bp, const char *s, int len)
+{
+ return BIO_dump_cb(write_bio, bp, s, len);
+}
+
+int BIO_dump_indent(BIO *bp, const char *s, int len, int indent)
+{
+ return BIO_dump_indent_cb(write_bio, bp, s, len, indent);
+}
+
+int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data,
+ int datalen)
+{
+ int i, j = 0;
+
+ if (datalen < 1)
+ return 1;
+
+ for (i = 0; i < datalen - 1; i++) {
+ if (i && !j)
+ BIO_printf(out, "%*s", indent, "");
+
+ BIO_printf(out, "%02X:", data[i]);
+
+ j = (j + 1) % width;
+ if (!j)
+ BIO_printf(out, "\n");
+ }
+
+ if (i && !j)
+ BIO_printf(out, "%*s", indent, "");
+ BIO_printf(out, "%02X", data[datalen - 1]);
+ return 1;
+}
diff --git a/contrib/libs/openssl/crypto/bio/b_print.c b/contrib/libs/openssl/crypto/bio/b_print.c
index 49d4e1c473..41b7f5e2f6 100644
--- a/contrib/libs/openssl/crypto/bio/b_print.c
+++ b/contrib/libs/openssl/crypto/bio/b_print.c
@@ -1,934 +1,934 @@
-/*
+/*
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "internal/cryptlib.h"
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "internal/cryptlib.h"
#include "crypto/ctype.h"
-#include "internal/numbers.h"
-#include <openssl/bio.h>
-
-/*
- * Copyright Patrick Powell 1995
- * This code is based on code written by Patrick Powell <papowell@astart.com>
- * It may be used for any purpose as long as this notice remains intact
- * on all source code distributions.
- */
-
-#ifdef HAVE_LONG_DOUBLE
-# define LDOUBLE long double
-#else
-# define LDOUBLE double
-#endif
-
-static int fmtstr(char **, char **, size_t *, size_t *,
- const char *, int, int, int);
-static int fmtint(char **, char **, size_t *, size_t *,
- int64_t, int, int, int, int);
-static int fmtfp(char **, char **, size_t *, size_t *,
- LDOUBLE, int, int, int, int);
-static int doapr_outch(char **, char **, size_t *, size_t *, int);
-static int _dopr(char **sbuffer, char **buffer,
- size_t *maxlen, size_t *retlen, int *truncated,
- const char *format, va_list args);
-
-/* format read states */
-#define DP_S_DEFAULT 0
-#define DP_S_FLAGS 1
-#define DP_S_MIN 2
-#define DP_S_DOT 3
-#define DP_S_MAX 4
-#define DP_S_MOD 5
-#define DP_S_CONV 6
-#define DP_S_DONE 7
-
-/* format flags - Bits */
-/* left-aligned padding */
-#define DP_F_MINUS (1 << 0)
-/* print an explicit '+' for a value with positive sign */
-#define DP_F_PLUS (1 << 1)
-/* print an explicit ' ' for a value with positive sign */
-#define DP_F_SPACE (1 << 2)
-/* print 0/0x prefix for octal/hex and decimal point for floating point */
-#define DP_F_NUM (1 << 3)
-/* print leading zeroes */
-#define DP_F_ZERO (1 << 4)
-/* print HEX in UPPPERcase */
-#define DP_F_UP (1 << 5)
-/* treat value as unsigned */
-#define DP_F_UNSIGNED (1 << 6)
-
-/* conversion flags */
-#define DP_C_SHORT 1
-#define DP_C_LONG 2
-#define DP_C_LDOUBLE 3
-#define DP_C_LLONG 4
-#define DP_C_SIZE 5
-
-/* Floating point formats */
-#define F_FORMAT 0
-#define E_FORMAT 1
-#define G_FORMAT 2
-
-/* some handy macros */
-#define char_to_int(p) (p - '0')
-#define OSSL_MAX(p,q) ((p >= q) ? p : q)
-
-static int
-_dopr(char **sbuffer,
- char **buffer,
- size_t *maxlen,
- size_t *retlen, int *truncated, const char *format, va_list args)
-{
- char ch;
- int64_t value;
- LDOUBLE fvalue;
- char *strvalue;
- int min;
- int max;
- int state;
- int flags;
- int cflags;
- size_t currlen;
-
- state = DP_S_DEFAULT;
- flags = currlen = cflags = min = 0;
- max = -1;
- ch = *format++;
-
- while (state != DP_S_DONE) {
- if (ch == '\0' || (buffer == NULL && currlen >= *maxlen))
- state = DP_S_DONE;
-
- switch (state) {
- case DP_S_DEFAULT:
- if (ch == '%')
- state = DP_S_FLAGS;
- else
- if (!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
- return 0;
- ch = *format++;
- break;
- case DP_S_FLAGS:
- switch (ch) {
- case '-':
- flags |= DP_F_MINUS;
- ch = *format++;
- break;
- case '+':
- flags |= DP_F_PLUS;
- ch = *format++;
- break;
- case ' ':
- flags |= DP_F_SPACE;
- ch = *format++;
- break;
- case '#':
- flags |= DP_F_NUM;
- ch = *format++;
- break;
- case '0':
- flags |= DP_F_ZERO;
- ch = *format++;
- break;
- default:
- state = DP_S_MIN;
- break;
- }
- break;
- case DP_S_MIN:
- if (ossl_isdigit(ch)) {
- min = 10 * min + char_to_int(ch);
- ch = *format++;
- } else if (ch == '*') {
- min = va_arg(args, int);
- ch = *format++;
- state = DP_S_DOT;
- } else
- state = DP_S_DOT;
- break;
- case DP_S_DOT:
- if (ch == '.') {
- state = DP_S_MAX;
- ch = *format++;
- } else
- state = DP_S_MOD;
- break;
- case DP_S_MAX:
- if (ossl_isdigit(ch)) {
- if (max < 0)
- max = 0;
- max = 10 * max + char_to_int(ch);
- ch = *format++;
- } else if (ch == '*') {
- max = va_arg(args, int);
- ch = *format++;
- state = DP_S_MOD;
- } else
- state = DP_S_MOD;
- break;
- case DP_S_MOD:
- switch (ch) {
- case 'h':
- cflags = DP_C_SHORT;
- ch = *format++;
- break;
- case 'l':
- if (*format == 'l') {
- cflags = DP_C_LLONG;
- format++;
- } else
- cflags = DP_C_LONG;
- ch = *format++;
- break;
- case 'q':
- case 'j':
- cflags = DP_C_LLONG;
- ch = *format++;
- break;
- case 'L':
- cflags = DP_C_LDOUBLE;
- ch = *format++;
- break;
- case 'z':
- cflags = DP_C_SIZE;
- ch = *format++;
- break;
- default:
- break;
- }
- state = DP_S_CONV;
- break;
- case DP_S_CONV:
- switch (ch) {
- case 'd':
- case 'i':
- switch (cflags) {
- case DP_C_SHORT:
- value = (short int)va_arg(args, int);
- break;
- case DP_C_LONG:
- value = va_arg(args, long int);
- break;
- case DP_C_LLONG:
- value = va_arg(args, int64_t);
- break;
- case DP_C_SIZE:
- value = va_arg(args, ossl_ssize_t);
- break;
- default:
- value = va_arg(args, int);
- break;
- }
- if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, 10, min,
- max, flags))
- return 0;
- break;
- case 'X':
- flags |= DP_F_UP;
- /* FALLTHROUGH */
- case 'x':
- case 'o':
- case 'u':
- flags |= DP_F_UNSIGNED;
- switch (cflags) {
- case DP_C_SHORT:
- value = (unsigned short int)va_arg(args, unsigned int);
- break;
- case DP_C_LONG:
- value = va_arg(args, unsigned long int);
- break;
- case DP_C_LLONG:
- value = va_arg(args, uint64_t);
- break;
- case DP_C_SIZE:
- value = va_arg(args, size_t);
- break;
- default:
- value = va_arg(args, unsigned int);
- break;
- }
- if (!fmtint(sbuffer, buffer, &currlen, maxlen, value,
- ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
- min, max, flags))
- return 0;
- break;
- case 'f':
- if (cflags == DP_C_LDOUBLE)
- fvalue = va_arg(args, LDOUBLE);
- else
- fvalue = va_arg(args, double);
- if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
- flags, F_FORMAT))
- return 0;
- break;
- case 'E':
- flags |= DP_F_UP;
- /* fall thru */
- case 'e':
- if (cflags == DP_C_LDOUBLE)
- fvalue = va_arg(args, LDOUBLE);
- else
- fvalue = va_arg(args, double);
- if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
- flags, E_FORMAT))
- return 0;
- break;
- case 'G':
- flags |= DP_F_UP;
- /* fall thru */
- case 'g':
- if (cflags == DP_C_LDOUBLE)
- fvalue = va_arg(args, LDOUBLE);
- else
- fvalue = va_arg(args, double);
- if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
- flags, G_FORMAT))
- return 0;
- break;
- case 'c':
- if (!doapr_outch(sbuffer, buffer, &currlen, maxlen,
- va_arg(args, int)))
- return 0;
- break;
- case 's':
- strvalue = va_arg(args, char *);
- if (max < 0) {
- if (buffer)
- max = INT_MAX;
- else
- max = *maxlen;
- }
- if (!fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
- flags, min, max))
- return 0;
- break;
- case 'p':
- value = (size_t)va_arg(args, void *);
- if (!fmtint(sbuffer, buffer, &currlen, maxlen,
- value, 16, min, max, flags | DP_F_NUM))
- return 0;
- break;
- case 'n':
- {
- int *num;
- num = va_arg(args, int *);
- *num = currlen;
- }
- break;
- case '%':
- if (!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
- return 0;
- break;
- case 'w':
- /* not supported yet, treat as next char */
- ch = *format++;
- break;
- default:
- /* unknown, skip */
- break;
- }
- ch = *format++;
- state = DP_S_DEFAULT;
- flags = cflags = min = 0;
- max = -1;
- break;
- case DP_S_DONE:
- break;
- default:
- break;
- }
- }
- /*
- * We have to truncate if there is no dynamic buffer and we have filled the
- * static buffer.
- */
- if (buffer == NULL) {
- *truncated = (currlen > *maxlen - 1);
- if (*truncated)
- currlen = *maxlen - 1;
- }
- if (!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0'))
- return 0;
- *retlen = currlen - 1;
- return 1;
-}
-
-static int
-fmtstr(char **sbuffer,
- char **buffer,
- size_t *currlen,
- size_t *maxlen, const char *value, int flags, int min, int max)
-{
- int padlen;
- size_t strln;
- int cnt = 0;
-
- if (value == 0)
- value = "<NULL>";
-
- strln = OPENSSL_strnlen(value, max < 0 ? SIZE_MAX : (size_t)max);
-
- padlen = min - strln;
- if (min < 0 || padlen < 0)
- padlen = 0;
- if (max >= 0) {
- /*
- * Calculate the maximum output including padding.
- * Make sure max doesn't overflow into negativity
- */
- if (max < INT_MAX - padlen)
- max += padlen;
- else
- max = INT_MAX;
- }
- if (flags & DP_F_MINUS)
- padlen = -padlen;
-
- while ((padlen > 0) && (max < 0 || cnt < max)) {
- if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
- return 0;
- --padlen;
- ++cnt;
- }
- while (strln > 0 && (max < 0 || cnt < max)) {
- if (!doapr_outch(sbuffer, buffer, currlen, maxlen, *value++))
- return 0;
- --strln;
- ++cnt;
- }
- while ((padlen < 0) && (max < 0 || cnt < max)) {
- if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
- return 0;
- ++padlen;
- ++cnt;
- }
- return 1;
-}
-
-static int
-fmtint(char **sbuffer,
- char **buffer,
- size_t *currlen,
- size_t *maxlen, int64_t value, int base, int min, int max, int flags)
-{
- int signvalue = 0;
- const char *prefix = "";
- uint64_t uvalue;
- char convert[DECIMAL_SIZE(value) + 3];
- int place = 0;
- int spadlen = 0;
- int zpadlen = 0;
- int caps = 0;
-
- if (max < 0)
- max = 0;
- uvalue = value;
- if (!(flags & DP_F_UNSIGNED)) {
- if (value < 0) {
- signvalue = '-';
- uvalue = 0 - (uint64_t)value;
- } else if (flags & DP_F_PLUS)
- signvalue = '+';
- else if (flags & DP_F_SPACE)
- signvalue = ' ';
- }
- if (flags & DP_F_NUM) {
- if (base == 8)
- prefix = "0";
- if (base == 16)
- prefix = "0x";
- }
- if (flags & DP_F_UP)
- caps = 1;
- do {
- convert[place++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")
- [uvalue % (unsigned)base];
- uvalue = (uvalue / (unsigned)base);
- } while (uvalue && (place < (int)sizeof(convert)));
- if (place == sizeof(convert))
- place--;
- convert[place] = 0;
-
- zpadlen = max - place;
- spadlen =
- min - OSSL_MAX(max, place) - (signvalue ? 1 : 0) - strlen(prefix);
- if (zpadlen < 0)
- zpadlen = 0;
- if (spadlen < 0)
- spadlen = 0;
- if (flags & DP_F_ZERO) {
- zpadlen = OSSL_MAX(zpadlen, spadlen);
- spadlen = 0;
- }
- if (flags & DP_F_MINUS)
- spadlen = -spadlen;
-
- /* spaces */
- while (spadlen > 0) {
- if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
- return 0;
- --spadlen;
- }
-
- /* sign */
- if (signvalue)
- if (!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
- return 0;
-
- /* prefix */
- while (*prefix) {
- if (!doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix))
- return 0;
- prefix++;
- }
-
- /* zeros */
- if (zpadlen > 0) {
- while (zpadlen > 0) {
- if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
- return 0;
- --zpadlen;
- }
- }
- /* digits */
- while (place > 0) {
- if (!doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]))
- return 0;
- }
-
- /* left justified spaces */
- while (spadlen < 0) {
- if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
- return 0;
- ++spadlen;
- }
- return 1;
-}
-
-static LDOUBLE abs_val(LDOUBLE value)
-{
- LDOUBLE result = value;
- if (value < 0)
- result = -value;
- return result;
-}
-
-static LDOUBLE pow_10(int in_exp)
-{
- LDOUBLE result = 1;
- while (in_exp) {
- result *= 10;
- in_exp--;
- }
- return result;
-}
-
-static long roundv(LDOUBLE value)
-{
- long intpart;
- intpart = (long)value;
- value = value - intpart;
- if (value >= 0.5)
- intpart++;
- return intpart;
-}
-
-static int
-fmtfp(char **sbuffer,
- char **buffer,
- size_t *currlen,
- size_t *maxlen, LDOUBLE fvalue, int min, int max, int flags, int style)
-{
- int signvalue = 0;
- LDOUBLE ufvalue;
- LDOUBLE tmpvalue;
- char iconvert[20];
- char fconvert[20];
- char econvert[20];
- int iplace = 0;
- int fplace = 0;
- int eplace = 0;
- int padlen = 0;
- int zpadlen = 0;
- long exp = 0;
- unsigned long intpart;
- unsigned long fracpart;
- unsigned long max10;
- int realstyle;
-
- if (max < 0)
- max = 6;
-
- if (fvalue < 0)
- signvalue = '-';
- else if (flags & DP_F_PLUS)
- signvalue = '+';
- else if (flags & DP_F_SPACE)
- signvalue = ' ';
-
- /*
- * G_FORMAT sometimes prints like E_FORMAT and sometimes like F_FORMAT
- * depending on the number to be printed. Work out which one it is and use
- * that from here on.
- */
- if (style == G_FORMAT) {
- if (fvalue == 0.0) {
- realstyle = F_FORMAT;
- } else if (fvalue < 0.0001) {
- realstyle = E_FORMAT;
- } else if ((max == 0 && fvalue >= 10)
- || (max > 0 && fvalue >= pow_10(max))) {
- realstyle = E_FORMAT;
- } else {
- realstyle = F_FORMAT;
- }
- } else {
- realstyle = style;
- }
-
- if (style != F_FORMAT) {
- tmpvalue = fvalue;
- /* Calculate the exponent */
- if (fvalue != 0.0) {
- while (tmpvalue < 1) {
- tmpvalue *= 10;
- exp--;
- }
- while (tmpvalue > 10) {
- tmpvalue /= 10;
- exp++;
- }
- }
- if (style == G_FORMAT) {
- /*
- * In G_FORMAT the "precision" represents significant digits. We
- * always have at least 1 significant digit.
- */
- if (max == 0)
- max = 1;
- /* Now convert significant digits to decimal places */
- if (realstyle == F_FORMAT) {
- max -= (exp + 1);
- if (max < 0) {
- /*
- * Should not happen. If we're in F_FORMAT then exp < max?
- */
- return 0;
- }
- } else {
- /*
- * In E_FORMAT there is always one significant digit in front
- * of the decimal point, so:
- * significant digits == 1 + decimal places
- */
- max--;
- }
- }
- if (realstyle == E_FORMAT)
- fvalue = tmpvalue;
- }
- ufvalue = abs_val(fvalue);
+#include "internal/numbers.h"
+#include <openssl/bio.h>
+
+/*
+ * Copyright Patrick Powell 1995
+ * This code is based on code written by Patrick Powell <papowell@astart.com>
+ * It may be used for any purpose as long as this notice remains intact
+ * on all source code distributions.
+ */
+
+#ifdef HAVE_LONG_DOUBLE
+# define LDOUBLE long double
+#else
+# define LDOUBLE double
+#endif
+
+static int fmtstr(char **, char **, size_t *, size_t *,
+ const char *, int, int, int);
+static int fmtint(char **, char **, size_t *, size_t *,
+ int64_t, int, int, int, int);
+static int fmtfp(char **, char **, size_t *, size_t *,
+ LDOUBLE, int, int, int, int);
+static int doapr_outch(char **, char **, size_t *, size_t *, int);
+static int _dopr(char **sbuffer, char **buffer,
+ size_t *maxlen, size_t *retlen, int *truncated,
+ const char *format, va_list args);
+
+/* format read states */
+#define DP_S_DEFAULT 0
+#define DP_S_FLAGS 1
+#define DP_S_MIN 2
+#define DP_S_DOT 3
+#define DP_S_MAX 4
+#define DP_S_MOD 5
+#define DP_S_CONV 6
+#define DP_S_DONE 7
+
+/* format flags - Bits */
+/* left-aligned padding */
+#define DP_F_MINUS (1 << 0)
+/* print an explicit '+' for a value with positive sign */
+#define DP_F_PLUS (1 << 1)
+/* print an explicit ' ' for a value with positive sign */
+#define DP_F_SPACE (1 << 2)
+/* print 0/0x prefix for octal/hex and decimal point for floating point */
+#define DP_F_NUM (1 << 3)
+/* print leading zeroes */
+#define DP_F_ZERO (1 << 4)
+/* print HEX in UPPPERcase */
+#define DP_F_UP (1 << 5)
+/* treat value as unsigned */
+#define DP_F_UNSIGNED (1 << 6)
+
+/* conversion flags */
+#define DP_C_SHORT 1
+#define DP_C_LONG 2
+#define DP_C_LDOUBLE 3
+#define DP_C_LLONG 4
+#define DP_C_SIZE 5
+
+/* Floating point formats */
+#define F_FORMAT 0
+#define E_FORMAT 1
+#define G_FORMAT 2
+
+/* some handy macros */
+#define char_to_int(p) (p - '0')
+#define OSSL_MAX(p,q) ((p >= q) ? p : q)
+
+static int
+_dopr(char **sbuffer,
+ char **buffer,
+ size_t *maxlen,
+ size_t *retlen, int *truncated, const char *format, va_list args)
+{
+ char ch;
+ int64_t value;
+ LDOUBLE fvalue;
+ char *strvalue;
+ int min;
+ int max;
+ int state;
+ int flags;
+ int cflags;
+ size_t currlen;
+
+ state = DP_S_DEFAULT;
+ flags = currlen = cflags = min = 0;
+ max = -1;
+ ch = *format++;
+
+ while (state != DP_S_DONE) {
+ if (ch == '\0' || (buffer == NULL && currlen >= *maxlen))
+ state = DP_S_DONE;
+
+ switch (state) {
+ case DP_S_DEFAULT:
+ if (ch == '%')
+ state = DP_S_FLAGS;
+ else
+ if (!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
+ return 0;
+ ch = *format++;
+ break;
+ case DP_S_FLAGS:
+ switch (ch) {
+ case '-':
+ flags |= DP_F_MINUS;
+ ch = *format++;
+ break;
+ case '+':
+ flags |= DP_F_PLUS;
+ ch = *format++;
+ break;
+ case ' ':
+ flags |= DP_F_SPACE;
+ ch = *format++;
+ break;
+ case '#':
+ flags |= DP_F_NUM;
+ ch = *format++;
+ break;
+ case '0':
+ flags |= DP_F_ZERO;
+ ch = *format++;
+ break;
+ default:
+ state = DP_S_MIN;
+ break;
+ }
+ break;
+ case DP_S_MIN:
+ if (ossl_isdigit(ch)) {
+ min = 10 * min + char_to_int(ch);
+ ch = *format++;
+ } else if (ch == '*') {
+ min = va_arg(args, int);
+ ch = *format++;
+ state = DP_S_DOT;
+ } else
+ state = DP_S_DOT;
+ break;
+ case DP_S_DOT:
+ if (ch == '.') {
+ state = DP_S_MAX;
+ ch = *format++;
+ } else
+ state = DP_S_MOD;
+ break;
+ case DP_S_MAX:
+ if (ossl_isdigit(ch)) {
+ if (max < 0)
+ max = 0;
+ max = 10 * max + char_to_int(ch);
+ ch = *format++;
+ } else if (ch == '*') {
+ max = va_arg(args, int);
+ ch = *format++;
+ state = DP_S_MOD;
+ } else
+ state = DP_S_MOD;
+ break;
+ case DP_S_MOD:
+ switch (ch) {
+ case 'h':
+ cflags = DP_C_SHORT;
+ ch = *format++;
+ break;
+ case 'l':
+ if (*format == 'l') {
+ cflags = DP_C_LLONG;
+ format++;
+ } else
+ cflags = DP_C_LONG;
+ ch = *format++;
+ break;
+ case 'q':
+ case 'j':
+ cflags = DP_C_LLONG;
+ ch = *format++;
+ break;
+ case 'L':
+ cflags = DP_C_LDOUBLE;
+ ch = *format++;
+ break;
+ case 'z':
+ cflags = DP_C_SIZE;
+ ch = *format++;
+ break;
+ default:
+ break;
+ }
+ state = DP_S_CONV;
+ break;
+ case DP_S_CONV:
+ switch (ch) {
+ case 'd':
+ case 'i':
+ switch (cflags) {
+ case DP_C_SHORT:
+ value = (short int)va_arg(args, int);
+ break;
+ case DP_C_LONG:
+ value = va_arg(args, long int);
+ break;
+ case DP_C_LLONG:
+ value = va_arg(args, int64_t);
+ break;
+ case DP_C_SIZE:
+ value = va_arg(args, ossl_ssize_t);
+ break;
+ default:
+ value = va_arg(args, int);
+ break;
+ }
+ if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, 10, min,
+ max, flags))
+ return 0;
+ break;
+ case 'X':
+ flags |= DP_F_UP;
+ /* FALLTHROUGH */
+ case 'x':
+ case 'o':
+ case 'u':
+ flags |= DP_F_UNSIGNED;
+ switch (cflags) {
+ case DP_C_SHORT:
+ value = (unsigned short int)va_arg(args, unsigned int);
+ break;
+ case DP_C_LONG:
+ value = va_arg(args, unsigned long int);
+ break;
+ case DP_C_LLONG:
+ value = va_arg(args, uint64_t);
+ break;
+ case DP_C_SIZE:
+ value = va_arg(args, size_t);
+ break;
+ default:
+ value = va_arg(args, unsigned int);
+ break;
+ }
+ if (!fmtint(sbuffer, buffer, &currlen, maxlen, value,
+ ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
+ min, max, flags))
+ return 0;
+ break;
+ case 'f':
+ if (cflags == DP_C_LDOUBLE)
+ fvalue = va_arg(args, LDOUBLE);
+ else
+ fvalue = va_arg(args, double);
+ if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
+ flags, F_FORMAT))
+ return 0;
+ break;
+ case 'E':
+ flags |= DP_F_UP;
+ /* fall thru */
+ case 'e':
+ if (cflags == DP_C_LDOUBLE)
+ fvalue = va_arg(args, LDOUBLE);
+ else
+ fvalue = va_arg(args, double);
+ if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
+ flags, E_FORMAT))
+ return 0;
+ break;
+ case 'G':
+ flags |= DP_F_UP;
+ /* fall thru */
+ case 'g':
+ if (cflags == DP_C_LDOUBLE)
+ fvalue = va_arg(args, LDOUBLE);
+ else
+ fvalue = va_arg(args, double);
+ if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
+ flags, G_FORMAT))
+ return 0;
+ break;
+ case 'c':
+ if (!doapr_outch(sbuffer, buffer, &currlen, maxlen,
+ va_arg(args, int)))
+ return 0;
+ break;
+ case 's':
+ strvalue = va_arg(args, char *);
+ if (max < 0) {
+ if (buffer)
+ max = INT_MAX;
+ else
+ max = *maxlen;
+ }
+ if (!fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
+ flags, min, max))
+ return 0;
+ break;
+ case 'p':
+ value = (size_t)va_arg(args, void *);
+ if (!fmtint(sbuffer, buffer, &currlen, maxlen,
+ value, 16, min, max, flags | DP_F_NUM))
+ return 0;
+ break;
+ case 'n':
+ {
+ int *num;
+ num = va_arg(args, int *);
+ *num = currlen;
+ }
+ break;
+ case '%':
+ if (!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
+ return 0;
+ break;
+ case 'w':
+ /* not supported yet, treat as next char */
+ ch = *format++;
+ break;
+ default:
+ /* unknown, skip */
+ break;
+ }
+ ch = *format++;
+ state = DP_S_DEFAULT;
+ flags = cflags = min = 0;
+ max = -1;
+ break;
+ case DP_S_DONE:
+ break;
+ default:
+ break;
+ }
+ }
+ /*
+ * We have to truncate if there is no dynamic buffer and we have filled the
+ * static buffer.
+ */
+ if (buffer == NULL) {
+ *truncated = (currlen > *maxlen - 1);
+ if (*truncated)
+ currlen = *maxlen - 1;
+ }
+ if (!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0'))
+ return 0;
+ *retlen = currlen - 1;
+ return 1;
+}
+
+static int
+fmtstr(char **sbuffer,
+ char **buffer,
+ size_t *currlen,
+ size_t *maxlen, const char *value, int flags, int min, int max)
+{
+ int padlen;
+ size_t strln;
+ int cnt = 0;
+
+ if (value == 0)
+ value = "<NULL>";
+
+ strln = OPENSSL_strnlen(value, max < 0 ? SIZE_MAX : (size_t)max);
+
+ padlen = min - strln;
+ if (min < 0 || padlen < 0)
+ padlen = 0;
+ if (max >= 0) {
+ /*
+ * Calculate the maximum output including padding.
+ * Make sure max doesn't overflow into negativity
+ */
+ if (max < INT_MAX - padlen)
+ max += padlen;
+ else
+ max = INT_MAX;
+ }
+ if (flags & DP_F_MINUS)
+ padlen = -padlen;
+
+ while ((padlen > 0) && (max < 0 || cnt < max)) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
+ --padlen;
+ ++cnt;
+ }
+ while (strln > 0 && (max < 0 || cnt < max)) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, *value++))
+ return 0;
+ --strln;
+ ++cnt;
+ }
+ while ((padlen < 0) && (max < 0 || cnt < max)) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
+ ++padlen;
+ ++cnt;
+ }
+ return 1;
+}
+
+static int
+fmtint(char **sbuffer,
+ char **buffer,
+ size_t *currlen,
+ size_t *maxlen, int64_t value, int base, int min, int max, int flags)
+{
+ int signvalue = 0;
+ const char *prefix = "";
+ uint64_t uvalue;
+ char convert[DECIMAL_SIZE(value) + 3];
+ int place = 0;
+ int spadlen = 0;
+ int zpadlen = 0;
+ int caps = 0;
+
+ if (max < 0)
+ max = 0;
+ uvalue = value;
+ if (!(flags & DP_F_UNSIGNED)) {
+ if (value < 0) {
+ signvalue = '-';
+ uvalue = 0 - (uint64_t)value;
+ } else if (flags & DP_F_PLUS)
+ signvalue = '+';
+ else if (flags & DP_F_SPACE)
+ signvalue = ' ';
+ }
+ if (flags & DP_F_NUM) {
+ if (base == 8)
+ prefix = "0";
+ if (base == 16)
+ prefix = "0x";
+ }
+ if (flags & DP_F_UP)
+ caps = 1;
+ do {
+ convert[place++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")
+ [uvalue % (unsigned)base];
+ uvalue = (uvalue / (unsigned)base);
+ } while (uvalue && (place < (int)sizeof(convert)));
+ if (place == sizeof(convert))
+ place--;
+ convert[place] = 0;
+
+ zpadlen = max - place;
+ spadlen =
+ min - OSSL_MAX(max, place) - (signvalue ? 1 : 0) - strlen(prefix);
+ if (zpadlen < 0)
+ zpadlen = 0;
+ if (spadlen < 0)
+ spadlen = 0;
+ if (flags & DP_F_ZERO) {
+ zpadlen = OSSL_MAX(zpadlen, spadlen);
+ spadlen = 0;
+ }
+ if (flags & DP_F_MINUS)
+ spadlen = -spadlen;
+
+ /* spaces */
+ while (spadlen > 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
+ --spadlen;
+ }
+
+ /* sign */
+ if (signvalue)
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+ return 0;
+
+ /* prefix */
+ while (*prefix) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix))
+ return 0;
+ prefix++;
+ }
+
+ /* zeros */
+ if (zpadlen > 0) {
+ while (zpadlen > 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+ return 0;
+ --zpadlen;
+ }
+ }
+ /* digits */
+ while (place > 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]))
+ return 0;
+ }
+
+ /* left justified spaces */
+ while (spadlen < 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
+ ++spadlen;
+ }
+ return 1;
+}
+
+static LDOUBLE abs_val(LDOUBLE value)
+{
+ LDOUBLE result = value;
+ if (value < 0)
+ result = -value;
+ return result;
+}
+
+static LDOUBLE pow_10(int in_exp)
+{
+ LDOUBLE result = 1;
+ while (in_exp) {
+ result *= 10;
+ in_exp--;
+ }
+ return result;
+}
+
+static long roundv(LDOUBLE value)
+{
+ long intpart;
+ intpart = (long)value;
+ value = value - intpart;
+ if (value >= 0.5)
+ intpart++;
+ return intpart;
+}
+
+static int
+fmtfp(char **sbuffer,
+ char **buffer,
+ size_t *currlen,
+ size_t *maxlen, LDOUBLE fvalue, int min, int max, int flags, int style)
+{
+ int signvalue = 0;
+ LDOUBLE ufvalue;
+ LDOUBLE tmpvalue;
+ char iconvert[20];
+ char fconvert[20];
+ char econvert[20];
+ int iplace = 0;
+ int fplace = 0;
+ int eplace = 0;
+ int padlen = 0;
+ int zpadlen = 0;
+ long exp = 0;
+ unsigned long intpart;
+ unsigned long fracpart;
+ unsigned long max10;
+ int realstyle;
+
+ if (max < 0)
+ max = 6;
+
+ if (fvalue < 0)
+ signvalue = '-';
+ else if (flags & DP_F_PLUS)
+ signvalue = '+';
+ else if (flags & DP_F_SPACE)
+ signvalue = ' ';
+
+ /*
+ * G_FORMAT sometimes prints like E_FORMAT and sometimes like F_FORMAT
+ * depending on the number to be printed. Work out which one it is and use
+ * that from here on.
+ */
+ if (style == G_FORMAT) {
+ if (fvalue == 0.0) {
+ realstyle = F_FORMAT;
+ } else if (fvalue < 0.0001) {
+ realstyle = E_FORMAT;
+ } else if ((max == 0 && fvalue >= 10)
+ || (max > 0 && fvalue >= pow_10(max))) {
+ realstyle = E_FORMAT;
+ } else {
+ realstyle = F_FORMAT;
+ }
+ } else {
+ realstyle = style;
+ }
+
+ if (style != F_FORMAT) {
+ tmpvalue = fvalue;
+ /* Calculate the exponent */
+ if (fvalue != 0.0) {
+ while (tmpvalue < 1) {
+ tmpvalue *= 10;
+ exp--;
+ }
+ while (tmpvalue > 10) {
+ tmpvalue /= 10;
+ exp++;
+ }
+ }
+ if (style == G_FORMAT) {
+ /*
+ * In G_FORMAT the "precision" represents significant digits. We
+ * always have at least 1 significant digit.
+ */
+ if (max == 0)
+ max = 1;
+ /* Now convert significant digits to decimal places */
+ if (realstyle == F_FORMAT) {
+ max -= (exp + 1);
+ if (max < 0) {
+ /*
+ * Should not happen. If we're in F_FORMAT then exp < max?
+ */
+ return 0;
+ }
+ } else {
+ /*
+ * In E_FORMAT there is always one significant digit in front
+ * of the decimal point, so:
+ * significant digits == 1 + decimal places
+ */
+ max--;
+ }
+ }
+ if (realstyle == E_FORMAT)
+ fvalue = tmpvalue;
+ }
+ ufvalue = abs_val(fvalue);
/*
* By subtracting 65535 (2^16-1) we cancel the low order 15 bits
* of ULONG_MAX to avoid using imprecise floating point values.
*/
if (ufvalue >= (double)(ULONG_MAX - 65535) + 65536.0) {
- /* Number too big */
- return 0;
- }
- intpart = (unsigned long)ufvalue;
-
- /*
- * sorry, we only support 9 digits past the decimal because of our
- * conversion method
- */
- if (max > 9)
- max = 9;
-
- /*
- * we "cheat" by converting the fractional part to integer by multiplying
- * by a factor of 10
- */
- max10 = roundv(pow_10(max));
- fracpart = roundv(pow_10(max) * (ufvalue - intpart));
-
- if (fracpart >= max10) {
- intpart++;
- fracpart -= max10;
- }
-
- /* convert integer part */
- do {
- iconvert[iplace++] = "0123456789"[intpart % 10];
- intpart = (intpart / 10);
- } while (intpart && (iplace < (int)sizeof(iconvert)));
- if (iplace == sizeof(iconvert))
- iplace--;
- iconvert[iplace] = 0;
-
- /* convert fractional part */
- while (fplace < max) {
- if (style == G_FORMAT && fplace == 0 && (fracpart % 10) == 0) {
- /* We strip trailing zeros in G_FORMAT */
- max--;
- fracpart = fracpart / 10;
- if (fplace < max)
- continue;
- break;
- }
- fconvert[fplace++] = "0123456789"[fracpart % 10];
- fracpart = (fracpart / 10);
- }
-
- if (fplace == sizeof(fconvert))
- fplace--;
- fconvert[fplace] = 0;
-
- /* convert exponent part */
- if (realstyle == E_FORMAT) {
- int tmpexp;
- if (exp < 0)
- tmpexp = -exp;
- else
- tmpexp = exp;
-
- do {
- econvert[eplace++] = "0123456789"[tmpexp % 10];
- tmpexp = (tmpexp / 10);
- } while (tmpexp > 0 && eplace < (int)sizeof(econvert));
- /* Exponent is huge!! Too big to print */
- if (tmpexp > 0)
- return 0;
- /* Add a leading 0 for single digit exponents */
- if (eplace == 1)
- econvert[eplace++] = '0';
- }
-
- /*
- * -1 for decimal point (if we have one, i.e. max > 0),
- * another -1 if we are printing a sign
- */
- padlen = min - iplace - max - (max > 0 ? 1 : 0) - ((signvalue) ? 1 : 0);
- /* Take some off for exponent prefix "+e" and exponent */
- if (realstyle == E_FORMAT)
- padlen -= 2 + eplace;
- zpadlen = max - fplace;
- if (zpadlen < 0)
- zpadlen = 0;
- if (padlen < 0)
- padlen = 0;
- if (flags & DP_F_MINUS)
- padlen = -padlen;
-
- if ((flags & DP_F_ZERO) && (padlen > 0)) {
- if (signvalue) {
- if (!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
- return 0;
- --padlen;
- signvalue = 0;
- }
- while (padlen > 0) {
- if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
- return 0;
- --padlen;
- }
- }
- while (padlen > 0) {
- if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
- return 0;
- --padlen;
- }
- if (signvalue && !doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
- return 0;
-
- while (iplace > 0) {
- if (!doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]))
- return 0;
- }
-
- /*
- * Decimal point. This should probably use locale to find the correct
- * char to print out.
- */
- if (max > 0 || (flags & DP_F_NUM)) {
- if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '.'))
- return 0;
-
- while (fplace > 0) {
- if (!doapr_outch(sbuffer, buffer, currlen, maxlen,
- fconvert[--fplace]))
- return 0;
- }
- }
- while (zpadlen > 0) {
- if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
- return 0;
- --zpadlen;
- }
- if (realstyle == E_FORMAT) {
- char ech;
-
- if ((flags & DP_F_UP) == 0)
- ech = 'e';
- else
- ech = 'E';
- if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ech))
- return 0;
- if (exp < 0) {
- if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '-'))
- return 0;
- } else {
- if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '+'))
- return 0;
- }
- while (eplace > 0) {
- if (!doapr_outch(sbuffer, buffer, currlen, maxlen,
- econvert[--eplace]))
- return 0;
- }
- }
-
- while (padlen < 0) {
- if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
- return 0;
- ++padlen;
- }
- return 1;
-}
-
-#define BUFFER_INC 1024
-
-static int
-doapr_outch(char **sbuffer,
- char **buffer, size_t *currlen, size_t *maxlen, int c)
-{
- /* If we haven't at least one buffer, someone has done a big booboo */
- if (!ossl_assert(*sbuffer != NULL || buffer != NULL))
- return 0;
-
- /* |currlen| must always be <= |*maxlen| */
- if (!ossl_assert(*currlen <= *maxlen))
- return 0;
-
- if (buffer && *currlen == *maxlen) {
- if (*maxlen > INT_MAX - BUFFER_INC)
- return 0;
-
- *maxlen += BUFFER_INC;
- if (*buffer == NULL) {
- if ((*buffer = OPENSSL_malloc(*maxlen)) == NULL) {
- BIOerr(BIO_F_DOAPR_OUTCH, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- if (*currlen > 0) {
- if (!ossl_assert(*sbuffer != NULL))
- return 0;
- memcpy(*buffer, *sbuffer, *currlen);
- }
- *sbuffer = NULL;
- } else {
- char *tmpbuf;
- tmpbuf = OPENSSL_realloc(*buffer, *maxlen);
- if (tmpbuf == NULL)
- return 0;
- *buffer = tmpbuf;
- }
- }
-
- if (*currlen < *maxlen) {
- if (*sbuffer)
- (*sbuffer)[(*currlen)++] = (char)c;
- else
- (*buffer)[(*currlen)++] = (char)c;
- }
-
- return 1;
-}
-
-/***************************************************************************/
-
-int BIO_printf(BIO *bio, const char *format, ...)
-{
- va_list args;
- int ret;
-
- va_start(args, format);
-
- ret = BIO_vprintf(bio, format, args);
-
- va_end(args);
- return ret;
-}
-
-int BIO_vprintf(BIO *bio, const char *format, va_list args)
-{
- int ret;
- size_t retlen;
- char hugebuf[1024 * 2]; /* Was previously 10k, which is unreasonable
- * in small-stack environments, like threads
- * or DOS programs. */
- char *hugebufp = hugebuf;
- size_t hugebufsize = sizeof(hugebuf);
- char *dynbuf = NULL;
- int ignored;
-
- dynbuf = NULL;
- if (!_dopr(&hugebufp, &dynbuf, &hugebufsize, &retlen, &ignored, format,
- args)) {
- OPENSSL_free(dynbuf);
- return -1;
- }
- if (dynbuf) {
- ret = BIO_write(bio, dynbuf, (int)retlen);
- OPENSSL_free(dynbuf);
- } else {
- ret = BIO_write(bio, hugebuf, (int)retlen);
- }
- return ret;
-}
-
-/*
- * As snprintf is not available everywhere, we provide our own
- * implementation. This function has nothing to do with BIOs, but it's
- * closely related to BIO_printf, and we need *some* name prefix ... (XXX the
- * function should be renamed, but to what?)
- */
-int BIO_snprintf(char *buf, size_t n, const char *format, ...)
-{
- va_list args;
- int ret;
-
- va_start(args, format);
-
- ret = BIO_vsnprintf(buf, n, format, args);
-
- va_end(args);
- return ret;
-}
-
-int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
-{
- size_t retlen;
- int truncated;
-
- if (!_dopr(&buf, NULL, &n, &retlen, &truncated, format, args))
- return -1;
-
- if (truncated)
- /*
- * In case of truncation, return -1 like traditional snprintf.
- * (Current drafts for ISO/IEC 9899 say snprintf should return the
- * number of characters that would have been written, had the buffer
- * been large enough.)
- */
- return -1;
- else
- return (retlen <= INT_MAX) ? (int)retlen : -1;
-}
+ /* Number too big */
+ return 0;
+ }
+ intpart = (unsigned long)ufvalue;
+
+ /*
+ * sorry, we only support 9 digits past the decimal because of our
+ * conversion method
+ */
+ if (max > 9)
+ max = 9;
+
+ /*
+ * we "cheat" by converting the fractional part to integer by multiplying
+ * by a factor of 10
+ */
+ max10 = roundv(pow_10(max));
+ fracpart = roundv(pow_10(max) * (ufvalue - intpart));
+
+ if (fracpart >= max10) {
+ intpart++;
+ fracpart -= max10;
+ }
+
+ /* convert integer part */
+ do {
+ iconvert[iplace++] = "0123456789"[intpart % 10];
+ intpart = (intpart / 10);
+ } while (intpart && (iplace < (int)sizeof(iconvert)));
+ if (iplace == sizeof(iconvert))
+ iplace--;
+ iconvert[iplace] = 0;
+
+ /* convert fractional part */
+ while (fplace < max) {
+ if (style == G_FORMAT && fplace == 0 && (fracpart % 10) == 0) {
+ /* We strip trailing zeros in G_FORMAT */
+ max--;
+ fracpart = fracpart / 10;
+ if (fplace < max)
+ continue;
+ break;
+ }
+ fconvert[fplace++] = "0123456789"[fracpart % 10];
+ fracpart = (fracpart / 10);
+ }
+
+ if (fplace == sizeof(fconvert))
+ fplace--;
+ fconvert[fplace] = 0;
+
+ /* convert exponent part */
+ if (realstyle == E_FORMAT) {
+ int tmpexp;
+ if (exp < 0)
+ tmpexp = -exp;
+ else
+ tmpexp = exp;
+
+ do {
+ econvert[eplace++] = "0123456789"[tmpexp % 10];
+ tmpexp = (tmpexp / 10);
+ } while (tmpexp > 0 && eplace < (int)sizeof(econvert));
+ /* Exponent is huge!! Too big to print */
+ if (tmpexp > 0)
+ return 0;
+ /* Add a leading 0 for single digit exponents */
+ if (eplace == 1)
+ econvert[eplace++] = '0';
+ }
+
+ /*
+ * -1 for decimal point (if we have one, i.e. max > 0),
+ * another -1 if we are printing a sign
+ */
+ padlen = min - iplace - max - (max > 0 ? 1 : 0) - ((signvalue) ? 1 : 0);
+ /* Take some off for exponent prefix "+e" and exponent */
+ if (realstyle == E_FORMAT)
+ padlen -= 2 + eplace;
+ zpadlen = max - fplace;
+ if (zpadlen < 0)
+ zpadlen = 0;
+ if (padlen < 0)
+ padlen = 0;
+ if (flags & DP_F_MINUS)
+ padlen = -padlen;
+
+ if ((flags & DP_F_ZERO) && (padlen > 0)) {
+ if (signvalue) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+ return 0;
+ --padlen;
+ signvalue = 0;
+ }
+ while (padlen > 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+ return 0;
+ --padlen;
+ }
+ }
+ while (padlen > 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
+ --padlen;
+ }
+ if (signvalue && !doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+ return 0;
+
+ while (iplace > 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]))
+ return 0;
+ }
+
+ /*
+ * Decimal point. This should probably use locale to find the correct
+ * char to print out.
+ */
+ if (max > 0 || (flags & DP_F_NUM)) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '.'))
+ return 0;
+
+ while (fplace > 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen,
+ fconvert[--fplace]))
+ return 0;
+ }
+ }
+ while (zpadlen > 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+ return 0;
+ --zpadlen;
+ }
+ if (realstyle == E_FORMAT) {
+ char ech;
+
+ if ((flags & DP_F_UP) == 0)
+ ech = 'e';
+ else
+ ech = 'E';
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ech))
+ return 0;
+ if (exp < 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '-'))
+ return 0;
+ } else {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '+'))
+ return 0;
+ }
+ while (eplace > 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen,
+ econvert[--eplace]))
+ return 0;
+ }
+ }
+
+ while (padlen < 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
+ ++padlen;
+ }
+ return 1;
+}
+
+#define BUFFER_INC 1024
+
+static int
+doapr_outch(char **sbuffer,
+ char **buffer, size_t *currlen, size_t *maxlen, int c)
+{
+ /* If we haven't at least one buffer, someone has done a big booboo */
+ if (!ossl_assert(*sbuffer != NULL || buffer != NULL))
+ return 0;
+
+ /* |currlen| must always be <= |*maxlen| */
+ if (!ossl_assert(*currlen <= *maxlen))
+ return 0;
+
+ if (buffer && *currlen == *maxlen) {
+ if (*maxlen > INT_MAX - BUFFER_INC)
+ return 0;
+
+ *maxlen += BUFFER_INC;
+ if (*buffer == NULL) {
+ if ((*buffer = OPENSSL_malloc(*maxlen)) == NULL) {
+ BIOerr(BIO_F_DOAPR_OUTCH, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if (*currlen > 0) {
+ if (!ossl_assert(*sbuffer != NULL))
+ return 0;
+ memcpy(*buffer, *sbuffer, *currlen);
+ }
+ *sbuffer = NULL;
+ } else {
+ char *tmpbuf;
+ tmpbuf = OPENSSL_realloc(*buffer, *maxlen);
+ if (tmpbuf == NULL)
+ return 0;
+ *buffer = tmpbuf;
+ }
+ }
+
+ if (*currlen < *maxlen) {
+ if (*sbuffer)
+ (*sbuffer)[(*currlen)++] = (char)c;
+ else
+ (*buffer)[(*currlen)++] = (char)c;
+ }
+
+ return 1;
+}
+
+/***************************************************************************/
+
+int BIO_printf(BIO *bio, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start(args, format);
+
+ ret = BIO_vprintf(bio, format, args);
+
+ va_end(args);
+ return ret;
+}
+
+int BIO_vprintf(BIO *bio, const char *format, va_list args)
+{
+ int ret;
+ size_t retlen;
+ char hugebuf[1024 * 2]; /* Was previously 10k, which is unreasonable
+ * in small-stack environments, like threads
+ * or DOS programs. */
+ char *hugebufp = hugebuf;
+ size_t hugebufsize = sizeof(hugebuf);
+ char *dynbuf = NULL;
+ int ignored;
+
+ dynbuf = NULL;
+ if (!_dopr(&hugebufp, &dynbuf, &hugebufsize, &retlen, &ignored, format,
+ args)) {
+ OPENSSL_free(dynbuf);
+ return -1;
+ }
+ if (dynbuf) {
+ ret = BIO_write(bio, dynbuf, (int)retlen);
+ OPENSSL_free(dynbuf);
+ } else {
+ ret = BIO_write(bio, hugebuf, (int)retlen);
+ }
+ return ret;
+}
+
+/*
+ * As snprintf is not available everywhere, we provide our own
+ * implementation. This function has nothing to do with BIOs, but it's
+ * closely related to BIO_printf, and we need *some* name prefix ... (XXX the
+ * function should be renamed, but to what?)
+ */
+int BIO_snprintf(char *buf, size_t n, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start(args, format);
+
+ ret = BIO_vsnprintf(buf, n, format, args);
+
+ va_end(args);
+ return ret;
+}
+
+int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
+{
+ size_t retlen;
+ int truncated;
+
+ if (!_dopr(&buf, NULL, &n, &retlen, &truncated, format, args))
+ return -1;
+
+ if (truncated)
+ /*
+ * In case of truncation, return -1 like traditional snprintf.
+ * (Current drafts for ISO/IEC 9899 say snprintf should return the
+ * number of characters that would have been written, had the buffer
+ * been large enough.)
+ */
+ return -1;
+ else
+ return (retlen <= INT_MAX) ? (int)retlen : -1;
+}
diff --git a/contrib/libs/openssl/crypto/bio/b_sock.c b/contrib/libs/openssl/crypto/bio/b_sock.c
index 50ea7de346..df431e6d52 100644
--- a/contrib/libs/openssl/crypto/bio/b_sock.c
+++ b/contrib/libs/openssl/crypto/bio/b_sock.c
@@ -1,369 +1,369 @@
-/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
#include "bio_local.h"
-#ifndef OPENSSL_NO_SOCK
-# define SOCKET_PROTOCOL IPPROTO_TCP
-# ifdef SO_MAXCONN
-# define MAX_LISTEN SO_MAXCONN
-# elif defined(SOMAXCONN)
-# define MAX_LISTEN SOMAXCONN
-# else
-# define MAX_LISTEN 32
-# endif
-# if defined(OPENSSL_SYS_WINDOWS)
-static int wsa_init_done = 0;
-# endif
-
-# if OPENSSL_API_COMPAT < 0x10100000L
-int BIO_get_host_ip(const char *str, unsigned char *ip)
-{
- BIO_ADDRINFO *res = NULL;
- int ret = 0;
-
- if (BIO_sock_init() != 1)
- return 0; /* don't generate another error code here */
-
- if (BIO_lookup(str, NULL, BIO_LOOKUP_CLIENT, AF_INET, SOCK_STREAM, &res)) {
- size_t l;
-
- if (BIO_ADDRINFO_family(res) != AF_INET) {
- BIOerr(BIO_F_BIO_GET_HOST_IP,
- BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
- } else if (BIO_ADDR_rawaddress(BIO_ADDRINFO_address(res), NULL, &l)) {
- /*
- * Because only AF_INET addresses will reach this far, we can assert
- * that l should be 4
- */
- if (ossl_assert(l == 4))
- ret = BIO_ADDR_rawaddress(BIO_ADDRINFO_address(res), ip, &l);
- }
- BIO_ADDRINFO_free(res);
- } else {
- ERR_add_error_data(2, "host=", str);
- }
-
- return ret;
-}
-
-int BIO_get_port(const char *str, unsigned short *port_ptr)
-{
- BIO_ADDRINFO *res = NULL;
- int ret = 0;
-
- if (str == NULL) {
- BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_DEFINED);
- return 0;
- }
-
- if (BIO_sock_init() != 1)
- return 0; /* don't generate another error code here */
-
- if (BIO_lookup(NULL, str, BIO_LOOKUP_CLIENT, AF_INET, SOCK_STREAM, &res)) {
- if (BIO_ADDRINFO_family(res) != AF_INET) {
- BIOerr(BIO_F_BIO_GET_PORT,
- BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET);
- } else {
- *port_ptr = ntohs(BIO_ADDR_rawport(BIO_ADDRINFO_address(res)));
- ret = 1;
- }
- BIO_ADDRINFO_free(res);
- } else {
- ERR_add_error_data(2, "host=", str);
- }
-
- return ret;
-}
-# endif
-
-int BIO_sock_error(int sock)
-{
- int j = 0, i;
- socklen_t size = sizeof(j);
-
- /*
- * Note: under Windows the third parameter is of type (char *) whereas
- * under other systems it is (void *) if you don't have a cast it will
- * choke the compiler: if you do have a cast then you can either go for
- * (char *) or (void *).
- */
- i = getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)&j, &size);
- if (i < 0)
- return get_last_socket_error();
- else
- return j;
-}
-
-# if OPENSSL_API_COMPAT < 0x10100000L
-struct hostent *BIO_gethostbyname(const char *name)
-{
- /*
- * Caching gethostbyname() results forever is wrong, so we have to let
- * the true gethostbyname() worry about this
- */
- return gethostbyname(name);
-}
-# endif
-
-int BIO_sock_init(void)
-{
-# ifdef OPENSSL_SYS_WINDOWS
- static struct WSAData wsa_state;
-
- if (!wsa_init_done) {
- int err;
-
- wsa_init_done = 1;
- memset(&wsa_state, 0, sizeof(wsa_state));
- /*
- * Not making wsa_state available to the rest of the code is formally
- * wrong. But the structures we use are [believed to be] invariable
- * among Winsock DLLs, while API availability is [expected to be]
- * probed at run-time with DSO_global_lookup.
- */
- if (WSAStartup(0x0202, &wsa_state) != 0) {
- err = WSAGetLastError();
- SYSerr(SYS_F_WSASTARTUP, err);
- BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP);
- return -1;
- }
- }
-# endif /* OPENSSL_SYS_WINDOWS */
-# ifdef WATT32
- extern int _watt_do_exit;
- _watt_do_exit = 0; /* don't make sock_init() call exit() */
- if (sock_init())
- return -1;
-# endif
-
- return 1;
-}
-
-void bio_sock_cleanup_int(void)
-{
-# ifdef OPENSSL_SYS_WINDOWS
- if (wsa_init_done) {
- wsa_init_done = 0;
- WSACleanup();
- }
-# endif
-}
-
-int BIO_socket_ioctl(int fd, long type, void *arg)
-{
- int i;
-
-# ifdef __DJGPP__
- i = ioctlsocket(fd, type, (char *)arg);
-# else
-# if defined(OPENSSL_SYS_VMS)
- /*-
- * 2011-02-18 SMS.
- * VMS ioctl() can't tolerate a 64-bit "void *arg", but we
- * observe that all the consumers pass in an "unsigned long *",
- * so we arrange a local copy with a short pointer, and use
- * that, instead.
- */
-# if __INITIAL_POINTER_SIZE == 64
-# define ARG arg_32p
-# pragma pointer_size save
-# pragma pointer_size 32
- unsigned long arg_32;
- unsigned long *arg_32p;
-# pragma pointer_size restore
- arg_32p = &arg_32;
- arg_32 = *((unsigned long *)arg);
-# else /* __INITIAL_POINTER_SIZE == 64 */
-# define ARG arg
-# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
-# else /* defined(OPENSSL_SYS_VMS) */
-# define ARG arg
-# endif /* defined(OPENSSL_SYS_VMS) [else] */
-
- i = ioctlsocket(fd, type, ARG);
-# endif /* __DJGPP__ */
- if (i < 0)
- SYSerr(SYS_F_IOCTLSOCKET, get_last_socket_error());
- return i;
-}
-
-# if OPENSSL_API_COMPAT < 0x10100000L
-int BIO_get_accept_socket(char *host, int bind_mode)
-{
- int s = INVALID_SOCKET;
- char *h = NULL, *p = NULL;
- BIO_ADDRINFO *res = NULL;
-
- if (!BIO_parse_hostserv(host, &h, &p, BIO_PARSE_PRIO_SERV))
- return INVALID_SOCKET;
-
- if (BIO_sock_init() != 1)
- return INVALID_SOCKET;
-
- if (BIO_lookup(h, p, BIO_LOOKUP_SERVER, AF_UNSPEC, SOCK_STREAM, &res) != 0)
- goto err;
-
- if ((s = BIO_socket(BIO_ADDRINFO_family(res), BIO_ADDRINFO_socktype(res),
- BIO_ADDRINFO_protocol(res), 0)) == INVALID_SOCKET) {
- s = INVALID_SOCKET;
- goto err;
- }
-
- if (!BIO_listen(s, BIO_ADDRINFO_address(res),
- bind_mode ? BIO_SOCK_REUSEADDR : 0)) {
- BIO_closesocket(s);
- s = INVALID_SOCKET;
- }
-
- err:
- BIO_ADDRINFO_free(res);
- OPENSSL_free(h);
- OPENSSL_free(p);
-
- return s;
-}
-
-int BIO_accept(int sock, char **ip_port)
-{
- BIO_ADDR res;
- int ret = -1;
-
- ret = BIO_accept_ex(sock, &res, 0);
- if (ret == (int)INVALID_SOCKET) {
- if (BIO_sock_should_retry(ret)) {
- ret = -2;
- goto end;
- }
- SYSerr(SYS_F_ACCEPT, get_last_socket_error());
- BIOerr(BIO_F_BIO_ACCEPT, BIO_R_ACCEPT_ERROR);
- goto end;
- }
-
- if (ip_port != NULL) {
- char *host = BIO_ADDR_hostname_string(&res, 1);
- char *port = BIO_ADDR_service_string(&res, 1);
- if (host != NULL && port != NULL)
- *ip_port = OPENSSL_zalloc(strlen(host) + strlen(port) + 2);
- else
- *ip_port = NULL;
-
- if (*ip_port == NULL) {
- BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE);
- BIO_closesocket(ret);
- ret = (int)INVALID_SOCKET;
- } else {
- strcpy(*ip_port, host);
- strcat(*ip_port, ":");
- strcat(*ip_port, port);
- }
- OPENSSL_free(host);
- OPENSSL_free(port);
- }
-
- end:
- return ret;
-}
-# endif
-
-int BIO_set_tcp_ndelay(int s, int on)
-{
- int ret = 0;
-# if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
- int opt;
-
-# ifdef SOL_TCP
- opt = SOL_TCP;
-# else
-# ifdef IPPROTO_TCP
- opt = IPPROTO_TCP;
-# endif
-# endif
-
- ret = setsockopt(s, opt, TCP_NODELAY, (char *)&on, sizeof(on));
-# endif
- return (ret == 0);
-}
-
-int BIO_socket_nbio(int s, int mode)
-{
- int ret = -1;
- int l;
-
- l = mode;
-# ifdef FIONBIO
- l = mode;
-
- ret = BIO_socket_ioctl(s, FIONBIO, &l);
-# elif defined(F_GETFL) && defined(F_SETFL) && (defined(O_NONBLOCK) || defined(FNDELAY))
- /* make sure this call always pushes an error level; BIO_socket_ioctl() does so, so we do too. */
-
- l = fcntl(s, F_GETFL, 0);
- if (l == -1) {
- SYSerr(SYS_F_FCNTL, get_last_sys_error());
- ret = -1;
- } else {
-# if defined(O_NONBLOCK)
- l &= ~O_NONBLOCK;
-# else
- l &= ~FNDELAY; /* BSD4.x */
-# endif
- if (mode) {
-# if defined(O_NONBLOCK)
- l |= O_NONBLOCK;
-# else
- l |= FNDELAY; /* BSD4.x */
-# endif
- }
- ret = fcntl(s, F_SETFL, l);
-
- if (ret < 0) {
- SYSerr(SYS_F_FCNTL, get_last_sys_error());
- }
- }
-# else
- /* make sure this call always pushes an error level; BIO_socket_ioctl() does so, so we do too. */
- BIOerr(BIO_F_BIO_SOCKET_NBIO, ERR_R_PASSED_INVALID_ARGUMENT);
-# 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 ((size_t)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
+#ifndef OPENSSL_NO_SOCK
+# define SOCKET_PROTOCOL IPPROTO_TCP
+# ifdef SO_MAXCONN
+# define MAX_LISTEN SO_MAXCONN
+# elif defined(SOMAXCONN)
+# define MAX_LISTEN SOMAXCONN
+# else
+# define MAX_LISTEN 32
+# endif
+# if defined(OPENSSL_SYS_WINDOWS)
+static int wsa_init_done = 0;
+# endif
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+int BIO_get_host_ip(const char *str, unsigned char *ip)
+{
+ BIO_ADDRINFO *res = NULL;
+ int ret = 0;
+
+ if (BIO_sock_init() != 1)
+ return 0; /* don't generate another error code here */
+
+ if (BIO_lookup(str, NULL, BIO_LOOKUP_CLIENT, AF_INET, SOCK_STREAM, &res)) {
+ size_t l;
+
+ if (BIO_ADDRINFO_family(res) != AF_INET) {
+ BIOerr(BIO_F_BIO_GET_HOST_IP,
+ BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
+ } else if (BIO_ADDR_rawaddress(BIO_ADDRINFO_address(res), NULL, &l)) {
+ /*
+ * Because only AF_INET addresses will reach this far, we can assert
+ * that l should be 4
+ */
+ if (ossl_assert(l == 4))
+ ret = BIO_ADDR_rawaddress(BIO_ADDRINFO_address(res), ip, &l);
+ }
+ BIO_ADDRINFO_free(res);
+ } else {
+ ERR_add_error_data(2, "host=", str);
+ }
+
+ return ret;
+}
+
+int BIO_get_port(const char *str, unsigned short *port_ptr)
+{
+ BIO_ADDRINFO *res = NULL;
+ int ret = 0;
+
+ if (str == NULL) {
+ BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_DEFINED);
+ return 0;
+ }
+
+ if (BIO_sock_init() != 1)
+ return 0; /* don't generate another error code here */
+
+ if (BIO_lookup(NULL, str, BIO_LOOKUP_CLIENT, AF_INET, SOCK_STREAM, &res)) {
+ if (BIO_ADDRINFO_family(res) != AF_INET) {
+ BIOerr(BIO_F_BIO_GET_PORT,
+ BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET);
+ } else {
+ *port_ptr = ntohs(BIO_ADDR_rawport(BIO_ADDRINFO_address(res)));
+ ret = 1;
+ }
+ BIO_ADDRINFO_free(res);
+ } else {
+ ERR_add_error_data(2, "host=", str);
+ }
+
+ return ret;
+}
+# endif
+
+int BIO_sock_error(int sock)
+{
+ int j = 0, i;
+ socklen_t size = sizeof(j);
+
+ /*
+ * Note: under Windows the third parameter is of type (char *) whereas
+ * under other systems it is (void *) if you don't have a cast it will
+ * choke the compiler: if you do have a cast then you can either go for
+ * (char *) or (void *).
+ */
+ i = getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)&j, &size);
+ if (i < 0)
+ return get_last_socket_error();
+ else
+ return j;
+}
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+struct hostent *BIO_gethostbyname(const char *name)
+{
+ /*
+ * Caching gethostbyname() results forever is wrong, so we have to let
+ * the true gethostbyname() worry about this
+ */
+ return gethostbyname(name);
+}
+# endif
+
+int BIO_sock_init(void)
+{
+# ifdef OPENSSL_SYS_WINDOWS
+ static struct WSAData wsa_state;
+
+ if (!wsa_init_done) {
+ int err;
+
+ wsa_init_done = 1;
+ memset(&wsa_state, 0, sizeof(wsa_state));
+ /*
+ * Not making wsa_state available to the rest of the code is formally
+ * wrong. But the structures we use are [believed to be] invariable
+ * among Winsock DLLs, while API availability is [expected to be]
+ * probed at run-time with DSO_global_lookup.
+ */
+ if (WSAStartup(0x0202, &wsa_state) != 0) {
+ err = WSAGetLastError();
+ SYSerr(SYS_F_WSASTARTUP, err);
+ BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP);
+ return -1;
+ }
+ }
+# endif /* OPENSSL_SYS_WINDOWS */
+# ifdef WATT32
+ extern int _watt_do_exit;
+ _watt_do_exit = 0; /* don't make sock_init() call exit() */
+ if (sock_init())
+ return -1;
+# endif
+
+ return 1;
+}
+
+void bio_sock_cleanup_int(void)
+{
+# ifdef OPENSSL_SYS_WINDOWS
+ if (wsa_init_done) {
+ wsa_init_done = 0;
+ WSACleanup();
+ }
+# endif
+}
+
+int BIO_socket_ioctl(int fd, long type, void *arg)
+{
+ int i;
+
+# ifdef __DJGPP__
+ i = ioctlsocket(fd, type, (char *)arg);
+# else
+# if defined(OPENSSL_SYS_VMS)
+ /*-
+ * 2011-02-18 SMS.
+ * VMS ioctl() can't tolerate a 64-bit "void *arg", but we
+ * observe that all the consumers pass in an "unsigned long *",
+ * so we arrange a local copy with a short pointer, and use
+ * that, instead.
+ */
+# if __INITIAL_POINTER_SIZE == 64
+# define ARG arg_32p
+# pragma pointer_size save
+# pragma pointer_size 32
+ unsigned long arg_32;
+ unsigned long *arg_32p;
+# pragma pointer_size restore
+ arg_32p = &arg_32;
+ arg_32 = *((unsigned long *)arg);
+# else /* __INITIAL_POINTER_SIZE == 64 */
+# define ARG arg
+# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+# else /* defined(OPENSSL_SYS_VMS) */
+# define ARG arg
+# endif /* defined(OPENSSL_SYS_VMS) [else] */
+
+ i = ioctlsocket(fd, type, ARG);
+# endif /* __DJGPP__ */
+ if (i < 0)
+ SYSerr(SYS_F_IOCTLSOCKET, get_last_socket_error());
+ return i;
+}
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+int BIO_get_accept_socket(char *host, int bind_mode)
+{
+ int s = INVALID_SOCKET;
+ char *h = NULL, *p = NULL;
+ BIO_ADDRINFO *res = NULL;
+
+ if (!BIO_parse_hostserv(host, &h, &p, BIO_PARSE_PRIO_SERV))
+ return INVALID_SOCKET;
+
+ if (BIO_sock_init() != 1)
+ return INVALID_SOCKET;
+
+ if (BIO_lookup(h, p, BIO_LOOKUP_SERVER, AF_UNSPEC, SOCK_STREAM, &res) != 0)
+ goto err;
+
+ if ((s = BIO_socket(BIO_ADDRINFO_family(res), BIO_ADDRINFO_socktype(res),
+ BIO_ADDRINFO_protocol(res), 0)) == INVALID_SOCKET) {
+ s = INVALID_SOCKET;
+ goto err;
+ }
+
+ if (!BIO_listen(s, BIO_ADDRINFO_address(res),
+ bind_mode ? BIO_SOCK_REUSEADDR : 0)) {
+ BIO_closesocket(s);
+ s = INVALID_SOCKET;
+ }
+
+ err:
+ BIO_ADDRINFO_free(res);
+ OPENSSL_free(h);
+ OPENSSL_free(p);
+
+ return s;
+}
+
+int BIO_accept(int sock, char **ip_port)
+{
+ BIO_ADDR res;
+ int ret = -1;
+
+ ret = BIO_accept_ex(sock, &res, 0);
+ if (ret == (int)INVALID_SOCKET) {
+ if (BIO_sock_should_retry(ret)) {
+ ret = -2;
+ goto end;
+ }
+ SYSerr(SYS_F_ACCEPT, get_last_socket_error());
+ BIOerr(BIO_F_BIO_ACCEPT, BIO_R_ACCEPT_ERROR);
+ goto end;
+ }
+
+ if (ip_port != NULL) {
+ char *host = BIO_ADDR_hostname_string(&res, 1);
+ char *port = BIO_ADDR_service_string(&res, 1);
+ if (host != NULL && port != NULL)
+ *ip_port = OPENSSL_zalloc(strlen(host) + strlen(port) + 2);
+ else
+ *ip_port = NULL;
+
+ if (*ip_port == NULL) {
+ BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE);
+ BIO_closesocket(ret);
+ ret = (int)INVALID_SOCKET;
+ } else {
+ strcpy(*ip_port, host);
+ strcat(*ip_port, ":");
+ strcat(*ip_port, port);
+ }
+ OPENSSL_free(host);
+ OPENSSL_free(port);
+ }
+
+ end:
+ return ret;
+}
+# endif
+
+int BIO_set_tcp_ndelay(int s, int on)
+{
+ int ret = 0;
+# if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
+ int opt;
+
+# ifdef SOL_TCP
+ opt = SOL_TCP;
+# else
+# ifdef IPPROTO_TCP
+ opt = IPPROTO_TCP;
+# endif
+# endif
+
+ ret = setsockopt(s, opt, TCP_NODELAY, (char *)&on, sizeof(on));
+# endif
+ return (ret == 0);
+}
+
+int BIO_socket_nbio(int s, int mode)
+{
+ int ret = -1;
+ int l;
+
+ l = mode;
+# ifdef FIONBIO
+ l = mode;
+
+ ret = BIO_socket_ioctl(s, FIONBIO, &l);
+# elif defined(F_GETFL) && defined(F_SETFL) && (defined(O_NONBLOCK) || defined(FNDELAY))
+ /* make sure this call always pushes an error level; BIO_socket_ioctl() does so, so we do too. */
+
+ l = fcntl(s, F_GETFL, 0);
+ if (l == -1) {
+ SYSerr(SYS_F_FCNTL, get_last_sys_error());
+ ret = -1;
+ } else {
+# if defined(O_NONBLOCK)
+ l &= ~O_NONBLOCK;
+# else
+ l &= ~FNDELAY; /* BSD4.x */
+# endif
+ if (mode) {
+# if defined(O_NONBLOCK)
+ l |= O_NONBLOCK;
+# else
+ l |= FNDELAY; /* BSD4.x */
+# endif
+ }
+ ret = fcntl(s, F_SETFL, l);
+
+ if (ret < 0) {
+ SYSerr(SYS_F_FCNTL, get_last_sys_error());
+ }
+ }
+# else
+ /* make sure this call always pushes an error level; BIO_socket_ioctl() does so, so we do too. */
+ BIOerr(BIO_F_BIO_SOCKET_NBIO, ERR_R_PASSED_INVALID_ARGUMENT);
+# 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 ((size_t)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
diff --git a/contrib/libs/openssl/crypto/bio/b_sock2.c b/contrib/libs/openssl/crypto/bio/b_sock2.c
index f5f9620809..104ff31b0d 100644
--- a/contrib/libs/openssl/crypto/bio/b_sock2.c
+++ b/contrib/libs/openssl/crypto/bio/b_sock2.c
@@ -1,318 +1,318 @@
-/*
+/*
* Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
#include "bio_local.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 successful.
- *
- * 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)
-{
- const 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,
- (const void *)&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,
- (const void *)&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) {
- if (!BIO_sock_should_retry(-1)) {
- SYSerr(SYS_F_CONNECT, get_last_socket_error());
- BIOerr(BIO_F_BIO_CONNECT, BIO_R_CONNECT_ERROR);
- }
- return 0;
- }
- return 1;
-}
-
-/*-
- * BIO_bind - bind socket to address
- * @sock: the socket to set
- * @addr: local address to bind to
- * @options: BIO socket options
- *
- * Binds to the address using the given socket and options.
- *
- * Options can be a combination of the following:
- * - BIO_SOCK_REUSEADDR: Try to reuse the address and port combination
- * for a recently closed port.
- *
- * 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_bind(int sock, const BIO_ADDR *addr, int options)
-{
-# ifndef OPENSSL_SYS_WINDOWS
- int on = 1;
-# endif
-
- if (sock == -1) {
- BIOerr(BIO_F_BIO_BIND, BIO_R_INVALID_SOCKET);
- 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,
- (const void *)&on, sizeof(on)) != 0) {
- SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
- BIOerr(BIO_F_BIO_BIND, BIO_R_UNABLE_TO_REUSEADDR);
- 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_BIND, BIO_R_UNABLE_TO_BIND_SOCKET);
- 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
- * successful.
- *
- * 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,
- (void *)&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;
-
- if (options & BIO_SOCK_KEEPALIVE) {
- if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
- (const void *)&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,
- (const void *)&on, sizeof(on)) != 0) {
- SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
- BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_NODELAY);
- return 0;
- }
- }
-
+
+#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 successful.
+ *
+ * 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)
+{
+ const 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,
+ (const void *)&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,
+ (const void *)&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) {
+ if (!BIO_sock_should_retry(-1)) {
+ SYSerr(SYS_F_CONNECT, get_last_socket_error());
+ BIOerr(BIO_F_BIO_CONNECT, BIO_R_CONNECT_ERROR);
+ }
+ return 0;
+ }
+ return 1;
+}
+
+/*-
+ * BIO_bind - bind socket to address
+ * @sock: the socket to set
+ * @addr: local address to bind to
+ * @options: BIO socket options
+ *
+ * Binds to the address using the given socket and options.
+ *
+ * Options can be a combination of the following:
+ * - BIO_SOCK_REUSEADDR: Try to reuse the address and port combination
+ * for a recently closed port.
+ *
+ * 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_bind(int sock, const BIO_ADDR *addr, int options)
+{
+# ifndef OPENSSL_SYS_WINDOWS
+ int on = 1;
+# endif
+
+ if (sock == -1) {
+ BIOerr(BIO_F_BIO_BIND, BIO_R_INVALID_SOCKET);
+ 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,
+ (const void *)&on, sizeof(on)) != 0) {
+ SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
+ BIOerr(BIO_F_BIO_BIND, BIO_R_UNABLE_TO_REUSEADDR);
+ 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_BIND, BIO_R_UNABLE_TO_BIND_SOCKET);
+ 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
+ * successful.
+ *
+ * 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,
+ (void *)&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;
+
+ if (options & BIO_SOCK_KEEPALIVE) {
+ if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
+ (const void *)&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,
+ (const void *)&on, sizeof(on)) != 0) {
+ SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
+ BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_NODELAY);
+ return 0;
+ }
+ }
+
/* On OpenBSD it is always ipv6 only with ipv6 sockets thus read-only */
# if defined(IPV6_V6ONLY) && !defined(__OpenBSD__)
- if (BIO_ADDR_family(addr) == AF_INET6) {
- /*
- * Note: Windows default of IPV6_V6ONLY is ON, and Linux is OFF.
- * Therefore we always have to use setsockopt here.
- */
- on = options & BIO_SOCK_V6_ONLY ? 1 : 0;
- if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
- (const void *)&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 (!BIO_bind(sock, addr, options))
- 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;
- BIO_ADDR locaddr;
- BIO_ADDR *addr = addr_ == NULL ? &locaddr : addr_;
-
- len = sizeof(*addr);
- accepted_sock = accept(accept_sock,
- BIO_ADDR_sockaddr_noconst(addr), &len);
- if (accepted_sock == -1) {
- if (!BIO_sock_should_retry(accepted_sock)) {
- 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)) {
- closesocket(accepted_sock);
- 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
+ if (BIO_ADDR_family(addr) == AF_INET6) {
+ /*
+ * Note: Windows default of IPV6_V6ONLY is ON, and Linux is OFF.
+ * Therefore we always have to use setsockopt here.
+ */
+ on = options & BIO_SOCK_V6_ONLY ? 1 : 0;
+ if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
+ (const void *)&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 (!BIO_bind(sock, addr, options))
+ 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;
+ BIO_ADDR locaddr;
+ BIO_ADDR *addr = addr_ == NULL ? &locaddr : addr_;
+
+ len = sizeof(*addr);
+ accepted_sock = accept(accept_sock,
+ BIO_ADDR_sockaddr_noconst(addr), &len);
+ if (accepted_sock == -1) {
+ if (!BIO_sock_should_retry(accepted_sock)) {
+ 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)) {
+ closesocket(accepted_sock);
+ 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
diff --git a/contrib/libs/openssl/crypto/bio/bf_buff.c b/contrib/libs/openssl/crypto/bio/bf_buff.c
index bdc3fddecc..51ae1f918d 100644
--- a/contrib/libs/openssl/crypto/bio/bf_buff.c
+++ b/contrib/libs/openssl/crypto/bio/bf_buff.c
@@ -1,475 +1,475 @@
-/*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include <errno.h>
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <errno.h>
#include "bio_local.h"
-#include "internal/cryptlib.h"
-
-static int buffer_write(BIO *h, const char *buf, int num);
-static int buffer_read(BIO *h, char *buf, int size);
-static int buffer_puts(BIO *h, const char *str);
-static int buffer_gets(BIO *h, char *str, int size);
-static long buffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-static int buffer_new(BIO *h);
-static int buffer_free(BIO *data);
-static long buffer_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
-#define DEFAULT_BUFFER_SIZE 4096
-
-static const BIO_METHOD methods_buffer = {
- BIO_TYPE_BUFFER,
- "buffer",
- /* TODO: Convert to new style write function */
- bwrite_conv,
- buffer_write,
- /* TODO: Convert to new style read function */
- bread_conv,
- buffer_read,
- buffer_puts,
- buffer_gets,
- buffer_ctrl,
- buffer_new,
- buffer_free,
- buffer_callback_ctrl,
-};
-
-const BIO_METHOD *BIO_f_buffer(void)
-{
- return &methods_buffer;
-}
-
-static int buffer_new(BIO *bi)
-{
- BIO_F_BUFFER_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
-
- if (ctx == NULL)
- return 0;
- ctx->ibuf_size = DEFAULT_BUFFER_SIZE;
- ctx->ibuf = OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
- if (ctx->ibuf == NULL) {
- OPENSSL_free(ctx);
- return 0;
- }
- ctx->obuf_size = DEFAULT_BUFFER_SIZE;
- ctx->obuf = OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
- if (ctx->obuf == NULL) {
- OPENSSL_free(ctx->ibuf);
- OPENSSL_free(ctx);
- return 0;
- }
-
- bi->init = 1;
- bi->ptr = (char *)ctx;
- bi->flags = 0;
- return 1;
-}
-
-static int buffer_free(BIO *a)
-{
- BIO_F_BUFFER_CTX *b;
-
- if (a == NULL)
- return 0;
- b = (BIO_F_BUFFER_CTX *)a->ptr;
- OPENSSL_free(b->ibuf);
- OPENSSL_free(b->obuf);
- OPENSSL_free(a->ptr);
- a->ptr = NULL;
- a->init = 0;
- a->flags = 0;
- return 1;
-}
-
-static int buffer_read(BIO *b, char *out, int outl)
-{
- int i, num = 0;
- BIO_F_BUFFER_CTX *ctx;
-
- if (out == NULL)
- return 0;
- ctx = (BIO_F_BUFFER_CTX *)b->ptr;
-
- if ((ctx == NULL) || (b->next_bio == NULL))
- return 0;
- num = 0;
- BIO_clear_retry_flags(b);
-
- start:
- i = ctx->ibuf_len;
- /* If there is stuff left over, grab it */
- if (i != 0) {
- if (i > outl)
- i = outl;
- memcpy(out, &(ctx->ibuf[ctx->ibuf_off]), i);
- ctx->ibuf_off += i;
- ctx->ibuf_len -= i;
- num += i;
- if (outl == i)
- return num;
- outl -= i;
- out += i;
- }
-
- /*
- * We may have done a partial read. try to do more. We have nothing in
- * the buffer. If we get an error and have read some data, just return it
- * and let them retry to get the error again. copy direct to parent
- * address space
- */
- if (outl > ctx->ibuf_size) {
- for (;;) {
- i = BIO_read(b->next_bio, out, outl);
- if (i <= 0) {
- BIO_copy_next_retry(b);
- if (i < 0)
- return ((num > 0) ? num : i);
- if (i == 0)
- return num;
- }
- num += i;
- if (outl == i)
- return num;
- out += i;
- outl -= i;
- }
- }
- /* else */
-
- /* we are going to be doing some buffering */
- i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size);
- if (i <= 0) {
- BIO_copy_next_retry(b);
- if (i < 0)
- return ((num > 0) ? num : i);
- if (i == 0)
- return num;
- }
- ctx->ibuf_off = 0;
- ctx->ibuf_len = i;
-
- /* Lets re-read using ourselves :-) */
- goto start;
-}
-
-static int buffer_write(BIO *b, const char *in, int inl)
-{
- int i, num = 0;
- BIO_F_BUFFER_CTX *ctx;
-
- if ((in == NULL) || (inl <= 0))
- return 0;
- ctx = (BIO_F_BUFFER_CTX *)b->ptr;
- if ((ctx == NULL) || (b->next_bio == NULL))
- return 0;
-
- BIO_clear_retry_flags(b);
- start:
- i = ctx->obuf_size - (ctx->obuf_len + ctx->obuf_off);
- /* add to buffer and return */
- if (i >= inl) {
- memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, inl);
- ctx->obuf_len += inl;
- return (num + inl);
- }
- /* else */
- /* stuff already in buffer, so add to it first, then flush */
- if (ctx->obuf_len != 0) {
- if (i > 0) { /* lets fill it up if we can */
- memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, i);
- in += i;
- inl -= i;
- num += i;
- ctx->obuf_len += i;
- }
- /* we now have a full buffer needing flushing */
- for (;;) {
- i = BIO_write(b->next_bio, &(ctx->obuf[ctx->obuf_off]),
- ctx->obuf_len);
- if (i <= 0) {
- BIO_copy_next_retry(b);
-
- if (i < 0)
- return ((num > 0) ? num : i);
- if (i == 0)
- return num;
- }
- ctx->obuf_off += i;
- ctx->obuf_len -= i;
- if (ctx->obuf_len == 0)
- break;
- }
- }
- /*
- * we only get here if the buffer has been flushed and we still have
- * stuff to write
- */
- ctx->obuf_off = 0;
-
- /* we now have inl bytes to write */
- while (inl >= ctx->obuf_size) {
- i = BIO_write(b->next_bio, in, inl);
- if (i <= 0) {
- BIO_copy_next_retry(b);
- if (i < 0)
- return ((num > 0) ? num : i);
- if (i == 0)
- return num;
- }
- num += i;
- in += i;
- inl -= i;
- if (inl == 0)
- return num;
- }
-
- /*
- * copy the rest into the buffer since we have only a small amount left
- */
- goto start;
-}
-
-static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
-{
- BIO *dbio;
- BIO_F_BUFFER_CTX *ctx;
- long ret = 1;
- char *p1, *p2;
- int r, i, *ip;
- int ibs, obs;
-
- ctx = (BIO_F_BUFFER_CTX *)b->ptr;
-
- switch (cmd) {
- case BIO_CTRL_RESET:
- ctx->ibuf_off = 0;
- ctx->ibuf_len = 0;
- ctx->obuf_off = 0;
- ctx->obuf_len = 0;
- if (b->next_bio == NULL)
- return 0;
- ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
- break;
- case BIO_CTRL_EOF:
- if (ctx->ibuf_len > 0)
- return 0;
- ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
- break;
- case BIO_CTRL_INFO:
- ret = (long)ctx->obuf_len;
- break;
- case BIO_C_GET_BUFF_NUM_LINES:
- ret = 0;
- p1 = ctx->ibuf;
- for (i = 0; i < ctx->ibuf_len; i++) {
- if (p1[ctx->ibuf_off + i] == '\n')
- ret++;
- }
- break;
- case BIO_CTRL_WPENDING:
- ret = (long)ctx->obuf_len;
- if (ret == 0) {
- if (b->next_bio == NULL)
- return 0;
- ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
- }
- break;
- case BIO_CTRL_PENDING:
- ret = (long)ctx->ibuf_len;
- if (ret == 0) {
- if (b->next_bio == NULL)
- return 0;
- ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
- }
- break;
- case BIO_C_SET_BUFF_READ_DATA:
- if (num > ctx->ibuf_size) {
- p1 = OPENSSL_malloc((int)num);
- if (p1 == NULL)
- goto malloc_error;
- OPENSSL_free(ctx->ibuf);
- ctx->ibuf = p1;
- }
- ctx->ibuf_off = 0;
- ctx->ibuf_len = (int)num;
- memcpy(ctx->ibuf, ptr, (int)num);
- ret = 1;
- break;
- case BIO_C_SET_BUFF_SIZE:
- if (ptr != NULL) {
- ip = (int *)ptr;
- if (*ip == 0) {
- ibs = (int)num;
- obs = ctx->obuf_size;
- } else { /* if (*ip == 1) */
-
- ibs = ctx->ibuf_size;
- obs = (int)num;
- }
- } else {
- ibs = (int)num;
- obs = (int)num;
- }
- p1 = ctx->ibuf;
- p2 = ctx->obuf;
- if ((ibs > DEFAULT_BUFFER_SIZE) && (ibs != ctx->ibuf_size)) {
- p1 = OPENSSL_malloc((int)num);
- if (p1 == NULL)
- goto malloc_error;
- }
- if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size)) {
- p2 = OPENSSL_malloc((int)num);
- if (p2 == NULL) {
- if (p1 != ctx->ibuf)
- OPENSSL_free(p1);
- goto malloc_error;
- }
- }
- if (ctx->ibuf != p1) {
- OPENSSL_free(ctx->ibuf);
- ctx->ibuf = p1;
- ctx->ibuf_off = 0;
- ctx->ibuf_len = 0;
- ctx->ibuf_size = ibs;
- }
- if (ctx->obuf != p2) {
- OPENSSL_free(ctx->obuf);
- ctx->obuf = p2;
- ctx->obuf_off = 0;
- ctx->obuf_len = 0;
- ctx->obuf_size = obs;
- }
- break;
- case BIO_C_DO_STATE_MACHINE:
- if (b->next_bio == NULL)
- return 0;
- BIO_clear_retry_flags(b);
- ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
- BIO_copy_next_retry(b);
- break;
-
- case BIO_CTRL_FLUSH:
- if (b->next_bio == NULL)
- return 0;
- if (ctx->obuf_len <= 0) {
- ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
- break;
- }
-
- for (;;) {
- BIO_clear_retry_flags(b);
- if (ctx->obuf_len > 0) {
- r = BIO_write(b->next_bio,
- &(ctx->obuf[ctx->obuf_off]), ctx->obuf_len);
- BIO_copy_next_retry(b);
- if (r <= 0)
- return (long)r;
- ctx->obuf_off += r;
- ctx->obuf_len -= r;
- } else {
- ctx->obuf_len = 0;
- ctx->obuf_off = 0;
- break;
- }
- }
- ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
- break;
- case BIO_CTRL_DUP:
- dbio = (BIO *)ptr;
- if (!BIO_set_read_buffer_size(dbio, ctx->ibuf_size) ||
- !BIO_set_write_buffer_size(dbio, ctx->obuf_size))
- ret = 0;
- break;
- case BIO_CTRL_PEEK:
- /* Ensure there's stuff in the input buffer */
- {
- char fake_buf[1];
- (void)buffer_read(b, fake_buf, 0);
- }
- if (num > ctx->ibuf_len)
- num = ctx->ibuf_len;
- memcpy(ptr, &(ctx->ibuf[ctx->ibuf_off]), num);
- ret = num;
- break;
- default:
- if (b->next_bio == NULL)
- return 0;
- ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
- break;
- }
- return ret;
- malloc_error:
- BIOerr(BIO_F_BUFFER_CTRL, ERR_R_MALLOC_FAILURE);
- return 0;
-}
-
-static long buffer_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
-{
- long ret = 1;
-
- if (b->next_bio == NULL)
- return 0;
- switch (cmd) {
- default:
- ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
- break;
- }
- return ret;
-}
-
-static int buffer_gets(BIO *b, char *buf, int size)
-{
- BIO_F_BUFFER_CTX *ctx;
- int num = 0, i, flag;
- char *p;
-
- ctx = (BIO_F_BUFFER_CTX *)b->ptr;
- size--; /* reserve space for a '\0' */
- BIO_clear_retry_flags(b);
-
- for (;;) {
- if (ctx->ibuf_len > 0) {
- p = &(ctx->ibuf[ctx->ibuf_off]);
- flag = 0;
- for (i = 0; (i < ctx->ibuf_len) && (i < size); i++) {
- *(buf++) = p[i];
- if (p[i] == '\n') {
- flag = 1;
- i++;
- break;
- }
- }
- num += i;
- size -= i;
- ctx->ibuf_len -= i;
- ctx->ibuf_off += i;
- if (flag || size == 0) {
- *buf = '\0';
- return num;
- }
- } else { /* read another chunk */
-
- i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size);
- if (i <= 0) {
- BIO_copy_next_retry(b);
- *buf = '\0';
- if (i < 0)
- return ((num > 0) ? num : i);
- if (i == 0)
- return num;
- }
- ctx->ibuf_len = i;
- ctx->ibuf_off = 0;
- }
- }
-}
-
-static int buffer_puts(BIO *b, const char *str)
-{
- return buffer_write(b, str, strlen(str));
-}
+#include "internal/cryptlib.h"
+
+static int buffer_write(BIO *h, const char *buf, int num);
+static int buffer_read(BIO *h, char *buf, int size);
+static int buffer_puts(BIO *h, const char *str);
+static int buffer_gets(BIO *h, char *str, int size);
+static long buffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int buffer_new(BIO *h);
+static int buffer_free(BIO *data);
+static long buffer_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
+#define DEFAULT_BUFFER_SIZE 4096
+
+static const BIO_METHOD methods_buffer = {
+ BIO_TYPE_BUFFER,
+ "buffer",
+ /* TODO: Convert to new style write function */
+ bwrite_conv,
+ buffer_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
+ buffer_read,
+ buffer_puts,
+ buffer_gets,
+ buffer_ctrl,
+ buffer_new,
+ buffer_free,
+ buffer_callback_ctrl,
+};
+
+const BIO_METHOD *BIO_f_buffer(void)
+{
+ return &methods_buffer;
+}
+
+static int buffer_new(BIO *bi)
+{
+ BIO_F_BUFFER_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+ if (ctx == NULL)
+ return 0;
+ ctx->ibuf_size = DEFAULT_BUFFER_SIZE;
+ ctx->ibuf = OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
+ if (ctx->ibuf == NULL) {
+ OPENSSL_free(ctx);
+ return 0;
+ }
+ ctx->obuf_size = DEFAULT_BUFFER_SIZE;
+ ctx->obuf = OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
+ if (ctx->obuf == NULL) {
+ OPENSSL_free(ctx->ibuf);
+ OPENSSL_free(ctx);
+ return 0;
+ }
+
+ bi->init = 1;
+ bi->ptr = (char *)ctx;
+ bi->flags = 0;
+ return 1;
+}
+
+static int buffer_free(BIO *a)
+{
+ BIO_F_BUFFER_CTX *b;
+
+ if (a == NULL)
+ return 0;
+ b = (BIO_F_BUFFER_CTX *)a->ptr;
+ OPENSSL_free(b->ibuf);
+ OPENSSL_free(b->obuf);
+ OPENSSL_free(a->ptr);
+ a->ptr = NULL;
+ a->init = 0;
+ a->flags = 0;
+ return 1;
+}
+
+static int buffer_read(BIO *b, char *out, int outl)
+{
+ int i, num = 0;
+ BIO_F_BUFFER_CTX *ctx;
+
+ if (out == NULL)
+ return 0;
+ ctx = (BIO_F_BUFFER_CTX *)b->ptr;
+
+ if ((ctx == NULL) || (b->next_bio == NULL))
+ return 0;
+ num = 0;
+ BIO_clear_retry_flags(b);
+
+ start:
+ i = ctx->ibuf_len;
+ /* If there is stuff left over, grab it */
+ if (i != 0) {
+ if (i > outl)
+ i = outl;
+ memcpy(out, &(ctx->ibuf[ctx->ibuf_off]), i);
+ ctx->ibuf_off += i;
+ ctx->ibuf_len -= i;
+ num += i;
+ if (outl == i)
+ return num;
+ outl -= i;
+ out += i;
+ }
+
+ /*
+ * We may have done a partial read. try to do more. We have nothing in
+ * the buffer. If we get an error and have read some data, just return it
+ * and let them retry to get the error again. copy direct to parent
+ * address space
+ */
+ if (outl > ctx->ibuf_size) {
+ for (;;) {
+ i = BIO_read(b->next_bio, out, outl);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ if (i < 0)
+ return ((num > 0) ? num : i);
+ if (i == 0)
+ return num;
+ }
+ num += i;
+ if (outl == i)
+ return num;
+ out += i;
+ outl -= i;
+ }
+ }
+ /* else */
+
+ /* we are going to be doing some buffering */
+ i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ if (i < 0)
+ return ((num > 0) ? num : i);
+ if (i == 0)
+ return num;
+ }
+ ctx->ibuf_off = 0;
+ ctx->ibuf_len = i;
+
+ /* Lets re-read using ourselves :-) */
+ goto start;
+}
+
+static int buffer_write(BIO *b, const char *in, int inl)
+{
+ int i, num = 0;
+ BIO_F_BUFFER_CTX *ctx;
+
+ if ((in == NULL) || (inl <= 0))
+ return 0;
+ ctx = (BIO_F_BUFFER_CTX *)b->ptr;
+ if ((ctx == NULL) || (b->next_bio == NULL))
+ return 0;
+
+ BIO_clear_retry_flags(b);
+ start:
+ i = ctx->obuf_size - (ctx->obuf_len + ctx->obuf_off);
+ /* add to buffer and return */
+ if (i >= inl) {
+ memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, inl);
+ ctx->obuf_len += inl;
+ return (num + inl);
+ }
+ /* else */
+ /* stuff already in buffer, so add to it first, then flush */
+ if (ctx->obuf_len != 0) {
+ if (i > 0) { /* lets fill it up if we can */
+ memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, i);
+ in += i;
+ inl -= i;
+ num += i;
+ ctx->obuf_len += i;
+ }
+ /* we now have a full buffer needing flushing */
+ for (;;) {
+ i = BIO_write(b->next_bio, &(ctx->obuf[ctx->obuf_off]),
+ ctx->obuf_len);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+
+ if (i < 0)
+ return ((num > 0) ? num : i);
+ if (i == 0)
+ return num;
+ }
+ ctx->obuf_off += i;
+ ctx->obuf_len -= i;
+ if (ctx->obuf_len == 0)
+ break;
+ }
+ }
+ /*
+ * we only get here if the buffer has been flushed and we still have
+ * stuff to write
+ */
+ ctx->obuf_off = 0;
+
+ /* we now have inl bytes to write */
+ while (inl >= ctx->obuf_size) {
+ i = BIO_write(b->next_bio, in, inl);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ if (i < 0)
+ return ((num > 0) ? num : i);
+ if (i == 0)
+ return num;
+ }
+ num += i;
+ in += i;
+ inl -= i;
+ if (inl == 0)
+ return num;
+ }
+
+ /*
+ * copy the rest into the buffer since we have only a small amount left
+ */
+ goto start;
+}
+
+static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ BIO *dbio;
+ BIO_F_BUFFER_CTX *ctx;
+ long ret = 1;
+ char *p1, *p2;
+ int r, i, *ip;
+ int ibs, obs;
+
+ ctx = (BIO_F_BUFFER_CTX *)b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ ctx->ibuf_off = 0;
+ ctx->ibuf_len = 0;
+ ctx->obuf_off = 0;
+ ctx->obuf_len = 0;
+ if (b->next_bio == NULL)
+ return 0;
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_EOF:
+ if (ctx->ibuf_len > 0)
+ return 0;
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_INFO:
+ ret = (long)ctx->obuf_len;
+ break;
+ case BIO_C_GET_BUFF_NUM_LINES:
+ ret = 0;
+ p1 = ctx->ibuf;
+ for (i = 0; i < ctx->ibuf_len; i++) {
+ if (p1[ctx->ibuf_off + i] == '\n')
+ ret++;
+ }
+ break;
+ case BIO_CTRL_WPENDING:
+ ret = (long)ctx->obuf_len;
+ if (ret == 0) {
+ if (b->next_bio == NULL)
+ return 0;
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ }
+ break;
+ case BIO_CTRL_PENDING:
+ ret = (long)ctx->ibuf_len;
+ if (ret == 0) {
+ if (b->next_bio == NULL)
+ return 0;
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ }
+ break;
+ case BIO_C_SET_BUFF_READ_DATA:
+ if (num > ctx->ibuf_size) {
+ p1 = OPENSSL_malloc((int)num);
+ if (p1 == NULL)
+ goto malloc_error;
+ OPENSSL_free(ctx->ibuf);
+ ctx->ibuf = p1;
+ }
+ ctx->ibuf_off = 0;
+ ctx->ibuf_len = (int)num;
+ memcpy(ctx->ibuf, ptr, (int)num);
+ ret = 1;
+ break;
+ case BIO_C_SET_BUFF_SIZE:
+ if (ptr != NULL) {
+ ip = (int *)ptr;
+ if (*ip == 0) {
+ ibs = (int)num;
+ obs = ctx->obuf_size;
+ } else { /* if (*ip == 1) */
+
+ ibs = ctx->ibuf_size;
+ obs = (int)num;
+ }
+ } else {
+ ibs = (int)num;
+ obs = (int)num;
+ }
+ p1 = ctx->ibuf;
+ p2 = ctx->obuf;
+ if ((ibs > DEFAULT_BUFFER_SIZE) && (ibs != ctx->ibuf_size)) {
+ p1 = OPENSSL_malloc((int)num);
+ if (p1 == NULL)
+ goto malloc_error;
+ }
+ if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size)) {
+ p2 = OPENSSL_malloc((int)num);
+ if (p2 == NULL) {
+ if (p1 != ctx->ibuf)
+ OPENSSL_free(p1);
+ goto malloc_error;
+ }
+ }
+ if (ctx->ibuf != p1) {
+ OPENSSL_free(ctx->ibuf);
+ ctx->ibuf = p1;
+ ctx->ibuf_off = 0;
+ ctx->ibuf_len = 0;
+ ctx->ibuf_size = ibs;
+ }
+ if (ctx->obuf != p2) {
+ OPENSSL_free(ctx->obuf);
+ ctx->obuf = p2;
+ ctx->obuf_off = 0;
+ ctx->obuf_len = 0;
+ ctx->obuf_size = obs;
+ }
+ break;
+ case BIO_C_DO_STATE_MACHINE:
+ if (b->next_bio == NULL)
+ return 0;
+ BIO_clear_retry_flags(b);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ BIO_copy_next_retry(b);
+ break;
+
+ case BIO_CTRL_FLUSH:
+ if (b->next_bio == NULL)
+ return 0;
+ if (ctx->obuf_len <= 0) {
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ }
+
+ for (;;) {
+ BIO_clear_retry_flags(b);
+ if (ctx->obuf_len > 0) {
+ r = BIO_write(b->next_bio,
+ &(ctx->obuf[ctx->obuf_off]), ctx->obuf_len);
+ BIO_copy_next_retry(b);
+ if (r <= 0)
+ return (long)r;
+ ctx->obuf_off += r;
+ ctx->obuf_len -= r;
+ } else {
+ ctx->obuf_len = 0;
+ ctx->obuf_off = 0;
+ break;
+ }
+ }
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_DUP:
+ dbio = (BIO *)ptr;
+ if (!BIO_set_read_buffer_size(dbio, ctx->ibuf_size) ||
+ !BIO_set_write_buffer_size(dbio, ctx->obuf_size))
+ ret = 0;
+ break;
+ case BIO_CTRL_PEEK:
+ /* Ensure there's stuff in the input buffer */
+ {
+ char fake_buf[1];
+ (void)buffer_read(b, fake_buf, 0);
+ }
+ if (num > ctx->ibuf_len)
+ num = ctx->ibuf_len;
+ memcpy(ptr, &(ctx->ibuf[ctx->ibuf_off]), num);
+ ret = num;
+ break;
+ default:
+ if (b->next_bio == NULL)
+ return 0;
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ }
+ return ret;
+ malloc_error:
+ BIOerr(BIO_F_BUFFER_CTRL, ERR_R_MALLOC_FAILURE);
+ return 0;
+}
+
+static long buffer_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
+{
+ long ret = 1;
+
+ if (b->next_bio == NULL)
+ return 0;
+ switch (cmd) {
+ default:
+ ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+ break;
+ }
+ return ret;
+}
+
+static int buffer_gets(BIO *b, char *buf, int size)
+{
+ BIO_F_BUFFER_CTX *ctx;
+ int num = 0, i, flag;
+ char *p;
+
+ ctx = (BIO_F_BUFFER_CTX *)b->ptr;
+ size--; /* reserve space for a '\0' */
+ BIO_clear_retry_flags(b);
+
+ for (;;) {
+ if (ctx->ibuf_len > 0) {
+ p = &(ctx->ibuf[ctx->ibuf_off]);
+ flag = 0;
+ for (i = 0; (i < ctx->ibuf_len) && (i < size); i++) {
+ *(buf++) = p[i];
+ if (p[i] == '\n') {
+ flag = 1;
+ i++;
+ break;
+ }
+ }
+ num += i;
+ size -= i;
+ ctx->ibuf_len -= i;
+ ctx->ibuf_off += i;
+ if (flag || size == 0) {
+ *buf = '\0';
+ return num;
+ }
+ } else { /* read another chunk */
+
+ i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ *buf = '\0';
+ if (i < 0)
+ return ((num > 0) ? num : i);
+ if (i == 0)
+ return num;
+ }
+ ctx->ibuf_len = i;
+ ctx->ibuf_off = 0;
+ }
+ }
+}
+
+static int buffer_puts(BIO *b, const char *str)
+{
+ return buffer_write(b, str, strlen(str));
+}
diff --git a/contrib/libs/openssl/crypto/bio/bf_lbuf.c b/contrib/libs/openssl/crypto/bio/bf_lbuf.c
index 260df96cf8..72f9901813 100644
--- a/contrib/libs/openssl/crypto/bio/bf_lbuf.c
+++ b/contrib/libs/openssl/crypto/bio/bf_lbuf.c
@@ -1,326 +1,326 @@
-/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include <errno.h>
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <errno.h>
#include "bio_local.h"
-#include "internal/cryptlib.h"
-#include <openssl/evp.h>
-
-static int linebuffer_write(BIO *h, const char *buf, int num);
-static int linebuffer_read(BIO *h, char *buf, int size);
-static int linebuffer_puts(BIO *h, const char *str);
-static int linebuffer_gets(BIO *h, char *str, int size);
-static long linebuffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-static int linebuffer_new(BIO *h);
-static int linebuffer_free(BIO *data);
-static long linebuffer_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
-
-/* A 10k maximum should be enough for most purposes */
-#define DEFAULT_LINEBUFFER_SIZE 1024*10
-
-/* #define DEBUG */
-
-static const BIO_METHOD methods_linebuffer = {
- BIO_TYPE_LINEBUFFER,
- "linebuffer",
- /* TODO: Convert to new style write function */
- bwrite_conv,
- linebuffer_write,
- /* TODO: Convert to new style read function */
- bread_conv,
- linebuffer_read,
- linebuffer_puts,
- linebuffer_gets,
- linebuffer_ctrl,
- linebuffer_new,
- linebuffer_free,
- linebuffer_callback_ctrl,
-};
-
-const BIO_METHOD *BIO_f_linebuffer(void)
-{
- return &methods_linebuffer;
-}
-
-typedef struct bio_linebuffer_ctx_struct {
- char *obuf; /* the output char array */
- int obuf_size; /* how big is the output buffer */
- int obuf_len; /* how many bytes are in it */
-} BIO_LINEBUFFER_CTX;
-
-static int linebuffer_new(BIO *bi)
-{
- BIO_LINEBUFFER_CTX *ctx;
-
- if ((ctx = OPENSSL_malloc(sizeof(*ctx))) == NULL) {
- BIOerr(BIO_F_LINEBUFFER_NEW, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- ctx->obuf = OPENSSL_malloc(DEFAULT_LINEBUFFER_SIZE);
- if (ctx->obuf == NULL) {
- BIOerr(BIO_F_LINEBUFFER_NEW, ERR_R_MALLOC_FAILURE);
- OPENSSL_free(ctx);
- return 0;
- }
- ctx->obuf_size = DEFAULT_LINEBUFFER_SIZE;
- ctx->obuf_len = 0;
-
- bi->init = 1;
- bi->ptr = (char *)ctx;
- bi->flags = 0;
- return 1;
-}
-
-static int linebuffer_free(BIO *a)
-{
- BIO_LINEBUFFER_CTX *b;
-
- if (a == NULL)
- return 0;
- b = (BIO_LINEBUFFER_CTX *)a->ptr;
- OPENSSL_free(b->obuf);
- OPENSSL_free(a->ptr);
- a->ptr = NULL;
- a->init = 0;
- a->flags = 0;
- return 1;
-}
-
-static int linebuffer_read(BIO *b, char *out, int outl)
-{
- int ret = 0;
-
- if (out == NULL)
- return 0;
- if (b->next_bio == NULL)
- return 0;
- ret = BIO_read(b->next_bio, out, outl);
- BIO_clear_retry_flags(b);
- BIO_copy_next_retry(b);
- return ret;
-}
-
-static int linebuffer_write(BIO *b, const char *in, int inl)
-{
- int i, num = 0, foundnl;
- BIO_LINEBUFFER_CTX *ctx;
-
- if ((in == NULL) || (inl <= 0))
- return 0;
- ctx = (BIO_LINEBUFFER_CTX *)b->ptr;
- if ((ctx == NULL) || (b->next_bio == NULL))
- return 0;
-
- BIO_clear_retry_flags(b);
-
- do {
- const char *p;
- char c;
-
- for (p = in, c = '\0'; p < in + inl && (c = *p) != '\n'; p++) ;
- if (c == '\n') {
- p++;
- foundnl = 1;
- } else
- foundnl = 0;
-
- /*
- * If a NL was found and we already have text in the save buffer,
- * concatenate them and write
- */
- while ((foundnl || p - in > ctx->obuf_size - ctx->obuf_len)
- && ctx->obuf_len > 0) {
- int orig_olen = ctx->obuf_len;
-
- i = ctx->obuf_size - ctx->obuf_len;
- if (p - in > 0) {
- if (i >= p - in) {
- memcpy(&(ctx->obuf[ctx->obuf_len]), in, p - in);
- ctx->obuf_len += p - in;
- inl -= p - in;
- num += p - in;
- in = p;
- } else {
- memcpy(&(ctx->obuf[ctx->obuf_len]), in, i);
- ctx->obuf_len += i;
- inl -= i;
- in += i;
- num += i;
- }
- }
- i = BIO_write(b->next_bio, ctx->obuf, ctx->obuf_len);
- if (i <= 0) {
- ctx->obuf_len = orig_olen;
- BIO_copy_next_retry(b);
-
- if (i < 0)
- return ((num > 0) ? num : i);
- if (i == 0)
- return num;
- }
- if (i < ctx->obuf_len)
- memmove(ctx->obuf, ctx->obuf + i, ctx->obuf_len - i);
- ctx->obuf_len -= i;
- }
-
- /*
- * Now that the save buffer is emptied, let's write the input buffer
- * if a NL was found and there is anything to write.
- */
- if ((foundnl || p - in > ctx->obuf_size) && p - in > 0) {
- i = BIO_write(b->next_bio, in, p - in);
- if (i <= 0) {
- BIO_copy_next_retry(b);
- if (i < 0)
- return ((num > 0) ? num : i);
- if (i == 0)
- return num;
- }
- num += i;
- in += i;
- inl -= i;
- }
- }
- while (foundnl && inl > 0);
- /*
- * We've written as much as we can. The rest of the input buffer, if
- * any, is text that doesn't and with a NL and therefore needs to be
- * saved for the next trip.
- */
- if (inl > 0) {
- memcpy(&(ctx->obuf[ctx->obuf_len]), in, inl);
- ctx->obuf_len += inl;
- num += inl;
- }
- return num;
-}
-
-static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr)
-{
- BIO *dbio;
- BIO_LINEBUFFER_CTX *ctx;
- long ret = 1;
- char *p;
- int r;
- int obs;
-
- ctx = (BIO_LINEBUFFER_CTX *)b->ptr;
-
- switch (cmd) {
- case BIO_CTRL_RESET:
- ctx->obuf_len = 0;
- if (b->next_bio == NULL)
- return 0;
- ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
- break;
- case BIO_CTRL_INFO:
- ret = (long)ctx->obuf_len;
- break;
- case BIO_CTRL_WPENDING:
- ret = (long)ctx->obuf_len;
- if (ret == 0) {
- if (b->next_bio == NULL)
- return 0;
- ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
- }
- break;
- case BIO_C_SET_BUFF_SIZE:
- obs = (int)num;
- p = ctx->obuf;
- if ((obs > DEFAULT_LINEBUFFER_SIZE) && (obs != ctx->obuf_size)) {
- p = OPENSSL_malloc((int)num);
- if (p == NULL)
- goto malloc_error;
- }
- if (ctx->obuf != p) {
- if (ctx->obuf_len > obs) {
- ctx->obuf_len = obs;
- }
- memcpy(p, ctx->obuf, ctx->obuf_len);
- OPENSSL_free(ctx->obuf);
- ctx->obuf = p;
- ctx->obuf_size = obs;
- }
- break;
- case BIO_C_DO_STATE_MACHINE:
- if (b->next_bio == NULL)
- return 0;
- BIO_clear_retry_flags(b);
- ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
- BIO_copy_next_retry(b);
- break;
-
- case BIO_CTRL_FLUSH:
- if (b->next_bio == NULL)
- return 0;
- if (ctx->obuf_len <= 0) {
- ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
- break;
- }
-
- for (;;) {
- BIO_clear_retry_flags(b);
- if (ctx->obuf_len > 0) {
- r = BIO_write(b->next_bio, ctx->obuf, ctx->obuf_len);
- BIO_copy_next_retry(b);
- if (r <= 0)
- return (long)r;
- if (r < ctx->obuf_len)
- memmove(ctx->obuf, ctx->obuf + r, ctx->obuf_len - r);
- ctx->obuf_len -= r;
- } else {
- ctx->obuf_len = 0;
- break;
- }
- }
- ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
- break;
- case BIO_CTRL_DUP:
- dbio = (BIO *)ptr;
- if (!BIO_set_write_buffer_size(dbio, ctx->obuf_size))
- ret = 0;
- break;
- default:
- if (b->next_bio == NULL)
- return 0;
- ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
- break;
- }
- return ret;
- malloc_error:
- BIOerr(BIO_F_LINEBUFFER_CTRL, ERR_R_MALLOC_FAILURE);
- return 0;
-}
-
-static long linebuffer_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
-{
- long ret = 1;
-
- if (b->next_bio == NULL)
- return 0;
- switch (cmd) {
- default:
- ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
- break;
- }
- return ret;
-}
-
-static int linebuffer_gets(BIO *b, char *buf, int size)
-{
- if (b->next_bio == NULL)
- return 0;
- return BIO_gets(b->next_bio, buf, size);
-}
-
-static int linebuffer_puts(BIO *b, const char *str)
-{
- return linebuffer_write(b, str, strlen(str));
-}
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+
+static int linebuffer_write(BIO *h, const char *buf, int num);
+static int linebuffer_read(BIO *h, char *buf, int size);
+static int linebuffer_puts(BIO *h, const char *str);
+static int linebuffer_gets(BIO *h, char *str, int size);
+static long linebuffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int linebuffer_new(BIO *h);
+static int linebuffer_free(BIO *data);
+static long linebuffer_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
+
+/* A 10k maximum should be enough for most purposes */
+#define DEFAULT_LINEBUFFER_SIZE 1024*10
+
+/* #define DEBUG */
+
+static const BIO_METHOD methods_linebuffer = {
+ BIO_TYPE_LINEBUFFER,
+ "linebuffer",
+ /* TODO: Convert to new style write function */
+ bwrite_conv,
+ linebuffer_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
+ linebuffer_read,
+ linebuffer_puts,
+ linebuffer_gets,
+ linebuffer_ctrl,
+ linebuffer_new,
+ linebuffer_free,
+ linebuffer_callback_ctrl,
+};
+
+const BIO_METHOD *BIO_f_linebuffer(void)
+{
+ return &methods_linebuffer;
+}
+
+typedef struct bio_linebuffer_ctx_struct {
+ char *obuf; /* the output char array */
+ int obuf_size; /* how big is the output buffer */
+ int obuf_len; /* how many bytes are in it */
+} BIO_LINEBUFFER_CTX;
+
+static int linebuffer_new(BIO *bi)
+{
+ BIO_LINEBUFFER_CTX *ctx;
+
+ if ((ctx = OPENSSL_malloc(sizeof(*ctx))) == NULL) {
+ BIOerr(BIO_F_LINEBUFFER_NEW, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ ctx->obuf = OPENSSL_malloc(DEFAULT_LINEBUFFER_SIZE);
+ if (ctx->obuf == NULL) {
+ BIOerr(BIO_F_LINEBUFFER_NEW, ERR_R_MALLOC_FAILURE);
+ OPENSSL_free(ctx);
+ return 0;
+ }
+ ctx->obuf_size = DEFAULT_LINEBUFFER_SIZE;
+ ctx->obuf_len = 0;
+
+ bi->init = 1;
+ bi->ptr = (char *)ctx;
+ bi->flags = 0;
+ return 1;
+}
+
+static int linebuffer_free(BIO *a)
+{
+ BIO_LINEBUFFER_CTX *b;
+
+ if (a == NULL)
+ return 0;
+ b = (BIO_LINEBUFFER_CTX *)a->ptr;
+ OPENSSL_free(b->obuf);
+ OPENSSL_free(a->ptr);
+ a->ptr = NULL;
+ a->init = 0;
+ a->flags = 0;
+ return 1;
+}
+
+static int linebuffer_read(BIO *b, char *out, int outl)
+{
+ int ret = 0;
+
+ if (out == NULL)
+ return 0;
+ if (b->next_bio == NULL)
+ return 0;
+ ret = BIO_read(b->next_bio, out, outl);
+ BIO_clear_retry_flags(b);
+ BIO_copy_next_retry(b);
+ return ret;
+}
+
+static int linebuffer_write(BIO *b, const char *in, int inl)
+{
+ int i, num = 0, foundnl;
+ BIO_LINEBUFFER_CTX *ctx;
+
+ if ((in == NULL) || (inl <= 0))
+ return 0;
+ ctx = (BIO_LINEBUFFER_CTX *)b->ptr;
+ if ((ctx == NULL) || (b->next_bio == NULL))
+ return 0;
+
+ BIO_clear_retry_flags(b);
+
+ do {
+ const char *p;
+ char c;
+
+ for (p = in, c = '\0'; p < in + inl && (c = *p) != '\n'; p++) ;
+ if (c == '\n') {
+ p++;
+ foundnl = 1;
+ } else
+ foundnl = 0;
+
+ /*
+ * If a NL was found and we already have text in the save buffer,
+ * concatenate them and write
+ */
+ while ((foundnl || p - in > ctx->obuf_size - ctx->obuf_len)
+ && ctx->obuf_len > 0) {
+ int orig_olen = ctx->obuf_len;
+
+ i = ctx->obuf_size - ctx->obuf_len;
+ if (p - in > 0) {
+ if (i >= p - in) {
+ memcpy(&(ctx->obuf[ctx->obuf_len]), in, p - in);
+ ctx->obuf_len += p - in;
+ inl -= p - in;
+ num += p - in;
+ in = p;
+ } else {
+ memcpy(&(ctx->obuf[ctx->obuf_len]), in, i);
+ ctx->obuf_len += i;
+ inl -= i;
+ in += i;
+ num += i;
+ }
+ }
+ i = BIO_write(b->next_bio, ctx->obuf, ctx->obuf_len);
+ if (i <= 0) {
+ ctx->obuf_len = orig_olen;
+ BIO_copy_next_retry(b);
+
+ if (i < 0)
+ return ((num > 0) ? num : i);
+ if (i == 0)
+ return num;
+ }
+ if (i < ctx->obuf_len)
+ memmove(ctx->obuf, ctx->obuf + i, ctx->obuf_len - i);
+ ctx->obuf_len -= i;
+ }
+
+ /*
+ * Now that the save buffer is emptied, let's write the input buffer
+ * if a NL was found and there is anything to write.
+ */
+ if ((foundnl || p - in > ctx->obuf_size) && p - in > 0) {
+ i = BIO_write(b->next_bio, in, p - in);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ if (i < 0)
+ return ((num > 0) ? num : i);
+ if (i == 0)
+ return num;
+ }
+ num += i;
+ in += i;
+ inl -= i;
+ }
+ }
+ while (foundnl && inl > 0);
+ /*
+ * We've written as much as we can. The rest of the input buffer, if
+ * any, is text that doesn't and with a NL and therefore needs to be
+ * saved for the next trip.
+ */
+ if (inl > 0) {
+ memcpy(&(ctx->obuf[ctx->obuf_len]), in, inl);
+ ctx->obuf_len += inl;
+ num += inl;
+ }
+ return num;
+}
+
+static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ BIO *dbio;
+ BIO_LINEBUFFER_CTX *ctx;
+ long ret = 1;
+ char *p;
+ int r;
+ int obs;
+
+ ctx = (BIO_LINEBUFFER_CTX *)b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ ctx->obuf_len = 0;
+ if (b->next_bio == NULL)
+ return 0;
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_INFO:
+ ret = (long)ctx->obuf_len;
+ break;
+ case BIO_CTRL_WPENDING:
+ ret = (long)ctx->obuf_len;
+ if (ret == 0) {
+ if (b->next_bio == NULL)
+ return 0;
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ }
+ break;
+ case BIO_C_SET_BUFF_SIZE:
+ obs = (int)num;
+ p = ctx->obuf;
+ if ((obs > DEFAULT_LINEBUFFER_SIZE) && (obs != ctx->obuf_size)) {
+ p = OPENSSL_malloc((int)num);
+ if (p == NULL)
+ goto malloc_error;
+ }
+ if (ctx->obuf != p) {
+ if (ctx->obuf_len > obs) {
+ ctx->obuf_len = obs;
+ }
+ memcpy(p, ctx->obuf, ctx->obuf_len);
+ OPENSSL_free(ctx->obuf);
+ ctx->obuf = p;
+ ctx->obuf_size = obs;
+ }
+ break;
+ case BIO_C_DO_STATE_MACHINE:
+ if (b->next_bio == NULL)
+ return 0;
+ BIO_clear_retry_flags(b);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ BIO_copy_next_retry(b);
+ break;
+
+ case BIO_CTRL_FLUSH:
+ if (b->next_bio == NULL)
+ return 0;
+ if (ctx->obuf_len <= 0) {
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ }
+
+ for (;;) {
+ BIO_clear_retry_flags(b);
+ if (ctx->obuf_len > 0) {
+ r = BIO_write(b->next_bio, ctx->obuf, ctx->obuf_len);
+ BIO_copy_next_retry(b);
+ if (r <= 0)
+ return (long)r;
+ if (r < ctx->obuf_len)
+ memmove(ctx->obuf, ctx->obuf + r, ctx->obuf_len - r);
+ ctx->obuf_len -= r;
+ } else {
+ ctx->obuf_len = 0;
+ break;
+ }
+ }
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_DUP:
+ dbio = (BIO *)ptr;
+ if (!BIO_set_write_buffer_size(dbio, ctx->obuf_size))
+ ret = 0;
+ break;
+ default:
+ if (b->next_bio == NULL)
+ return 0;
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ }
+ return ret;
+ malloc_error:
+ BIOerr(BIO_F_LINEBUFFER_CTRL, ERR_R_MALLOC_FAILURE);
+ return 0;
+}
+
+static long linebuffer_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
+{
+ long ret = 1;
+
+ if (b->next_bio == NULL)
+ return 0;
+ switch (cmd) {
+ default:
+ ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+ break;
+ }
+ return ret;
+}
+
+static int linebuffer_gets(BIO *b, char *buf, int size)
+{
+ if (b->next_bio == NULL)
+ return 0;
+ return BIO_gets(b->next_bio, buf, size);
+}
+
+static int linebuffer_puts(BIO *b, const char *str)
+{
+ return linebuffer_write(b, str, strlen(str));
+}
diff --git a/contrib/libs/openssl/crypto/bio/bf_nbio.c b/contrib/libs/openssl/crypto/bio/bf_nbio.c
index 123f77f5e9..dd7011ab66 100644
--- a/contrib/libs/openssl/crypto/bio/bf_nbio.c
+++ b/contrib/libs/openssl/crypto/bio/bf_nbio.c
@@ -1,200 +1,200 @@
-/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include <errno.h>
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <errno.h>
#include "bio_local.h"
-#include "internal/cryptlib.h"
-#include <openssl/rand.h>
-
-/*
- * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest
- */
-
-static int nbiof_write(BIO *h, const char *buf, int num);
-static int nbiof_read(BIO *h, char *buf, int size);
-static int nbiof_puts(BIO *h, const char *str);
-static int nbiof_gets(BIO *h, char *str, int size);
-static long nbiof_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-static int nbiof_new(BIO *h);
-static int nbiof_free(BIO *data);
-static long nbiof_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
-typedef struct nbio_test_st {
- /* only set if we sent a 'should retry' error */
- int lrn;
- int lwn;
-} NBIO_TEST;
-
-static const BIO_METHOD methods_nbiof = {
- BIO_TYPE_NBIO_TEST,
- "non-blocking IO test filter",
- /* TODO: Convert to new style write function */
- bwrite_conv,
- nbiof_write,
- /* TODO: Convert to new style read function */
- bread_conv,
- nbiof_read,
- nbiof_puts,
- nbiof_gets,
- nbiof_ctrl,
- nbiof_new,
- nbiof_free,
- nbiof_callback_ctrl,
-};
-
-const BIO_METHOD *BIO_f_nbio_test(void)
-{
- return &methods_nbiof;
-}
-
-static int nbiof_new(BIO *bi)
-{
- NBIO_TEST *nt;
-
- if ((nt = OPENSSL_zalloc(sizeof(*nt))) == NULL) {
- BIOerr(BIO_F_NBIOF_NEW, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- nt->lrn = -1;
- nt->lwn = -1;
- bi->ptr = (char *)nt;
- bi->init = 1;
- return 1;
-}
-
-static int nbiof_free(BIO *a)
-{
- if (a == NULL)
- return 0;
- OPENSSL_free(a->ptr);
- a->ptr = NULL;
- a->init = 0;
- a->flags = 0;
- return 1;
-}
-
-static int nbiof_read(BIO *b, char *out, int outl)
-{
- int ret = 0;
- int num;
- unsigned char n;
-
- if (out == NULL)
- return 0;
- if (b->next_bio == NULL)
- return 0;
-
- BIO_clear_retry_flags(b);
- if (RAND_priv_bytes(&n, 1) <= 0)
- return -1;
- num = (n & 0x07);
-
- if (outl > num)
- outl = num;
-
- if (num == 0) {
- ret = -1;
- BIO_set_retry_read(b);
- } else {
- ret = BIO_read(b->next_bio, out, outl);
- if (ret < 0)
- BIO_copy_next_retry(b);
- }
- return ret;
-}
-
-static int nbiof_write(BIO *b, const char *in, int inl)
-{
- NBIO_TEST *nt;
- int ret = 0;
- int num;
- unsigned char n;
-
- if ((in == NULL) || (inl <= 0))
- return 0;
- if (b->next_bio == NULL)
- return 0;
- nt = (NBIO_TEST *)b->ptr;
-
- BIO_clear_retry_flags(b);
-
- if (nt->lwn > 0) {
- num = nt->lwn;
- nt->lwn = 0;
- } else {
- if (RAND_priv_bytes(&n, 1) <= 0)
- return -1;
- num = (n & 7);
- }
-
- if (inl > num)
- inl = num;
-
- if (num == 0) {
- ret = -1;
- BIO_set_retry_write(b);
- } else {
- ret = BIO_write(b->next_bio, in, inl);
- if (ret < 0) {
- BIO_copy_next_retry(b);
- nt->lwn = inl;
- }
- }
- return ret;
-}
-
-static long nbiof_ctrl(BIO *b, int cmd, long num, void *ptr)
-{
- long ret;
-
- if (b->next_bio == NULL)
- return 0;
- switch (cmd) {
- case BIO_C_DO_STATE_MACHINE:
- BIO_clear_retry_flags(b);
- ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
- BIO_copy_next_retry(b);
- break;
- case BIO_CTRL_DUP:
- ret = 0L;
- break;
- default:
- ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
- break;
- }
- return ret;
-}
-
-static long nbiof_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
-{
- long ret = 1;
-
- if (b->next_bio == NULL)
- return 0;
- switch (cmd) {
- default:
- ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
- break;
- }
- return ret;
-}
-
-static int nbiof_gets(BIO *bp, char *buf, int size)
-{
- if (bp->next_bio == NULL)
- return 0;
- return BIO_gets(bp->next_bio, buf, size);
-}
-
-static int nbiof_puts(BIO *bp, const char *str)
-{
- if (bp->next_bio == NULL)
- return 0;
- return BIO_puts(bp->next_bio, str);
-}
+#include "internal/cryptlib.h"
+#include <openssl/rand.h>
+
+/*
+ * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest
+ */
+
+static int nbiof_write(BIO *h, const char *buf, int num);
+static int nbiof_read(BIO *h, char *buf, int size);
+static int nbiof_puts(BIO *h, const char *str);
+static int nbiof_gets(BIO *h, char *str, int size);
+static long nbiof_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int nbiof_new(BIO *h);
+static int nbiof_free(BIO *data);
+static long nbiof_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
+typedef struct nbio_test_st {
+ /* only set if we sent a 'should retry' error */
+ int lrn;
+ int lwn;
+} NBIO_TEST;
+
+static const BIO_METHOD methods_nbiof = {
+ BIO_TYPE_NBIO_TEST,
+ "non-blocking IO test filter",
+ /* TODO: Convert to new style write function */
+ bwrite_conv,
+ nbiof_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
+ nbiof_read,
+ nbiof_puts,
+ nbiof_gets,
+ nbiof_ctrl,
+ nbiof_new,
+ nbiof_free,
+ nbiof_callback_ctrl,
+};
+
+const BIO_METHOD *BIO_f_nbio_test(void)
+{
+ return &methods_nbiof;
+}
+
+static int nbiof_new(BIO *bi)
+{
+ NBIO_TEST *nt;
+
+ if ((nt = OPENSSL_zalloc(sizeof(*nt))) == NULL) {
+ BIOerr(BIO_F_NBIOF_NEW, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ nt->lrn = -1;
+ nt->lwn = -1;
+ bi->ptr = (char *)nt;
+ bi->init = 1;
+ return 1;
+}
+
+static int nbiof_free(BIO *a)
+{
+ if (a == NULL)
+ return 0;
+ OPENSSL_free(a->ptr);
+ a->ptr = NULL;
+ a->init = 0;
+ a->flags = 0;
+ return 1;
+}
+
+static int nbiof_read(BIO *b, char *out, int outl)
+{
+ int ret = 0;
+ int num;
+ unsigned char n;
+
+ if (out == NULL)
+ return 0;
+ if (b->next_bio == NULL)
+ return 0;
+
+ BIO_clear_retry_flags(b);
+ if (RAND_priv_bytes(&n, 1) <= 0)
+ return -1;
+ num = (n & 0x07);
+
+ if (outl > num)
+ outl = num;
+
+ if (num == 0) {
+ ret = -1;
+ BIO_set_retry_read(b);
+ } else {
+ ret = BIO_read(b->next_bio, out, outl);
+ if (ret < 0)
+ BIO_copy_next_retry(b);
+ }
+ return ret;
+}
+
+static int nbiof_write(BIO *b, const char *in, int inl)
+{
+ NBIO_TEST *nt;
+ int ret = 0;
+ int num;
+ unsigned char n;
+
+ if ((in == NULL) || (inl <= 0))
+ return 0;
+ if (b->next_bio == NULL)
+ return 0;
+ nt = (NBIO_TEST *)b->ptr;
+
+ BIO_clear_retry_flags(b);
+
+ if (nt->lwn > 0) {
+ num = nt->lwn;
+ nt->lwn = 0;
+ } else {
+ if (RAND_priv_bytes(&n, 1) <= 0)
+ return -1;
+ num = (n & 7);
+ }
+
+ if (inl > num)
+ inl = num;
+
+ if (num == 0) {
+ ret = -1;
+ BIO_set_retry_write(b);
+ } else {
+ ret = BIO_write(b->next_bio, in, inl);
+ if (ret < 0) {
+ BIO_copy_next_retry(b);
+ nt->lwn = inl;
+ }
+ }
+ return ret;
+}
+
+static long nbiof_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ long ret;
+
+ if (b->next_bio == NULL)
+ return 0;
+ switch (cmd) {
+ case BIO_C_DO_STATE_MACHINE:
+ BIO_clear_retry_flags(b);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ BIO_copy_next_retry(b);
+ break;
+ case BIO_CTRL_DUP:
+ ret = 0L;
+ break;
+ default:
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ }
+ return ret;
+}
+
+static long nbiof_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
+{
+ long ret = 1;
+
+ if (b->next_bio == NULL)
+ return 0;
+ switch (cmd) {
+ default:
+ ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+ break;
+ }
+ return ret;
+}
+
+static int nbiof_gets(BIO *bp, char *buf, int size)
+{
+ if (bp->next_bio == NULL)
+ return 0;
+ return BIO_gets(bp->next_bio, buf, size);
+}
+
+static int nbiof_puts(BIO *bp, const char *str)
+{
+ if (bp->next_bio == NULL)
+ return 0;
+ return BIO_puts(bp->next_bio, str);
+}
diff --git a/contrib/libs/openssl/crypto/bio/bf_null.c b/contrib/libs/openssl/crypto/bio/bf_null.c
index 22f788bfb3..48c6be692a 100644
--- a/contrib/libs/openssl/crypto/bio/bf_null.c
+++ b/contrib/libs/openssl/crypto/bio/bf_null.c
@@ -1,122 +1,122 @@
-/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include <errno.h>
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <errno.h>
#include "bio_local.h"
-#include "internal/cryptlib.h"
-
-/*
- * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest
- */
-
-static int nullf_write(BIO *h, const char *buf, int num);
-static int nullf_read(BIO *h, char *buf, int size);
-static int nullf_puts(BIO *h, const char *str);
-static int nullf_gets(BIO *h, char *str, int size);
-static long nullf_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-static long nullf_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
-static const BIO_METHOD methods_nullf = {
- BIO_TYPE_NULL_FILTER,
- "NULL filter",
- /* TODO: Convert to new style write function */
- bwrite_conv,
- nullf_write,
- /* TODO: Convert to new style read function */
- bread_conv,
- nullf_read,
- nullf_puts,
- nullf_gets,
- nullf_ctrl,
- NULL,
- NULL,
- nullf_callback_ctrl,
-};
-
-const BIO_METHOD *BIO_f_null(void)
-{
- return &methods_nullf;
-}
-
-static int nullf_read(BIO *b, char *out, int outl)
-{
- int ret = 0;
-
- if (out == NULL)
- return 0;
- if (b->next_bio == NULL)
- return 0;
- ret = BIO_read(b->next_bio, out, outl);
- BIO_clear_retry_flags(b);
- BIO_copy_next_retry(b);
- return ret;
-}
-
-static int nullf_write(BIO *b, const char *in, int inl)
-{
- int ret = 0;
-
- if ((in == NULL) || (inl <= 0))
- return 0;
- if (b->next_bio == NULL)
- return 0;
- ret = BIO_write(b->next_bio, in, inl);
- BIO_clear_retry_flags(b);
- BIO_copy_next_retry(b);
- return ret;
-}
-
-static long nullf_ctrl(BIO *b, int cmd, long num, void *ptr)
-{
- long ret;
-
- if (b->next_bio == NULL)
- return 0;
- switch (cmd) {
- case BIO_C_DO_STATE_MACHINE:
- BIO_clear_retry_flags(b);
- ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
- BIO_copy_next_retry(b);
- break;
- case BIO_CTRL_DUP:
- ret = 0L;
- break;
- default:
- ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
- }
- return ret;
-}
-
-static long nullf_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
-{
- long ret = 1;
-
- if (b->next_bio == NULL)
- return 0;
- switch (cmd) {
- default:
- ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
- break;
- }
- return ret;
-}
-
-static int nullf_gets(BIO *bp, char *buf, int size)
-{
- if (bp->next_bio == NULL)
- return 0;
- return BIO_gets(bp->next_bio, buf, size);
-}
-
-static int nullf_puts(BIO *bp, const char *str)
-{
- if (bp->next_bio == NULL)
- return 0;
- return BIO_puts(bp->next_bio, str);
-}
+#include "internal/cryptlib.h"
+
+/*
+ * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest
+ */
+
+static int nullf_write(BIO *h, const char *buf, int num);
+static int nullf_read(BIO *h, char *buf, int size);
+static int nullf_puts(BIO *h, const char *str);
+static int nullf_gets(BIO *h, char *str, int size);
+static long nullf_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static long nullf_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
+static const BIO_METHOD methods_nullf = {
+ BIO_TYPE_NULL_FILTER,
+ "NULL filter",
+ /* TODO: Convert to new style write function */
+ bwrite_conv,
+ nullf_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
+ nullf_read,
+ nullf_puts,
+ nullf_gets,
+ nullf_ctrl,
+ NULL,
+ NULL,
+ nullf_callback_ctrl,
+};
+
+const BIO_METHOD *BIO_f_null(void)
+{
+ return &methods_nullf;
+}
+
+static int nullf_read(BIO *b, char *out, int outl)
+{
+ int ret = 0;
+
+ if (out == NULL)
+ return 0;
+ if (b->next_bio == NULL)
+ return 0;
+ ret = BIO_read(b->next_bio, out, outl);
+ BIO_clear_retry_flags(b);
+ BIO_copy_next_retry(b);
+ return ret;
+}
+
+static int nullf_write(BIO *b, const char *in, int inl)
+{
+ int ret = 0;
+
+ if ((in == NULL) || (inl <= 0))
+ return 0;
+ if (b->next_bio == NULL)
+ return 0;
+ ret = BIO_write(b->next_bio, in, inl);
+ BIO_clear_retry_flags(b);
+ BIO_copy_next_retry(b);
+ return ret;
+}
+
+static long nullf_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ long ret;
+
+ if (b->next_bio == NULL)
+ return 0;
+ switch (cmd) {
+ case BIO_C_DO_STATE_MACHINE:
+ BIO_clear_retry_flags(b);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ BIO_copy_next_retry(b);
+ break;
+ case BIO_CTRL_DUP:
+ ret = 0L;
+ break;
+ default:
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ }
+ return ret;
+}
+
+static long nullf_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
+{
+ long ret = 1;
+
+ if (b->next_bio == NULL)
+ return 0;
+ switch (cmd) {
+ default:
+ ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+ break;
+ }
+ return ret;
+}
+
+static int nullf_gets(BIO *bp, char *buf, int size)
+{
+ if (bp->next_bio == NULL)
+ return 0;
+ return BIO_gets(bp->next_bio, buf, size);
+}
+
+static int nullf_puts(BIO *bp, const char *str)
+{
+ if (bp->next_bio == NULL)
+ return 0;
+ return BIO_puts(bp->next_bio, str);
+}
diff --git a/contrib/libs/openssl/crypto/bio/bio_cb.c b/contrib/libs/openssl/crypto/bio/bio_cb.c
index 2ce733031e..a153100a88 100644
--- a/contrib/libs/openssl/crypto/bio/bio_cb.c
+++ b/contrib/libs/openssl/crypto/bio/bio_cb.c
@@ -1,98 +1,98 @@
-/*
- * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
+/*
+ * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
#include "bio_local.h"
-#include "internal/cryptlib.h"
-#include <openssl/err.h>
-
-long BIO_debug_callback(BIO *bio, int cmd, const char *argp,
- int argi, long argl, long ret)
-{
- BIO *b;
- char buf[256];
- char *p;
- long r = 1;
- int len, left;
-
- if (BIO_CB_RETURN & cmd)
- r = ret;
-
- len = BIO_snprintf(buf, sizeof(buf), "BIO[%p]: ", (void *)bio);
-
- /* Ignore errors and continue printing the other information. */
- if (len < 0)
- len = 0;
- p = buf + len;
- left = sizeof(buf) - len;
-
- switch (cmd) {
- case BIO_CB_FREE:
- BIO_snprintf(p, left, "Free - %s\n", bio->method->name);
- break;
- case BIO_CB_READ:
- if (bio->method->type & BIO_TYPE_DESCRIPTOR)
- BIO_snprintf(p, left, "read(%d,%lu) - %s fd=%d\n",
- bio->num, (unsigned long)argi,
- bio->method->name, bio->num);
- else
- BIO_snprintf(p, left, "read(%d,%lu) - %s\n",
- bio->num, (unsigned long)argi, bio->method->name);
- break;
- case BIO_CB_WRITE:
- if (bio->method->type & BIO_TYPE_DESCRIPTOR)
- BIO_snprintf(p, left, "write(%d,%lu) - %s fd=%d\n",
- bio->num, (unsigned long)argi,
- bio->method->name, bio->num);
- else
- BIO_snprintf(p, left, "write(%d,%lu) - %s\n",
- bio->num, (unsigned long)argi, bio->method->name);
- break;
- case BIO_CB_PUTS:
- BIO_snprintf(p, left, "puts() - %s\n", bio->method->name);
- break;
- case BIO_CB_GETS:
- BIO_snprintf(p, left, "gets(%lu) - %s\n", (unsigned long)argi,
- bio->method->name);
- break;
- case BIO_CB_CTRL:
- BIO_snprintf(p, left, "ctrl(%lu) - %s\n", (unsigned long)argi,
- bio->method->name);
- break;
- case BIO_CB_RETURN | BIO_CB_READ:
- BIO_snprintf(p, left, "read return %ld\n", ret);
- break;
- case BIO_CB_RETURN | BIO_CB_WRITE:
- BIO_snprintf(p, left, "write return %ld\n", ret);
- break;
- case BIO_CB_RETURN | BIO_CB_GETS:
- BIO_snprintf(p, left, "gets return %ld\n", ret);
- break;
- case BIO_CB_RETURN | BIO_CB_PUTS:
- BIO_snprintf(p, left, "puts return %ld\n", ret);
- break;
- case BIO_CB_RETURN | BIO_CB_CTRL:
- BIO_snprintf(p, left, "ctrl return %ld\n", ret);
- break;
- default:
- BIO_snprintf(p, left, "bio callback - unknown type (%d)\n", cmd);
- break;
- }
-
- b = (BIO *)bio->cb_arg;
- if (b != NULL)
- BIO_write(b, buf, strlen(buf));
-#if !defined(OPENSSL_NO_STDIO)
- else
- fputs(buf, stderr);
-#endif
- return r;
-}
+#include "internal/cryptlib.h"
+#include <openssl/err.h>
+
+long BIO_debug_callback(BIO *bio, int cmd, const char *argp,
+ int argi, long argl, long ret)
+{
+ BIO *b;
+ char buf[256];
+ char *p;
+ long r = 1;
+ int len, left;
+
+ if (BIO_CB_RETURN & cmd)
+ r = ret;
+
+ len = BIO_snprintf(buf, sizeof(buf), "BIO[%p]: ", (void *)bio);
+
+ /* Ignore errors and continue printing the other information. */
+ if (len < 0)
+ len = 0;
+ p = buf + len;
+ left = sizeof(buf) - len;
+
+ switch (cmd) {
+ case BIO_CB_FREE:
+ BIO_snprintf(p, left, "Free - %s\n", bio->method->name);
+ break;
+ case BIO_CB_READ:
+ if (bio->method->type & BIO_TYPE_DESCRIPTOR)
+ BIO_snprintf(p, left, "read(%d,%lu) - %s fd=%d\n",
+ bio->num, (unsigned long)argi,
+ bio->method->name, bio->num);
+ else
+ BIO_snprintf(p, left, "read(%d,%lu) - %s\n",
+ bio->num, (unsigned long)argi, bio->method->name);
+ break;
+ case BIO_CB_WRITE:
+ if (bio->method->type & BIO_TYPE_DESCRIPTOR)
+ BIO_snprintf(p, left, "write(%d,%lu) - %s fd=%d\n",
+ bio->num, (unsigned long)argi,
+ bio->method->name, bio->num);
+ else
+ BIO_snprintf(p, left, "write(%d,%lu) - %s\n",
+ bio->num, (unsigned long)argi, bio->method->name);
+ break;
+ case BIO_CB_PUTS:
+ BIO_snprintf(p, left, "puts() - %s\n", bio->method->name);
+ break;
+ case BIO_CB_GETS:
+ BIO_snprintf(p, left, "gets(%lu) - %s\n", (unsigned long)argi,
+ bio->method->name);
+ break;
+ case BIO_CB_CTRL:
+ BIO_snprintf(p, left, "ctrl(%lu) - %s\n", (unsigned long)argi,
+ bio->method->name);
+ break;
+ case BIO_CB_RETURN | BIO_CB_READ:
+ BIO_snprintf(p, left, "read return %ld\n", ret);
+ break;
+ case BIO_CB_RETURN | BIO_CB_WRITE:
+ BIO_snprintf(p, left, "write return %ld\n", ret);
+ break;
+ case BIO_CB_RETURN | BIO_CB_GETS:
+ BIO_snprintf(p, left, "gets return %ld\n", ret);
+ break;
+ case BIO_CB_RETURN | BIO_CB_PUTS:
+ BIO_snprintf(p, left, "puts return %ld\n", ret);
+ break;
+ case BIO_CB_RETURN | BIO_CB_CTRL:
+ BIO_snprintf(p, left, "ctrl return %ld\n", ret);
+ break;
+ default:
+ BIO_snprintf(p, left, "bio callback - unknown type (%d)\n", cmd);
+ break;
+ }
+
+ b = (BIO *)bio->cb_arg;
+ if (b != NULL)
+ BIO_write(b, buf, strlen(buf));
+#if !defined(OPENSSL_NO_STDIO)
+ else
+ fputs(buf, stderr);
+#endif
+ return r;
+}
diff --git a/contrib/libs/openssl/crypto/bio/bio_err.c b/contrib/libs/openssl/crypto/bio/bio_err.c
index dce434f302..7aa9dabb29 100644
--- a/contrib/libs/openssl/crypto/bio/bio_err.c
+++ b/contrib/libs/openssl/crypto/bio/bio_err.c
@@ -1,145 +1,145 @@
-/*
- * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <openssl/err.h>
-#include <openssl/bioerr.h>
-
-#ifndef OPENSSL_NO_ERR
-
-static const ERR_STRING_DATA BIO_str_functs[] = {
- {ERR_PACK(ERR_LIB_BIO, BIO_F_ACPT_STATE, 0), "acpt_state"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_ADDRINFO_WRAP, 0), "addrinfo_wrap"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_ADDR_STRINGS, 0), "addr_strings"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ACCEPT, 0), "BIO_accept"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ACCEPT_EX, 0), "BIO_accept_ex"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ACCEPT_NEW, 0), "BIO_ACCEPT_new"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ADDR_NEW, 0), "BIO_ADDR_new"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_BIND, 0), "BIO_bind"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_CALLBACK_CTRL, 0), "BIO_callback_ctrl"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_CONNECT, 0), "BIO_connect"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_CONNECT_NEW, 0), "BIO_CONNECT_new"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_CTRL, 0), "BIO_ctrl"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_GETS, 0), "BIO_gets"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_GET_HOST_IP, 0), "BIO_get_host_ip"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_GET_NEW_INDEX, 0), "BIO_get_new_index"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_GET_PORT, 0), "BIO_get_port"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_LISTEN, 0), "BIO_listen"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_LOOKUP, 0), "BIO_lookup"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_LOOKUP_EX, 0), "BIO_lookup_ex"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_MAKE_PAIR, 0), "bio_make_pair"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_METH_NEW, 0), "BIO_meth_new"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NEW, 0), "BIO_new"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NEW_DGRAM_SCTP, 0), "BIO_new_dgram_sctp"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NEW_FILE, 0), "BIO_new_file"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NEW_MEM_BUF, 0), "BIO_new_mem_buf"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NREAD, 0), "BIO_nread"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NREAD0, 0), "BIO_nread0"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NWRITE, 0), "BIO_nwrite"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NWRITE0, 0), "BIO_nwrite0"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_PARSE_HOSTSERV, 0), "BIO_parse_hostserv"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_PUTS, 0), "BIO_puts"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_READ, 0), "BIO_read"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_READ_EX, 0), "BIO_read_ex"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_READ_INTERN, 0), "bio_read_intern"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_SOCKET, 0), "BIO_socket"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_SOCKET_NBIO, 0), "BIO_socket_nbio"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_SOCK_INFO, 0), "BIO_sock_info"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_SOCK_INIT, 0), "BIO_sock_init"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_WRITE, 0), "BIO_write"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_WRITE_EX, 0), "BIO_write_ex"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_WRITE_INTERN, 0), "bio_write_intern"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_BUFFER_CTRL, 0), "buffer_ctrl"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_CONN_CTRL, 0), "conn_ctrl"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_CONN_STATE, 0), "conn_state"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_DGRAM_SCTP_NEW, 0), "dgram_sctp_new"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_DGRAM_SCTP_READ, 0), "dgram_sctp_read"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_DGRAM_SCTP_WRITE, 0), "dgram_sctp_write"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_DOAPR_OUTCH, 0), "doapr_outch"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_FILE_CTRL, 0), "file_ctrl"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_FILE_READ, 0), "file_read"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_LINEBUFFER_CTRL, 0), "linebuffer_ctrl"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_LINEBUFFER_NEW, 0), "linebuffer_new"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_MEM_WRITE, 0), "mem_write"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_NBIOF_NEW, 0), "nbiof_new"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_SLG_WRITE, 0), "slg_write"},
- {ERR_PACK(ERR_LIB_BIO, BIO_F_SSL_NEW, 0), "SSL_new"},
- {0, NULL}
-};
-
-static const ERR_STRING_DATA BIO_str_reasons[] = {
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_ACCEPT_ERROR), "accept error"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET),
- "addrinfo addr is not af inet"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_AMBIGUOUS_HOST_OR_SERVICE),
- "ambiguous host or service"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_BAD_FOPEN_MODE), "bad fopen mode"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_BROKEN_PIPE), "broken pipe"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_CONNECT_ERROR), "connect error"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET),
- "gethostbyname addr is not af inet"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETSOCKNAME_ERROR), "getsockname error"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS),
- "getsockname truncated address"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETTING_SOCKTYPE), "getting socktype"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_INVALID_ARGUMENT), "invalid argument"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_INVALID_SOCKET), "invalid socket"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_IN_USE), "in use"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_LENGTH_TOO_LONG), "length too long"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_LISTEN_V6_ONLY), "listen v6 only"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_LOOKUP_RETURNED_NOTHING),
- "lookup returned nothing"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_MALFORMED_HOST_OR_SERVICE),
- "malformed host or service"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NBIO_CONNECT_ERROR), "nbio connect error"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED),
- "no accept addr or service specified"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED),
- "no hostname or service specified"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_PORT_DEFINED), "no port defined"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_SUCH_FILE), "no such file"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NULL_PARAMETER), "null parameter"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_BIND_SOCKET),
- "unable to bind socket"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_CREATE_SOCKET),
- "unable to create socket"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_KEEPALIVE),
- "unable to keepalive"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_LISTEN_SOCKET),
- "unable to listen socket"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_NODELAY), "unable to nodelay"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_REUSEADDR),
- "unable to reuseaddr"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNAVAILABLE_IP_FAMILY),
- "unavailable ip family"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNINITIALIZED), "uninitialized"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNKNOWN_INFO_TYPE), "unknown info type"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNSUPPORTED_IP_FAMILY),
- "unsupported ip family"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNSUPPORTED_METHOD), "unsupported method"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNSUPPORTED_PROTOCOL_FAMILY),
- "unsupported protocol family"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_WRITE_TO_READ_ONLY_BIO),
- "write to read only BIO"},
- {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_WSASTARTUP), "WSAStartup"},
- {0, NULL}
-};
-
-#endif
-
-int ERR_load_BIO_strings(void)
-{
-#ifndef OPENSSL_NO_ERR
- if (ERR_func_error_string(BIO_str_functs[0].error) == NULL) {
- ERR_load_strings_const(BIO_str_functs);
- ERR_load_strings_const(BIO_str_reasons);
- }
-#endif
- return 1;
-}
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/err.h>
+#include <openssl/bioerr.h>
+
+#ifndef OPENSSL_NO_ERR
+
+static const ERR_STRING_DATA BIO_str_functs[] = {
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_ACPT_STATE, 0), "acpt_state"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_ADDRINFO_WRAP, 0), "addrinfo_wrap"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_ADDR_STRINGS, 0), "addr_strings"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ACCEPT, 0), "BIO_accept"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ACCEPT_EX, 0), "BIO_accept_ex"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ACCEPT_NEW, 0), "BIO_ACCEPT_new"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_ADDR_NEW, 0), "BIO_ADDR_new"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_BIND, 0), "BIO_bind"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_CALLBACK_CTRL, 0), "BIO_callback_ctrl"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_CONNECT, 0), "BIO_connect"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_CONNECT_NEW, 0), "BIO_CONNECT_new"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_CTRL, 0), "BIO_ctrl"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_GETS, 0), "BIO_gets"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_GET_HOST_IP, 0), "BIO_get_host_ip"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_GET_NEW_INDEX, 0), "BIO_get_new_index"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_GET_PORT, 0), "BIO_get_port"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_LISTEN, 0), "BIO_listen"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_LOOKUP, 0), "BIO_lookup"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_LOOKUP_EX, 0), "BIO_lookup_ex"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_MAKE_PAIR, 0), "bio_make_pair"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_METH_NEW, 0), "BIO_meth_new"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NEW, 0), "BIO_new"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NEW_DGRAM_SCTP, 0), "BIO_new_dgram_sctp"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NEW_FILE, 0), "BIO_new_file"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NEW_MEM_BUF, 0), "BIO_new_mem_buf"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NREAD, 0), "BIO_nread"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NREAD0, 0), "BIO_nread0"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NWRITE, 0), "BIO_nwrite"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_NWRITE0, 0), "BIO_nwrite0"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_PARSE_HOSTSERV, 0), "BIO_parse_hostserv"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_PUTS, 0), "BIO_puts"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_READ, 0), "BIO_read"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_READ_EX, 0), "BIO_read_ex"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_READ_INTERN, 0), "bio_read_intern"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_SOCKET, 0), "BIO_socket"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_SOCKET_NBIO, 0), "BIO_socket_nbio"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_SOCK_INFO, 0), "BIO_sock_info"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_SOCK_INIT, 0), "BIO_sock_init"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_WRITE, 0), "BIO_write"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_WRITE_EX, 0), "BIO_write_ex"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BIO_WRITE_INTERN, 0), "bio_write_intern"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_BUFFER_CTRL, 0), "buffer_ctrl"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_CONN_CTRL, 0), "conn_ctrl"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_CONN_STATE, 0), "conn_state"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_DGRAM_SCTP_NEW, 0), "dgram_sctp_new"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_DGRAM_SCTP_READ, 0), "dgram_sctp_read"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_DGRAM_SCTP_WRITE, 0), "dgram_sctp_write"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_DOAPR_OUTCH, 0), "doapr_outch"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_FILE_CTRL, 0), "file_ctrl"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_FILE_READ, 0), "file_read"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_LINEBUFFER_CTRL, 0), "linebuffer_ctrl"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_LINEBUFFER_NEW, 0), "linebuffer_new"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_MEM_WRITE, 0), "mem_write"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_NBIOF_NEW, 0), "nbiof_new"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_SLG_WRITE, 0), "slg_write"},
+ {ERR_PACK(ERR_LIB_BIO, BIO_F_SSL_NEW, 0), "SSL_new"},
+ {0, NULL}
+};
+
+static const ERR_STRING_DATA BIO_str_reasons[] = {
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_ACCEPT_ERROR), "accept error"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET),
+ "addrinfo addr is not af inet"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_AMBIGUOUS_HOST_OR_SERVICE),
+ "ambiguous host or service"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_BAD_FOPEN_MODE), "bad fopen mode"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_BROKEN_PIPE), "broken pipe"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_CONNECT_ERROR), "connect error"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET),
+ "gethostbyname addr is not af inet"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETSOCKNAME_ERROR), "getsockname error"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS),
+ "getsockname truncated address"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETTING_SOCKTYPE), "getting socktype"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_INVALID_ARGUMENT), "invalid argument"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_INVALID_SOCKET), "invalid socket"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_IN_USE), "in use"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_LENGTH_TOO_LONG), "length too long"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_LISTEN_V6_ONLY), "listen v6 only"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_LOOKUP_RETURNED_NOTHING),
+ "lookup returned nothing"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_MALFORMED_HOST_OR_SERVICE),
+ "malformed host or service"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NBIO_CONNECT_ERROR), "nbio connect error"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED),
+ "no accept addr or service specified"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED),
+ "no hostname or service specified"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_PORT_DEFINED), "no port defined"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_SUCH_FILE), "no such file"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NULL_PARAMETER), "null parameter"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_BIND_SOCKET),
+ "unable to bind socket"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_CREATE_SOCKET),
+ "unable to create socket"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_KEEPALIVE),
+ "unable to keepalive"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_LISTEN_SOCKET),
+ "unable to listen socket"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_NODELAY), "unable to nodelay"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_REUSEADDR),
+ "unable to reuseaddr"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNAVAILABLE_IP_FAMILY),
+ "unavailable ip family"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNINITIALIZED), "uninitialized"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNKNOWN_INFO_TYPE), "unknown info type"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNSUPPORTED_IP_FAMILY),
+ "unsupported ip family"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNSUPPORTED_METHOD), "unsupported method"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNSUPPORTED_PROTOCOL_FAMILY),
+ "unsupported protocol family"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_WRITE_TO_READ_ONLY_BIO),
+ "write to read only BIO"},
+ {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_WSASTARTUP), "WSAStartup"},
+ {0, NULL}
+};
+
+#endif
+
+int ERR_load_BIO_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+ if (ERR_func_error_string(BIO_str_functs[0].error) == NULL) {
+ ERR_load_strings_const(BIO_str_functs);
+ ERR_load_strings_const(BIO_str_reasons);
+ }
+#endif
+ return 1;
+}
diff --git a/contrib/libs/openssl/crypto/bio/bio_lib.c b/contrib/libs/openssl/crypto/bio/bio_lib.c
index a179377470..d2202e537b 100644
--- a/contrib/libs/openssl/crypto/bio/bio_lib.c
+++ b/contrib/libs/openssl/crypto/bio/bio_lib.c
@@ -1,786 +1,786 @@
-/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include <errno.h>
-#include <openssl/crypto.h>
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <openssl/crypto.h>
#include "bio_local.h"
-#include "internal/cryptlib.h"
-
-
-/*
- * Helper macro for the callback to determine whether an operator expects a
- * len parameter or not
- */
-#define HAS_LEN_OPER(o) ((o) == BIO_CB_READ || (o) == BIO_CB_WRITE || \
- (o) == BIO_CB_GETS)
-
-/*
- * Helper function to work out whether to call the new style callback or the old
- * one, and translate between the two.
- *
- * This has a long return type for consistency with the old callback. Similarly
- * for the "long" used for "inret"
- */
-static long bio_call_callback(BIO *b, int oper, const char *argp, size_t len,
- int argi, long argl, long inret, size_t *processed)
-{
- long ret;
- int bareoper;
-
- if (b->callback_ex != NULL)
- return b->callback_ex(b, oper, argp, len, argi, argl, inret, processed);
-
- /* Strip off any BIO_CB_RETURN flag */
- bareoper = oper & ~BIO_CB_RETURN;
-
- /*
- * We have an old style callback, so we will have to do nasty casts and
- * check for overflows.
- */
- if (HAS_LEN_OPER(bareoper)) {
- /* In this case |len| is set, and should be used instead of |argi| */
- if (len > INT_MAX)
- return -1;
-
- argi = (int)len;
- }
-
- if (inret > 0 && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) {
- if (*processed > INT_MAX)
- return -1;
- inret = *processed;
- }
-
- ret = b->callback(b, oper, argp, argi, argl, inret);
-
- if (ret > 0 && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) {
- *processed = (size_t)ret;
- ret = 1;
- }
-
- return ret;
-}
-
-BIO *BIO_new(const BIO_METHOD *method)
-{
- BIO *bio = OPENSSL_zalloc(sizeof(*bio));
-
- if (bio == NULL) {
- BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
-
- bio->method = method;
- bio->shutdown = 1;
- bio->references = 1;
-
- if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data))
- goto err;
-
- bio->lock = CRYPTO_THREAD_lock_new();
- if (bio->lock == NULL) {
- BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE);
- CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
- goto err;
- }
-
- if (method->create != NULL && !method->create(bio)) {
- BIOerr(BIO_F_BIO_NEW, ERR_R_INIT_FAIL);
- CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
- CRYPTO_THREAD_lock_free(bio->lock);
- goto err;
- }
- if (method->create == NULL)
- bio->init = 1;
-
- return bio;
-
-err:
- OPENSSL_free(bio);
- return NULL;
-}
-
-int BIO_free(BIO *a)
-{
- int ret;
-
- if (a == NULL)
- return 0;
-
- if (CRYPTO_DOWN_REF(&a->references, &ret, a->lock) <= 0)
- return 0;
-
- REF_PRINT_COUNT("BIO", a);
- if (ret > 0)
- return 1;
- REF_ASSERT_ISNT(ret < 0);
-
- if (a->callback != NULL || a->callback_ex != NULL) {
- ret = (int)bio_call_callback(a, BIO_CB_FREE, NULL, 0, 0, 0L, 1L, NULL);
- if (ret <= 0)
- return ret;
- }
-
- if ((a->method != NULL) && (a->method->destroy != NULL))
- a->method->destroy(a);
-
- CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
-
- CRYPTO_THREAD_lock_free(a->lock);
-
- OPENSSL_free(a);
-
- return 1;
-}
-
-void BIO_set_data(BIO *a, void *ptr)
-{
- a->ptr = ptr;
-}
-
-void *BIO_get_data(BIO *a)
-{
- return a->ptr;
-}
-
-void BIO_set_init(BIO *a, int init)
-{
- a->init = init;
-}
-
-int BIO_get_init(BIO *a)
-{
- return a->init;
-}
-
-void BIO_set_shutdown(BIO *a, int shut)
-{
- a->shutdown = shut;
-}
-
-int BIO_get_shutdown(BIO *a)
-{
- return a->shutdown;
-}
-
-void BIO_vfree(BIO *a)
-{
- BIO_free(a);
-}
-
-int BIO_up_ref(BIO *a)
-{
- int i;
-
- if (CRYPTO_UP_REF(&a->references, &i, a->lock) <= 0)
- return 0;
-
- REF_PRINT_COUNT("BIO", a);
- REF_ASSERT_ISNT(i < 2);
- return ((i > 1) ? 1 : 0);
-}
-
-void BIO_clear_flags(BIO *b, int flags)
-{
- b->flags &= ~flags;
-}
-
-int BIO_test_flags(const BIO *b, int flags)
-{
- return (b->flags & flags);
-}
-
-void BIO_set_flags(BIO *b, int flags)
-{
- b->flags |= flags;
-}
-
-BIO_callback_fn BIO_get_callback(const BIO *b)
-{
- return b->callback;
-}
-
-void BIO_set_callback(BIO *b, BIO_callback_fn cb)
-{
- b->callback = cb;
-}
-
-BIO_callback_fn_ex BIO_get_callback_ex(const BIO *b)
-{
- return b->callback_ex;
-}
-
-void BIO_set_callback_ex(BIO *b, BIO_callback_fn_ex cb)
-{
- b->callback_ex = cb;
-}
-
-void BIO_set_callback_arg(BIO *b, char *arg)
-{
- b->cb_arg = arg;
-}
-
-char *BIO_get_callback_arg(const BIO *b)
-{
- return b->cb_arg;
-}
-
-const char *BIO_method_name(const BIO *b)
-{
- return b->method->name;
-}
-
-int BIO_method_type(const BIO *b)
-{
- return b->method->type;
-}
-
-/*
- * This is essentially the same as BIO_read_ex() except that it allows
- * 0 or a negative value to indicate failure (retryable or not) in the return.
- * This is for compatibility with the old style BIO_read(), where existing code
- * may make assumptions about the return value that it might get.
- */
-static int bio_read_intern(BIO *b, void *data, size_t dlen, size_t *readbytes)
-{
- int ret;
-
- if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL)) {
- BIOerr(BIO_F_BIO_READ_INTERN, BIO_R_UNSUPPORTED_METHOD);
- return -2;
- }
-
- if ((b->callback != NULL || b->callback_ex != NULL) &&
- ((ret = (int)bio_call_callback(b, BIO_CB_READ, data, dlen, 0, 0L, 1L,
- NULL)) <= 0))
- return ret;
-
- if (!b->init) {
- BIOerr(BIO_F_BIO_READ_INTERN, BIO_R_UNINITIALIZED);
- return -2;
- }
-
- ret = b->method->bread(b, data, dlen, readbytes);
-
- if (ret > 0)
- b->num_read += (uint64_t)*readbytes;
-
- if (b->callback != NULL || b->callback_ex != NULL)
- ret = (int)bio_call_callback(b, BIO_CB_READ | BIO_CB_RETURN, data,
- dlen, 0, 0L, ret, readbytes);
-
- /* Shouldn't happen */
- if (ret > 0 && *readbytes > dlen) {
- BIOerr(BIO_F_BIO_READ_INTERN, ERR_R_INTERNAL_ERROR);
- return -1;
- }
-
- return ret;
-}
-
-int BIO_read(BIO *b, void *data, int dlen)
-{
- size_t readbytes;
- int ret;
-
- if (dlen < 0)
- return 0;
-
- ret = bio_read_intern(b, data, (size_t)dlen, &readbytes);
-
- if (ret > 0) {
- /* *readbytes should always be <= dlen */
- ret = (int)readbytes;
- }
-
- return ret;
-}
-
-int BIO_read_ex(BIO *b, void *data, size_t dlen, size_t *readbytes)
-{
- int ret;
-
- ret = bio_read_intern(b, data, dlen, readbytes);
-
- if (ret > 0)
- ret = 1;
- else
- ret = 0;
-
- return ret;
-}
-
-static int bio_write_intern(BIO *b, const void *data, size_t dlen,
- size_t *written)
-{
- int ret;
-
- if (b == NULL)
- return 0;
-
- if ((b->method == NULL) || (b->method->bwrite == NULL)) {
- BIOerr(BIO_F_BIO_WRITE_INTERN, BIO_R_UNSUPPORTED_METHOD);
- return -2;
- }
-
- if ((b->callback != NULL || b->callback_ex != NULL) &&
- ((ret = (int)bio_call_callback(b, BIO_CB_WRITE, data, dlen, 0, 0L, 1L,
- NULL)) <= 0))
- return ret;
-
- if (!b->init) {
- BIOerr(BIO_F_BIO_WRITE_INTERN, BIO_R_UNINITIALIZED);
- return -2;
- }
-
- ret = b->method->bwrite(b, data, dlen, written);
-
- if (ret > 0)
- b->num_write += (uint64_t)*written;
-
- if (b->callback != NULL || b->callback_ex != NULL)
- ret = (int)bio_call_callback(b, BIO_CB_WRITE | BIO_CB_RETURN, data,
- dlen, 0, 0L, ret, written);
-
- return ret;
-}
-
-int BIO_write(BIO *b, const void *data, int dlen)
-{
- size_t written;
- int ret;
-
- if (dlen < 0)
- return 0;
-
- ret = bio_write_intern(b, data, (size_t)dlen, &written);
-
- if (ret > 0) {
- /* *written should always be <= dlen */
- ret = (int)written;
- }
-
- return ret;
-}
-
-int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written)
-{
- int ret;
-
- ret = bio_write_intern(b, data, dlen, written);
-
- if (ret > 0)
- ret = 1;
- else
- ret = 0;
-
- return ret;
-}
-
-int BIO_puts(BIO *b, const char *buf)
-{
- int ret;
- size_t written = 0;
-
- if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL)) {
- BIOerr(BIO_F_BIO_PUTS, BIO_R_UNSUPPORTED_METHOD);
- return -2;
- }
-
- if (b->callback != NULL || b->callback_ex != NULL) {
- ret = (int)bio_call_callback(b, BIO_CB_PUTS, buf, 0, 0, 0L, 1L, NULL);
- if (ret <= 0)
- return ret;
- }
-
- if (!b->init) {
- BIOerr(BIO_F_BIO_PUTS, BIO_R_UNINITIALIZED);
- return -2;
- }
-
- ret = b->method->bputs(b, buf);
-
- if (ret > 0) {
- b->num_write += (uint64_t)ret;
- written = ret;
- ret = 1;
- }
-
- if (b->callback != NULL || b->callback_ex != NULL)
- ret = (int)bio_call_callback(b, BIO_CB_PUTS | BIO_CB_RETURN, buf, 0, 0,
- 0L, ret, &written);
-
- if (ret > 0) {
- if (written > INT_MAX) {
- BIOerr(BIO_F_BIO_PUTS, BIO_R_LENGTH_TOO_LONG);
- ret = -1;
- } else {
- ret = (int)written;
- }
- }
-
- return ret;
-}
-
-int BIO_gets(BIO *b, char *buf, int size)
-{
- int ret;
- size_t readbytes = 0;
-
- if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) {
- BIOerr(BIO_F_BIO_GETS, BIO_R_UNSUPPORTED_METHOD);
- return -2;
- }
-
- if (size < 0) {
- BIOerr(BIO_F_BIO_GETS, BIO_R_INVALID_ARGUMENT);
- return 0;
- }
-
- if (b->callback != NULL || b->callback_ex != NULL) {
- ret = (int)bio_call_callback(b, BIO_CB_GETS, buf, size, 0, 0L, 1, NULL);
- if (ret <= 0)
- return ret;
- }
-
- if (!b->init) {
- BIOerr(BIO_F_BIO_GETS, BIO_R_UNINITIALIZED);
- return -2;
- }
-
- ret = b->method->bgets(b, buf, size);
-
- if (ret > 0) {
- readbytes = ret;
- ret = 1;
- }
-
- if (b->callback != NULL || b->callback_ex != NULL)
- ret = (int)bio_call_callback(b, BIO_CB_GETS | BIO_CB_RETURN, buf, size,
- 0, 0L, ret, &readbytes);
-
- if (ret > 0) {
- /* Shouldn't happen */
- if (readbytes > (size_t)size)
- ret = -1;
- else
- ret = (int)readbytes;
- }
-
- return ret;
-}
-
-int BIO_indent(BIO *b, int indent, int max)
-{
- if (indent < 0)
- indent = 0;
- if (indent > max)
- indent = max;
- while (indent--)
- if (BIO_puts(b, " ") != 1)
- return 0;
- return 1;
-}
-
-long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
-{
- int i;
-
- i = iarg;
- return BIO_ctrl(b, cmd, larg, (char *)&i);
-}
-
-void *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
-{
- void *p = NULL;
-
- if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0)
- return NULL;
- else
- return p;
-}
-
-long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
-{
- long ret;
-
- if (b == NULL)
- return 0;
-
- if ((b->method == NULL) || (b->method->ctrl == NULL)) {
- BIOerr(BIO_F_BIO_CTRL, BIO_R_UNSUPPORTED_METHOD);
- return -2;
- }
-
- if (b->callback != NULL || b->callback_ex != NULL) {
- ret = bio_call_callback(b, BIO_CB_CTRL, parg, 0, cmd, larg, 1L, NULL);
- if (ret <= 0)
- return ret;
- }
-
- ret = b->method->ctrl(b, cmd, larg, parg);
-
- if (b->callback != NULL || b->callback_ex != NULL)
- ret = bio_call_callback(b, BIO_CB_CTRL | BIO_CB_RETURN, parg, 0, cmd,
- larg, ret, NULL);
-
- return ret;
-}
-
-long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
-{
- long ret;
-
- if (b == NULL)
- return 0;
-
- if ((b->method == NULL) || (b->method->callback_ctrl == NULL)
- || (cmd != BIO_CTRL_SET_CALLBACK)) {
- BIOerr(BIO_F_BIO_CALLBACK_CTRL, BIO_R_UNSUPPORTED_METHOD);
- return -2;
- }
-
- if (b->callback != NULL || b->callback_ex != NULL) {
- ret = bio_call_callback(b, BIO_CB_CTRL, (void *)&fp, 0, cmd, 0, 1L,
- NULL);
- if (ret <= 0)
- return ret;
- }
-
- ret = b->method->callback_ctrl(b, cmd, fp);
-
- if (b->callback != NULL || b->callback_ex != NULL)
- ret = bio_call_callback(b, BIO_CB_CTRL | BIO_CB_RETURN, (void *)&fp, 0,
- cmd, 0, ret, NULL);
-
- return ret;
-}
-
-/*
- * It is unfortunate to duplicate in functions what the BIO_(w)pending macros
- * do; but those macros have inappropriate return type, and for interfacing
- * from other programming languages, C macros aren't much of a help anyway.
- */
-size_t BIO_ctrl_pending(BIO *bio)
-{
- return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
-}
-
-size_t BIO_ctrl_wpending(BIO *bio)
-{
- return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
-}
-
-/* put the 'bio' on the end of b's list of operators */
-BIO *BIO_push(BIO *b, BIO *bio)
-{
- BIO *lb;
-
- if (b == NULL)
- return bio;
- lb = b;
- while (lb->next_bio != NULL)
- lb = lb->next_bio;
- lb->next_bio = bio;
- if (bio != NULL)
- bio->prev_bio = lb;
- /* called to do internal processing */
- BIO_ctrl(b, BIO_CTRL_PUSH, 0, lb);
- return b;
-}
-
-/* Remove the first and return the rest */
-BIO *BIO_pop(BIO *b)
-{
- BIO *ret;
-
- if (b == NULL)
- return NULL;
- ret = b->next_bio;
-
- BIO_ctrl(b, BIO_CTRL_POP, 0, b);
-
- if (b->prev_bio != NULL)
- b->prev_bio->next_bio = b->next_bio;
- if (b->next_bio != NULL)
- b->next_bio->prev_bio = b->prev_bio;
-
- b->next_bio = NULL;
- b->prev_bio = NULL;
- return ret;
-}
-
-BIO *BIO_get_retry_BIO(BIO *bio, int *reason)
-{
- BIO *b, *last;
-
- b = last = bio;
- for (;;) {
- if (!BIO_should_retry(b))
- break;
- last = b;
- b = b->next_bio;
- if (b == NULL)
- break;
- }
- if (reason != NULL)
- *reason = last->retry_reason;
- return last;
-}
-
-int BIO_get_retry_reason(BIO *bio)
-{
- return bio->retry_reason;
-}
-
-void BIO_set_retry_reason(BIO *bio, int reason)
-{
- bio->retry_reason = reason;
-}
-
-BIO *BIO_find_type(BIO *bio, int type)
-{
- int mt, mask;
-
- if (bio == NULL)
- return NULL;
- mask = type & 0xff;
- do {
- if (bio->method != NULL) {
- mt = bio->method->type;
-
- if (!mask) {
- if (mt & type)
- return bio;
- } else if (mt == type)
- return bio;
- }
- bio = bio->next_bio;
- } while (bio != NULL);
- return NULL;
-}
-
-BIO *BIO_next(BIO *b)
-{
- if (b == NULL)
- return NULL;
- return b->next_bio;
-}
-
-void BIO_set_next(BIO *b, BIO *next)
-{
- b->next_bio = next;
-}
-
-void BIO_free_all(BIO *bio)
-{
- BIO *b;
- int ref;
-
- while (bio != NULL) {
- b = bio;
- ref = b->references;
- bio = bio->next_bio;
- BIO_free(b);
- /* Since ref count > 1, don't free anyone else. */
- if (ref > 1)
- break;
- }
-}
-
-BIO *BIO_dup_chain(BIO *in)
-{
- BIO *ret = NULL, *eoc = NULL, *bio, *new_bio;
-
- for (bio = in; bio != NULL; bio = bio->next_bio) {
- if ((new_bio = BIO_new(bio->method)) == NULL)
- goto err;
- new_bio->callback = bio->callback;
- new_bio->callback_ex = bio->callback_ex;
- new_bio->cb_arg = bio->cb_arg;
- new_bio->init = bio->init;
- new_bio->shutdown = bio->shutdown;
- new_bio->flags = bio->flags;
-
- /* This will let SSL_s_sock() work with stdin/stdout */
- new_bio->num = bio->num;
-
- if (!BIO_dup_state(bio, (char *)new_bio)) {
- BIO_free(new_bio);
- goto err;
- }
-
- /* copy app data */
- if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new_bio->ex_data,
- &bio->ex_data)) {
- BIO_free(new_bio);
- goto err;
- }
-
- if (ret == NULL) {
- eoc = new_bio;
- ret = eoc;
- } else {
- BIO_push(eoc, new_bio);
- eoc = new_bio;
- }
- }
- return ret;
- err:
- BIO_free_all(ret);
-
- return NULL;
-}
-
-void BIO_copy_next_retry(BIO *b)
-{
- BIO_set_flags(b, BIO_get_retry_flags(b->next_bio));
- b->retry_reason = b->next_bio->retry_reason;
-}
-
-int BIO_set_ex_data(BIO *bio, int idx, void *data)
-{
- return CRYPTO_set_ex_data(&(bio->ex_data), idx, data);
-}
-
-void *BIO_get_ex_data(BIO *bio, int idx)
-{
- return CRYPTO_get_ex_data(&(bio->ex_data), idx);
-}
-
-uint64_t BIO_number_read(BIO *bio)
-{
- if (bio)
- return bio->num_read;
- return 0;
-}
-
-uint64_t BIO_number_written(BIO *bio)
-{
- if (bio)
- return bio->num_write;
- return 0;
-}
-
-void bio_free_ex_data(BIO *bio)
-{
- CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
-}
-
-void bio_cleanup(void)
-{
-#ifndef OPENSSL_NO_SOCK
- bio_sock_cleanup_int();
- CRYPTO_THREAD_lock_free(bio_lookup_lock);
- bio_lookup_lock = NULL;
-#endif
- CRYPTO_THREAD_lock_free(bio_type_lock);
- bio_type_lock = NULL;
-}
+#include "internal/cryptlib.h"
+
+
+/*
+ * Helper macro for the callback to determine whether an operator expects a
+ * len parameter or not
+ */
+#define HAS_LEN_OPER(o) ((o) == BIO_CB_READ || (o) == BIO_CB_WRITE || \
+ (o) == BIO_CB_GETS)
+
+/*
+ * Helper function to work out whether to call the new style callback or the old
+ * one, and translate between the two.
+ *
+ * This has a long return type for consistency with the old callback. Similarly
+ * for the "long" used for "inret"
+ */
+static long bio_call_callback(BIO *b, int oper, const char *argp, size_t len,
+ int argi, long argl, long inret, size_t *processed)
+{
+ long ret;
+ int bareoper;
+
+ if (b->callback_ex != NULL)
+ return b->callback_ex(b, oper, argp, len, argi, argl, inret, processed);
+
+ /* Strip off any BIO_CB_RETURN flag */
+ bareoper = oper & ~BIO_CB_RETURN;
+
+ /*
+ * We have an old style callback, so we will have to do nasty casts and
+ * check for overflows.
+ */
+ if (HAS_LEN_OPER(bareoper)) {
+ /* In this case |len| is set, and should be used instead of |argi| */
+ if (len > INT_MAX)
+ return -1;
+
+ argi = (int)len;
+ }
+
+ if (inret > 0 && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) {
+ if (*processed > INT_MAX)
+ return -1;
+ inret = *processed;
+ }
+
+ ret = b->callback(b, oper, argp, argi, argl, inret);
+
+ if (ret > 0 && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) {
+ *processed = (size_t)ret;
+ ret = 1;
+ }
+
+ return ret;
+}
+
+BIO *BIO_new(const BIO_METHOD *method)
+{
+ BIO *bio = OPENSSL_zalloc(sizeof(*bio));
+
+ if (bio == NULL) {
+ BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ bio->method = method;
+ bio->shutdown = 1;
+ bio->references = 1;
+
+ if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data))
+ goto err;
+
+ bio->lock = CRYPTO_THREAD_lock_new();
+ if (bio->lock == NULL) {
+ BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE);
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
+ goto err;
+ }
+
+ if (method->create != NULL && !method->create(bio)) {
+ BIOerr(BIO_F_BIO_NEW, ERR_R_INIT_FAIL);
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
+ CRYPTO_THREAD_lock_free(bio->lock);
+ goto err;
+ }
+ if (method->create == NULL)
+ bio->init = 1;
+
+ return bio;
+
+err:
+ OPENSSL_free(bio);
+ return NULL;
+}
+
+int BIO_free(BIO *a)
+{
+ int ret;
+
+ if (a == NULL)
+ return 0;
+
+ if (CRYPTO_DOWN_REF(&a->references, &ret, a->lock) <= 0)
+ return 0;
+
+ REF_PRINT_COUNT("BIO", a);
+ if (ret > 0)
+ return 1;
+ REF_ASSERT_ISNT(ret < 0);
+
+ if (a->callback != NULL || a->callback_ex != NULL) {
+ ret = (int)bio_call_callback(a, BIO_CB_FREE, NULL, 0, 0, 0L, 1L, NULL);
+ if (ret <= 0)
+ return ret;
+ }
+
+ if ((a->method != NULL) && (a->method->destroy != NULL))
+ a->method->destroy(a);
+
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
+
+ CRYPTO_THREAD_lock_free(a->lock);
+
+ OPENSSL_free(a);
+
+ return 1;
+}
+
+void BIO_set_data(BIO *a, void *ptr)
+{
+ a->ptr = ptr;
+}
+
+void *BIO_get_data(BIO *a)
+{
+ return a->ptr;
+}
+
+void BIO_set_init(BIO *a, int init)
+{
+ a->init = init;
+}
+
+int BIO_get_init(BIO *a)
+{
+ return a->init;
+}
+
+void BIO_set_shutdown(BIO *a, int shut)
+{
+ a->shutdown = shut;
+}
+
+int BIO_get_shutdown(BIO *a)
+{
+ return a->shutdown;
+}
+
+void BIO_vfree(BIO *a)
+{
+ BIO_free(a);
+}
+
+int BIO_up_ref(BIO *a)
+{
+ int i;
+
+ if (CRYPTO_UP_REF(&a->references, &i, a->lock) <= 0)
+ return 0;
+
+ REF_PRINT_COUNT("BIO", a);
+ REF_ASSERT_ISNT(i < 2);
+ return ((i > 1) ? 1 : 0);
+}
+
+void BIO_clear_flags(BIO *b, int flags)
+{
+ b->flags &= ~flags;
+}
+
+int BIO_test_flags(const BIO *b, int flags)
+{
+ return (b->flags & flags);
+}
+
+void BIO_set_flags(BIO *b, int flags)
+{
+ b->flags |= flags;
+}
+
+BIO_callback_fn BIO_get_callback(const BIO *b)
+{
+ return b->callback;
+}
+
+void BIO_set_callback(BIO *b, BIO_callback_fn cb)
+{
+ b->callback = cb;
+}
+
+BIO_callback_fn_ex BIO_get_callback_ex(const BIO *b)
+{
+ return b->callback_ex;
+}
+
+void BIO_set_callback_ex(BIO *b, BIO_callback_fn_ex cb)
+{
+ b->callback_ex = cb;
+}
+
+void BIO_set_callback_arg(BIO *b, char *arg)
+{
+ b->cb_arg = arg;
+}
+
+char *BIO_get_callback_arg(const BIO *b)
+{
+ return b->cb_arg;
+}
+
+const char *BIO_method_name(const BIO *b)
+{
+ return b->method->name;
+}
+
+int BIO_method_type(const BIO *b)
+{
+ return b->method->type;
+}
+
+/*
+ * This is essentially the same as BIO_read_ex() except that it allows
+ * 0 or a negative value to indicate failure (retryable or not) in the return.
+ * This is for compatibility with the old style BIO_read(), where existing code
+ * may make assumptions about the return value that it might get.
+ */
+static int bio_read_intern(BIO *b, void *data, size_t dlen, size_t *readbytes)
+{
+ int ret;
+
+ if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL)) {
+ BIOerr(BIO_F_BIO_READ_INTERN, BIO_R_UNSUPPORTED_METHOD);
+ return -2;
+ }
+
+ if ((b->callback != NULL || b->callback_ex != NULL) &&
+ ((ret = (int)bio_call_callback(b, BIO_CB_READ, data, dlen, 0, 0L, 1L,
+ NULL)) <= 0))
+ return ret;
+
+ if (!b->init) {
+ BIOerr(BIO_F_BIO_READ_INTERN, BIO_R_UNINITIALIZED);
+ return -2;
+ }
+
+ ret = b->method->bread(b, data, dlen, readbytes);
+
+ if (ret > 0)
+ b->num_read += (uint64_t)*readbytes;
+
+ if (b->callback != NULL || b->callback_ex != NULL)
+ ret = (int)bio_call_callback(b, BIO_CB_READ | BIO_CB_RETURN, data,
+ dlen, 0, 0L, ret, readbytes);
+
+ /* Shouldn't happen */
+ if (ret > 0 && *readbytes > dlen) {
+ BIOerr(BIO_F_BIO_READ_INTERN, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+
+ return ret;
+}
+
+int BIO_read(BIO *b, void *data, int dlen)
+{
+ size_t readbytes;
+ int ret;
+
+ if (dlen < 0)
+ return 0;
+
+ ret = bio_read_intern(b, data, (size_t)dlen, &readbytes);
+
+ if (ret > 0) {
+ /* *readbytes should always be <= dlen */
+ ret = (int)readbytes;
+ }
+
+ return ret;
+}
+
+int BIO_read_ex(BIO *b, void *data, size_t dlen, size_t *readbytes)
+{
+ int ret;
+
+ ret = bio_read_intern(b, data, dlen, readbytes);
+
+ if (ret > 0)
+ ret = 1;
+ else
+ ret = 0;
+
+ return ret;
+}
+
+static int bio_write_intern(BIO *b, const void *data, size_t dlen,
+ size_t *written)
+{
+ int ret;
+
+ if (b == NULL)
+ return 0;
+
+ if ((b->method == NULL) || (b->method->bwrite == NULL)) {
+ BIOerr(BIO_F_BIO_WRITE_INTERN, BIO_R_UNSUPPORTED_METHOD);
+ return -2;
+ }
+
+ if ((b->callback != NULL || b->callback_ex != NULL) &&
+ ((ret = (int)bio_call_callback(b, BIO_CB_WRITE, data, dlen, 0, 0L, 1L,
+ NULL)) <= 0))
+ return ret;
+
+ if (!b->init) {
+ BIOerr(BIO_F_BIO_WRITE_INTERN, BIO_R_UNINITIALIZED);
+ return -2;
+ }
+
+ ret = b->method->bwrite(b, data, dlen, written);
+
+ if (ret > 0)
+ b->num_write += (uint64_t)*written;
+
+ if (b->callback != NULL || b->callback_ex != NULL)
+ ret = (int)bio_call_callback(b, BIO_CB_WRITE | BIO_CB_RETURN, data,
+ dlen, 0, 0L, ret, written);
+
+ return ret;
+}
+
+int BIO_write(BIO *b, const void *data, int dlen)
+{
+ size_t written;
+ int ret;
+
+ if (dlen < 0)
+ return 0;
+
+ ret = bio_write_intern(b, data, (size_t)dlen, &written);
+
+ if (ret > 0) {
+ /* *written should always be <= dlen */
+ ret = (int)written;
+ }
+
+ return ret;
+}
+
+int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written)
+{
+ int ret;
+
+ ret = bio_write_intern(b, data, dlen, written);
+
+ if (ret > 0)
+ ret = 1;
+ else
+ ret = 0;
+
+ return ret;
+}
+
+int BIO_puts(BIO *b, const char *buf)
+{
+ int ret;
+ size_t written = 0;
+
+ if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL)) {
+ BIOerr(BIO_F_BIO_PUTS, BIO_R_UNSUPPORTED_METHOD);
+ return -2;
+ }
+
+ if (b->callback != NULL || b->callback_ex != NULL) {
+ ret = (int)bio_call_callback(b, BIO_CB_PUTS, buf, 0, 0, 0L, 1L, NULL);
+ if (ret <= 0)
+ return ret;
+ }
+
+ if (!b->init) {
+ BIOerr(BIO_F_BIO_PUTS, BIO_R_UNINITIALIZED);
+ return -2;
+ }
+
+ ret = b->method->bputs(b, buf);
+
+ if (ret > 0) {
+ b->num_write += (uint64_t)ret;
+ written = ret;
+ ret = 1;
+ }
+
+ if (b->callback != NULL || b->callback_ex != NULL)
+ ret = (int)bio_call_callback(b, BIO_CB_PUTS | BIO_CB_RETURN, buf, 0, 0,
+ 0L, ret, &written);
+
+ if (ret > 0) {
+ if (written > INT_MAX) {
+ BIOerr(BIO_F_BIO_PUTS, BIO_R_LENGTH_TOO_LONG);
+ ret = -1;
+ } else {
+ ret = (int)written;
+ }
+ }
+
+ return ret;
+}
+
+int BIO_gets(BIO *b, char *buf, int size)
+{
+ int ret;
+ size_t readbytes = 0;
+
+ if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) {
+ BIOerr(BIO_F_BIO_GETS, BIO_R_UNSUPPORTED_METHOD);
+ return -2;
+ }
+
+ if (size < 0) {
+ BIOerr(BIO_F_BIO_GETS, BIO_R_INVALID_ARGUMENT);
+ return 0;
+ }
+
+ if (b->callback != NULL || b->callback_ex != NULL) {
+ ret = (int)bio_call_callback(b, BIO_CB_GETS, buf, size, 0, 0L, 1, NULL);
+ if (ret <= 0)
+ return ret;
+ }
+
+ if (!b->init) {
+ BIOerr(BIO_F_BIO_GETS, BIO_R_UNINITIALIZED);
+ return -2;
+ }
+
+ ret = b->method->bgets(b, buf, size);
+
+ if (ret > 0) {
+ readbytes = ret;
+ ret = 1;
+ }
+
+ if (b->callback != NULL || b->callback_ex != NULL)
+ ret = (int)bio_call_callback(b, BIO_CB_GETS | BIO_CB_RETURN, buf, size,
+ 0, 0L, ret, &readbytes);
+
+ if (ret > 0) {
+ /* Shouldn't happen */
+ if (readbytes > (size_t)size)
+ ret = -1;
+ else
+ ret = (int)readbytes;
+ }
+
+ return ret;
+}
+
+int BIO_indent(BIO *b, int indent, int max)
+{
+ if (indent < 0)
+ indent = 0;
+ if (indent > max)
+ indent = max;
+ while (indent--)
+ if (BIO_puts(b, " ") != 1)
+ return 0;
+ return 1;
+}
+
+long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
+{
+ int i;
+
+ i = iarg;
+ return BIO_ctrl(b, cmd, larg, (char *)&i);
+}
+
+void *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
+{
+ void *p = NULL;
+
+ if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0)
+ return NULL;
+ else
+ return p;
+}
+
+long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
+{
+ long ret;
+
+ if (b == NULL)
+ return 0;
+
+ if ((b->method == NULL) || (b->method->ctrl == NULL)) {
+ BIOerr(BIO_F_BIO_CTRL, BIO_R_UNSUPPORTED_METHOD);
+ return -2;
+ }
+
+ if (b->callback != NULL || b->callback_ex != NULL) {
+ ret = bio_call_callback(b, BIO_CB_CTRL, parg, 0, cmd, larg, 1L, NULL);
+ if (ret <= 0)
+ return ret;
+ }
+
+ ret = b->method->ctrl(b, cmd, larg, parg);
+
+ if (b->callback != NULL || b->callback_ex != NULL)
+ ret = bio_call_callback(b, BIO_CB_CTRL | BIO_CB_RETURN, parg, 0, cmd,
+ larg, ret, NULL);
+
+ return ret;
+}
+
+long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
+{
+ long ret;
+
+ if (b == NULL)
+ return 0;
+
+ if ((b->method == NULL) || (b->method->callback_ctrl == NULL)
+ || (cmd != BIO_CTRL_SET_CALLBACK)) {
+ BIOerr(BIO_F_BIO_CALLBACK_CTRL, BIO_R_UNSUPPORTED_METHOD);
+ return -2;
+ }
+
+ if (b->callback != NULL || b->callback_ex != NULL) {
+ ret = bio_call_callback(b, BIO_CB_CTRL, (void *)&fp, 0, cmd, 0, 1L,
+ NULL);
+ if (ret <= 0)
+ return ret;
+ }
+
+ ret = b->method->callback_ctrl(b, cmd, fp);
+
+ if (b->callback != NULL || b->callback_ex != NULL)
+ ret = bio_call_callback(b, BIO_CB_CTRL | BIO_CB_RETURN, (void *)&fp, 0,
+ cmd, 0, ret, NULL);
+
+ return ret;
+}
+
+/*
+ * It is unfortunate to duplicate in functions what the BIO_(w)pending macros
+ * do; but those macros have inappropriate return type, and for interfacing
+ * from other programming languages, C macros aren't much of a help anyway.
+ */
+size_t BIO_ctrl_pending(BIO *bio)
+{
+ return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
+}
+
+size_t BIO_ctrl_wpending(BIO *bio)
+{
+ return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
+}
+
+/* put the 'bio' on the end of b's list of operators */
+BIO *BIO_push(BIO *b, BIO *bio)
+{
+ BIO *lb;
+
+ if (b == NULL)
+ return bio;
+ lb = b;
+ while (lb->next_bio != NULL)
+ lb = lb->next_bio;
+ lb->next_bio = bio;
+ if (bio != NULL)
+ bio->prev_bio = lb;
+ /* called to do internal processing */
+ BIO_ctrl(b, BIO_CTRL_PUSH, 0, lb);
+ return b;
+}
+
+/* Remove the first and return the rest */
+BIO *BIO_pop(BIO *b)
+{
+ BIO *ret;
+
+ if (b == NULL)
+ return NULL;
+ ret = b->next_bio;
+
+ BIO_ctrl(b, BIO_CTRL_POP, 0, b);
+
+ if (b->prev_bio != NULL)
+ b->prev_bio->next_bio = b->next_bio;
+ if (b->next_bio != NULL)
+ b->next_bio->prev_bio = b->prev_bio;
+
+ b->next_bio = NULL;
+ b->prev_bio = NULL;
+ return ret;
+}
+
+BIO *BIO_get_retry_BIO(BIO *bio, int *reason)
+{
+ BIO *b, *last;
+
+ b = last = bio;
+ for (;;) {
+ if (!BIO_should_retry(b))
+ break;
+ last = b;
+ b = b->next_bio;
+ if (b == NULL)
+ break;
+ }
+ if (reason != NULL)
+ *reason = last->retry_reason;
+ return last;
+}
+
+int BIO_get_retry_reason(BIO *bio)
+{
+ return bio->retry_reason;
+}
+
+void BIO_set_retry_reason(BIO *bio, int reason)
+{
+ bio->retry_reason = reason;
+}
+
+BIO *BIO_find_type(BIO *bio, int type)
+{
+ int mt, mask;
+
+ if (bio == NULL)
+ return NULL;
+ mask = type & 0xff;
+ do {
+ if (bio->method != NULL) {
+ mt = bio->method->type;
+
+ if (!mask) {
+ if (mt & type)
+ return bio;
+ } else if (mt == type)
+ return bio;
+ }
+ bio = bio->next_bio;
+ } while (bio != NULL);
+ return NULL;
+}
+
+BIO *BIO_next(BIO *b)
+{
+ if (b == NULL)
+ return NULL;
+ return b->next_bio;
+}
+
+void BIO_set_next(BIO *b, BIO *next)
+{
+ b->next_bio = next;
+}
+
+void BIO_free_all(BIO *bio)
+{
+ BIO *b;
+ int ref;
+
+ while (bio != NULL) {
+ b = bio;
+ ref = b->references;
+ bio = bio->next_bio;
+ BIO_free(b);
+ /* Since ref count > 1, don't free anyone else. */
+ if (ref > 1)
+ break;
+ }
+}
+
+BIO *BIO_dup_chain(BIO *in)
+{
+ BIO *ret = NULL, *eoc = NULL, *bio, *new_bio;
+
+ for (bio = in; bio != NULL; bio = bio->next_bio) {
+ if ((new_bio = BIO_new(bio->method)) == NULL)
+ goto err;
+ new_bio->callback = bio->callback;
+ new_bio->callback_ex = bio->callback_ex;
+ new_bio->cb_arg = bio->cb_arg;
+ new_bio->init = bio->init;
+ new_bio->shutdown = bio->shutdown;
+ new_bio->flags = bio->flags;
+
+ /* This will let SSL_s_sock() work with stdin/stdout */
+ new_bio->num = bio->num;
+
+ if (!BIO_dup_state(bio, (char *)new_bio)) {
+ BIO_free(new_bio);
+ goto err;
+ }
+
+ /* copy app data */
+ if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new_bio->ex_data,
+ &bio->ex_data)) {
+ BIO_free(new_bio);
+ goto err;
+ }
+
+ if (ret == NULL) {
+ eoc = new_bio;
+ ret = eoc;
+ } else {
+ BIO_push(eoc, new_bio);
+ eoc = new_bio;
+ }
+ }
+ return ret;
+ err:
+ BIO_free_all(ret);
+
+ return NULL;
+}
+
+void BIO_copy_next_retry(BIO *b)
+{
+ BIO_set_flags(b, BIO_get_retry_flags(b->next_bio));
+ b->retry_reason = b->next_bio->retry_reason;
+}
+
+int BIO_set_ex_data(BIO *bio, int idx, void *data)
+{
+ return CRYPTO_set_ex_data(&(bio->ex_data), idx, data);
+}
+
+void *BIO_get_ex_data(BIO *bio, int idx)
+{
+ return CRYPTO_get_ex_data(&(bio->ex_data), idx);
+}
+
+uint64_t BIO_number_read(BIO *bio)
+{
+ if (bio)
+ return bio->num_read;
+ return 0;
+}
+
+uint64_t BIO_number_written(BIO *bio)
+{
+ if (bio)
+ return bio->num_write;
+ return 0;
+}
+
+void bio_free_ex_data(BIO *bio)
+{
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
+}
+
+void bio_cleanup(void)
+{
+#ifndef OPENSSL_NO_SOCK
+ bio_sock_cleanup_int();
+ CRYPTO_THREAD_lock_free(bio_lookup_lock);
+ bio_lookup_lock = NULL;
+#endif
+ CRYPTO_THREAD_lock_free(bio_type_lock);
+ bio_type_lock = NULL;
+}
diff --git a/contrib/libs/openssl/crypto/bio/bio_meth.c b/contrib/libs/openssl/crypto/bio/bio_meth.c
index 9da4f51bf9..da11646192 100644
--- a/contrib/libs/openssl/crypto/bio/bio_meth.c
+++ b/contrib/libs/openssl/crypto/bio/bio_meth.c
@@ -1,220 +1,220 @@
-/*
- * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
+/*
+ * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
#include "bio_local.h"
-#include "internal/thread_once.h"
-
-CRYPTO_RWLOCK *bio_type_lock = NULL;
-static CRYPTO_ONCE bio_type_init = CRYPTO_ONCE_STATIC_INIT;
-
-DEFINE_RUN_ONCE_STATIC(do_bio_type_init)
-{
- bio_type_lock = CRYPTO_THREAD_lock_new();
- return bio_type_lock != NULL;
-}
-
-int BIO_get_new_index(void)
-{
- static CRYPTO_REF_COUNT bio_count = BIO_TYPE_START;
- int newval;
-
- if (!RUN_ONCE(&bio_type_init, do_bio_type_init)) {
- BIOerr(BIO_F_BIO_GET_NEW_INDEX, ERR_R_MALLOC_FAILURE);
- return -1;
- }
- if (!CRYPTO_UP_REF(&bio_count, &newval, bio_type_lock))
- return -1;
- return newval;
-}
-
-BIO_METHOD *BIO_meth_new(int type, const char *name)
-{
- BIO_METHOD *biom = OPENSSL_zalloc(sizeof(BIO_METHOD));
-
- if (biom == NULL
- || (biom->name = OPENSSL_strdup(name)) == NULL) {
- OPENSSL_free(biom);
- BIOerr(BIO_F_BIO_METH_NEW, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- biom->type = type;
- return biom;
-}
-
-void BIO_meth_free(BIO_METHOD *biom)
-{
- if (biom != NULL) {
- OPENSSL_free(biom->name);
- OPENSSL_free(biom);
- }
-}
-
-int (*BIO_meth_get_write(const BIO_METHOD *biom)) (BIO *, const char *, int)
-{
- return biom->bwrite_old;
-}
-
-int (*BIO_meth_get_write_ex(const BIO_METHOD *biom)) (BIO *, const char *, size_t,
- size_t *)
-{
- return biom->bwrite;
-}
-
-/* Conversion for old style bwrite to new style */
-int bwrite_conv(BIO *bio, const char *data, size_t datal, size_t *written)
-{
- int ret;
-
- if (datal > INT_MAX)
- datal = INT_MAX;
-
- ret = bio->method->bwrite_old(bio, data, (int)datal);
-
- if (ret <= 0) {
- *written = 0;
- return ret;
- }
-
- *written = (size_t)ret;
-
- return 1;
-}
-
-int BIO_meth_set_write(BIO_METHOD *biom,
- int (*bwrite) (BIO *, const char *, int))
-{
- biom->bwrite_old = bwrite;
- biom->bwrite = bwrite_conv;
- return 1;
-}
-
-int BIO_meth_set_write_ex(BIO_METHOD *biom,
- int (*bwrite) (BIO *, const char *, size_t, size_t *))
-{
- biom->bwrite_old = NULL;
- biom->bwrite = bwrite;
- return 1;
-}
-
-int (*BIO_meth_get_read(const BIO_METHOD *biom)) (BIO *, char *, int)
-{
- return biom->bread_old;
-}
-
-int (*BIO_meth_get_read_ex(const BIO_METHOD *biom)) (BIO *, char *, size_t, size_t *)
-{
- return biom->bread;
-}
-
-/* Conversion for old style bread to new style */
-int bread_conv(BIO *bio, char *data, size_t datal, size_t *readbytes)
-{
- int ret;
-
- if (datal > INT_MAX)
- datal = INT_MAX;
-
- ret = bio->method->bread_old(bio, data, (int)datal);
-
- if (ret <= 0) {
- *readbytes = 0;
- return ret;
- }
-
- *readbytes = (size_t)ret;
-
- return 1;
-}
-
-int BIO_meth_set_read(BIO_METHOD *biom,
- int (*bread) (BIO *, char *, int))
-{
- biom->bread_old = bread;
- biom->bread = bread_conv;
- return 1;
-}
-
-int BIO_meth_set_read_ex(BIO_METHOD *biom,
- int (*bread) (BIO *, char *, size_t, size_t *))
-{
- biom->bread_old = NULL;
- biom->bread = bread;
- return 1;
-}
-
-int (*BIO_meth_get_puts(const BIO_METHOD *biom)) (BIO *, const char *)
-{
- return biom->bputs;
-}
-
-int BIO_meth_set_puts(BIO_METHOD *biom,
- int (*bputs) (BIO *, const char *))
-{
- biom->bputs = bputs;
- return 1;
-}
-
-int (*BIO_meth_get_gets(const BIO_METHOD *biom)) (BIO *, char *, int)
-{
- return biom->bgets;
-}
-
-int BIO_meth_set_gets(BIO_METHOD *biom,
- int (*bgets) (BIO *, char *, int))
-{
- biom->bgets = bgets;
- return 1;
-}
-
-long (*BIO_meth_get_ctrl(const BIO_METHOD *biom)) (BIO *, int, long, void *)
-{
- return biom->ctrl;
-}
-
-int BIO_meth_set_ctrl(BIO_METHOD *biom,
- long (*ctrl) (BIO *, int, long, void *))
-{
- biom->ctrl = ctrl;
- return 1;
-}
-
-int (*BIO_meth_get_create(const BIO_METHOD *biom)) (BIO *)
-{
- return biom->create;
-}
-
-int BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *))
-{
- biom->create = create;
- return 1;
-}
-
-int (*BIO_meth_get_destroy(const BIO_METHOD *biom)) (BIO *)
-{
- return biom->destroy;
-}
-
-int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *))
-{
- biom->destroy = destroy;
- return 1;
-}
-
-long (*BIO_meth_get_callback_ctrl(const BIO_METHOD *biom)) (BIO *, int, BIO_info_cb *)
-{
- return biom->callback_ctrl;
-}
-
-int BIO_meth_set_callback_ctrl(BIO_METHOD *biom,
- long (*callback_ctrl) (BIO *, int,
- BIO_info_cb *))
-{
- biom->callback_ctrl = callback_ctrl;
- return 1;
-}
+#include "internal/thread_once.h"
+
+CRYPTO_RWLOCK *bio_type_lock = NULL;
+static CRYPTO_ONCE bio_type_init = CRYPTO_ONCE_STATIC_INIT;
+
+DEFINE_RUN_ONCE_STATIC(do_bio_type_init)
+{
+ bio_type_lock = CRYPTO_THREAD_lock_new();
+ return bio_type_lock != NULL;
+}
+
+int BIO_get_new_index(void)
+{
+ static CRYPTO_REF_COUNT bio_count = BIO_TYPE_START;
+ int newval;
+
+ if (!RUN_ONCE(&bio_type_init, do_bio_type_init)) {
+ BIOerr(BIO_F_BIO_GET_NEW_INDEX, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ if (!CRYPTO_UP_REF(&bio_count, &newval, bio_type_lock))
+ return -1;
+ return newval;
+}
+
+BIO_METHOD *BIO_meth_new(int type, const char *name)
+{
+ BIO_METHOD *biom = OPENSSL_zalloc(sizeof(BIO_METHOD));
+
+ if (biom == NULL
+ || (biom->name = OPENSSL_strdup(name)) == NULL) {
+ OPENSSL_free(biom);
+ BIOerr(BIO_F_BIO_METH_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ biom->type = type;
+ return biom;
+}
+
+void BIO_meth_free(BIO_METHOD *biom)
+{
+ if (biom != NULL) {
+ OPENSSL_free(biom->name);
+ OPENSSL_free(biom);
+ }
+}
+
+int (*BIO_meth_get_write(const BIO_METHOD *biom)) (BIO *, const char *, int)
+{
+ return biom->bwrite_old;
+}
+
+int (*BIO_meth_get_write_ex(const BIO_METHOD *biom)) (BIO *, const char *, size_t,
+ size_t *)
+{
+ return biom->bwrite;
+}
+
+/* Conversion for old style bwrite to new style */
+int bwrite_conv(BIO *bio, const char *data, size_t datal, size_t *written)
+{
+ int ret;
+
+ if (datal > INT_MAX)
+ datal = INT_MAX;
+
+ ret = bio->method->bwrite_old(bio, data, (int)datal);
+
+ if (ret <= 0) {
+ *written = 0;
+ return ret;
+ }
+
+ *written = (size_t)ret;
+
+ return 1;
+}
+
+int BIO_meth_set_write(BIO_METHOD *biom,
+ int (*bwrite) (BIO *, const char *, int))
+{
+ biom->bwrite_old = bwrite;
+ biom->bwrite = bwrite_conv;
+ return 1;
+}
+
+int BIO_meth_set_write_ex(BIO_METHOD *biom,
+ int (*bwrite) (BIO *, const char *, size_t, size_t *))
+{
+ biom->bwrite_old = NULL;
+ biom->bwrite = bwrite;
+ return 1;
+}
+
+int (*BIO_meth_get_read(const BIO_METHOD *biom)) (BIO *, char *, int)
+{
+ return biom->bread_old;
+}
+
+int (*BIO_meth_get_read_ex(const BIO_METHOD *biom)) (BIO *, char *, size_t, size_t *)
+{
+ return biom->bread;
+}
+
+/* Conversion for old style bread to new style */
+int bread_conv(BIO *bio, char *data, size_t datal, size_t *readbytes)
+{
+ int ret;
+
+ if (datal > INT_MAX)
+ datal = INT_MAX;
+
+ ret = bio->method->bread_old(bio, data, (int)datal);
+
+ if (ret <= 0) {
+ *readbytes = 0;
+ return ret;
+ }
+
+ *readbytes = (size_t)ret;
+
+ return 1;
+}
+
+int BIO_meth_set_read(BIO_METHOD *biom,
+ int (*bread) (BIO *, char *, int))
+{
+ biom->bread_old = bread;
+ biom->bread = bread_conv;
+ return 1;
+}
+
+int BIO_meth_set_read_ex(BIO_METHOD *biom,
+ int (*bread) (BIO *, char *, size_t, size_t *))
+{
+ biom->bread_old = NULL;
+ biom->bread = bread;
+ return 1;
+}
+
+int (*BIO_meth_get_puts(const BIO_METHOD *biom)) (BIO *, const char *)
+{
+ return biom->bputs;
+}
+
+int BIO_meth_set_puts(BIO_METHOD *biom,
+ int (*bputs) (BIO *, const char *))
+{
+ biom->bputs = bputs;
+ return 1;
+}
+
+int (*BIO_meth_get_gets(const BIO_METHOD *biom)) (BIO *, char *, int)
+{
+ return biom->bgets;
+}
+
+int BIO_meth_set_gets(BIO_METHOD *biom,
+ int (*bgets) (BIO *, char *, int))
+{
+ biom->bgets = bgets;
+ return 1;
+}
+
+long (*BIO_meth_get_ctrl(const BIO_METHOD *biom)) (BIO *, int, long, void *)
+{
+ return biom->ctrl;
+}
+
+int BIO_meth_set_ctrl(BIO_METHOD *biom,
+ long (*ctrl) (BIO *, int, long, void *))
+{
+ biom->ctrl = ctrl;
+ return 1;
+}
+
+int (*BIO_meth_get_create(const BIO_METHOD *biom)) (BIO *)
+{
+ return biom->create;
+}
+
+int BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *))
+{
+ biom->create = create;
+ return 1;
+}
+
+int (*BIO_meth_get_destroy(const BIO_METHOD *biom)) (BIO *)
+{
+ return biom->destroy;
+}
+
+int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *))
+{
+ biom->destroy = destroy;
+ return 1;
+}
+
+long (*BIO_meth_get_callback_ctrl(const BIO_METHOD *biom)) (BIO *, int, BIO_info_cb *)
+{
+ return biom->callback_ctrl;
+}
+
+int BIO_meth_set_callback_ctrl(BIO_METHOD *biom,
+ long (*callback_ctrl) (BIO *, int,
+ BIO_info_cb *))
+{
+ biom->callback_ctrl = callback_ctrl;
+ return 1;
+}
diff --git a/contrib/libs/openssl/crypto/bio/bss_acpt.c b/contrib/libs/openssl/crypto/bio/bss_acpt.c
index 29b2b45749..4461eae233 100644
--- a/contrib/libs/openssl/crypto/bio/bss_acpt.c
+++ b/contrib/libs/openssl/crypto/bio/bss_acpt.c
@@ -1,568 +1,568 @@
-/*
+/*
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include <errno.h>
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <errno.h>
#include "bio_local.h"
-
-#ifndef OPENSSL_NO_SOCK
-
-typedef struct bio_accept_st {
- int state;
- int accept_family;
- int bind_mode; /* Socket mode for BIO_listen */
- int accepted_mode; /* Socket mode for BIO_accept (set on accepted sock) */
- char *param_addr;
- char *param_serv;
-
- int accept_sock;
-
- BIO_ADDRINFO *addr_first;
- const BIO_ADDRINFO *addr_iter;
- BIO_ADDR cache_accepting_addr; /* Useful if we asked for port 0 */
- char *cache_accepting_name, *cache_accepting_serv;
- BIO_ADDR cache_peer_addr;
- char *cache_peer_name, *cache_peer_serv;
-
- BIO *bio_chain;
-} BIO_ACCEPT;
-
-static int acpt_write(BIO *h, const char *buf, int num);
-static int acpt_read(BIO *h, char *buf, int size);
-static int acpt_puts(BIO *h, const char *str);
-static long acpt_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-static int acpt_new(BIO *h);
-static int acpt_free(BIO *data);
-static int acpt_state(BIO *b, BIO_ACCEPT *c);
-static void acpt_close_socket(BIO *data);
-static BIO_ACCEPT *BIO_ACCEPT_new(void);
-static void BIO_ACCEPT_free(BIO_ACCEPT *a);
-
-# define ACPT_S_BEFORE 1
-# define ACPT_S_GET_ADDR 2
-# define ACPT_S_CREATE_SOCKET 3
-# define ACPT_S_LISTEN 4
-# define ACPT_S_ACCEPT 5
-# define ACPT_S_OK 6
-
-static const BIO_METHOD methods_acceptp = {
- BIO_TYPE_ACCEPT,
- "socket accept",
- /* TODO: Convert to new style write function */
- bwrite_conv,
- acpt_write,
- /* TODO: Convert to new style read function */
- bread_conv,
- acpt_read,
- acpt_puts,
- NULL, /* connect_gets, */
- acpt_ctrl,
- acpt_new,
- acpt_free,
- NULL, /* connect_callback_ctrl */
-};
-
-const BIO_METHOD *BIO_s_accept(void)
-{
- return &methods_acceptp;
-}
-
-static int acpt_new(BIO *bi)
-{
- BIO_ACCEPT *ba;
-
- bi->init = 0;
- bi->num = (int)INVALID_SOCKET;
- bi->flags = 0;
- if ((ba = BIO_ACCEPT_new()) == NULL)
- return 0;
- bi->ptr = (char *)ba;
- ba->state = ACPT_S_BEFORE;
- bi->shutdown = 1;
- return 1;
-}
-
-static BIO_ACCEPT *BIO_ACCEPT_new(void)
-{
- BIO_ACCEPT *ret;
-
- if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
- BIOerr(BIO_F_BIO_ACCEPT_NEW, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- ret->accept_family = BIO_FAMILY_IPANY;
- ret->accept_sock = (int)INVALID_SOCKET;
- return ret;
-}
-
-static void BIO_ACCEPT_free(BIO_ACCEPT *a)
-{
- if (a == NULL)
- return;
- OPENSSL_free(a->param_addr);
- OPENSSL_free(a->param_serv);
- BIO_ADDRINFO_free(a->addr_first);
- OPENSSL_free(a->cache_accepting_name);
- OPENSSL_free(a->cache_accepting_serv);
- OPENSSL_free(a->cache_peer_name);
- OPENSSL_free(a->cache_peer_serv);
- BIO_free(a->bio_chain);
- OPENSSL_free(a);
-}
-
-static void acpt_close_socket(BIO *bio)
-{
- BIO_ACCEPT *c;
-
- c = (BIO_ACCEPT *)bio->ptr;
- if (c->accept_sock != (int)INVALID_SOCKET) {
- shutdown(c->accept_sock, 2);
- closesocket(c->accept_sock);
- c->accept_sock = (int)INVALID_SOCKET;
- bio->num = (int)INVALID_SOCKET;
- }
-}
-
-static int acpt_free(BIO *a)
-{
- BIO_ACCEPT *data;
-
- if (a == NULL)
- return 0;
- data = (BIO_ACCEPT *)a->ptr;
-
- if (a->shutdown) {
- acpt_close_socket(a);
- BIO_ACCEPT_free(data);
- a->ptr = NULL;
- a->flags = 0;
- a->init = 0;
- }
- return 1;
-}
-
-static int acpt_state(BIO *b, BIO_ACCEPT *c)
-{
- BIO *bio = NULL, *dbio;
- int s = -1, ret = -1;
-
- for (;;) {
- switch (c->state) {
- case ACPT_S_BEFORE:
- if (c->param_addr == NULL && c->param_serv == NULL) {
- BIOerr(BIO_F_ACPT_STATE, BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED);
- ERR_add_error_data(4,
- "hostname=", c->param_addr,
- " service=", c->param_serv);
- goto exit_loop;
- }
-
- /* Because we're starting a new bind, any cached name and serv
- * are now obsolete and need to be cleaned out.
- * QUESTION: should this be done in acpt_close_socket() instead?
- */
- OPENSSL_free(c->cache_accepting_name);
- c->cache_accepting_name = NULL;
- OPENSSL_free(c->cache_accepting_serv);
- c->cache_accepting_serv = NULL;
- OPENSSL_free(c->cache_peer_name);
- c->cache_peer_name = NULL;
- OPENSSL_free(c->cache_peer_serv);
- c->cache_peer_serv = NULL;
-
- c->state = ACPT_S_GET_ADDR;
- break;
-
- case ACPT_S_GET_ADDR:
- {
- int family = AF_UNSPEC;
- switch (c->accept_family) {
- case BIO_FAMILY_IPV6:
- if (1) { /* This is a trick we use to avoid bit rot.
- * at least the "else" part will always be
- * compiled.
- */
-#ifdef AF_INET6
- family = AF_INET6;
- } else {
-#endif
- BIOerr(BIO_F_ACPT_STATE, BIO_R_UNAVAILABLE_IP_FAMILY);
- goto exit_loop;
- }
- break;
- case BIO_FAMILY_IPV4:
- family = AF_INET;
- break;
- case BIO_FAMILY_IPANY:
- family = AF_UNSPEC;
- break;
- default:
- BIOerr(BIO_F_ACPT_STATE, BIO_R_UNSUPPORTED_IP_FAMILY);
- goto exit_loop;
- }
- if (BIO_lookup(c->param_addr, c->param_serv, BIO_LOOKUP_SERVER,
- family, SOCK_STREAM, &c->addr_first) == 0)
- goto exit_loop;
- }
- if (c->addr_first == NULL) {
- BIOerr(BIO_F_ACPT_STATE, BIO_R_LOOKUP_RETURNED_NOTHING);
- goto exit_loop;
- }
- /* We're currently not iterating, but set this as preparation
- * for possible future development in that regard
- */
- c->addr_iter = c->addr_first;
- c->state = ACPT_S_CREATE_SOCKET;
- break;
-
- case ACPT_S_CREATE_SOCKET:
+
+#ifndef OPENSSL_NO_SOCK
+
+typedef struct bio_accept_st {
+ int state;
+ int accept_family;
+ int bind_mode; /* Socket mode for BIO_listen */
+ int accepted_mode; /* Socket mode for BIO_accept (set on accepted sock) */
+ char *param_addr;
+ char *param_serv;
+
+ int accept_sock;
+
+ BIO_ADDRINFO *addr_first;
+ const BIO_ADDRINFO *addr_iter;
+ BIO_ADDR cache_accepting_addr; /* Useful if we asked for port 0 */
+ char *cache_accepting_name, *cache_accepting_serv;
+ BIO_ADDR cache_peer_addr;
+ char *cache_peer_name, *cache_peer_serv;
+
+ BIO *bio_chain;
+} BIO_ACCEPT;
+
+static int acpt_write(BIO *h, const char *buf, int num);
+static int acpt_read(BIO *h, char *buf, int size);
+static int acpt_puts(BIO *h, const char *str);
+static long acpt_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int acpt_new(BIO *h);
+static int acpt_free(BIO *data);
+static int acpt_state(BIO *b, BIO_ACCEPT *c);
+static void acpt_close_socket(BIO *data);
+static BIO_ACCEPT *BIO_ACCEPT_new(void);
+static void BIO_ACCEPT_free(BIO_ACCEPT *a);
+
+# define ACPT_S_BEFORE 1
+# define ACPT_S_GET_ADDR 2
+# define ACPT_S_CREATE_SOCKET 3
+# define ACPT_S_LISTEN 4
+# define ACPT_S_ACCEPT 5
+# define ACPT_S_OK 6
+
+static const BIO_METHOD methods_acceptp = {
+ BIO_TYPE_ACCEPT,
+ "socket accept",
+ /* TODO: Convert to new style write function */
+ bwrite_conv,
+ acpt_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
+ acpt_read,
+ acpt_puts,
+ NULL, /* connect_gets, */
+ acpt_ctrl,
+ acpt_new,
+ acpt_free,
+ NULL, /* connect_callback_ctrl */
+};
+
+const BIO_METHOD *BIO_s_accept(void)
+{
+ return &methods_acceptp;
+}
+
+static int acpt_new(BIO *bi)
+{
+ BIO_ACCEPT *ba;
+
+ bi->init = 0;
+ bi->num = (int)INVALID_SOCKET;
+ bi->flags = 0;
+ if ((ba = BIO_ACCEPT_new()) == NULL)
+ return 0;
+ bi->ptr = (char *)ba;
+ ba->state = ACPT_S_BEFORE;
+ bi->shutdown = 1;
+ return 1;
+}
+
+static BIO_ACCEPT *BIO_ACCEPT_new(void)
+{
+ BIO_ACCEPT *ret;
+
+ if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
+ BIOerr(BIO_F_BIO_ACCEPT_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ ret->accept_family = BIO_FAMILY_IPANY;
+ ret->accept_sock = (int)INVALID_SOCKET;
+ return ret;
+}
+
+static void BIO_ACCEPT_free(BIO_ACCEPT *a)
+{
+ if (a == NULL)
+ return;
+ OPENSSL_free(a->param_addr);
+ OPENSSL_free(a->param_serv);
+ BIO_ADDRINFO_free(a->addr_first);
+ OPENSSL_free(a->cache_accepting_name);
+ OPENSSL_free(a->cache_accepting_serv);
+ OPENSSL_free(a->cache_peer_name);
+ OPENSSL_free(a->cache_peer_serv);
+ BIO_free(a->bio_chain);
+ OPENSSL_free(a);
+}
+
+static void acpt_close_socket(BIO *bio)
+{
+ BIO_ACCEPT *c;
+
+ c = (BIO_ACCEPT *)bio->ptr;
+ if (c->accept_sock != (int)INVALID_SOCKET) {
+ shutdown(c->accept_sock, 2);
+ closesocket(c->accept_sock);
+ c->accept_sock = (int)INVALID_SOCKET;
+ bio->num = (int)INVALID_SOCKET;
+ }
+}
+
+static int acpt_free(BIO *a)
+{
+ BIO_ACCEPT *data;
+
+ if (a == NULL)
+ return 0;
+ data = (BIO_ACCEPT *)a->ptr;
+
+ if (a->shutdown) {
+ acpt_close_socket(a);
+ BIO_ACCEPT_free(data);
+ a->ptr = NULL;
+ a->flags = 0;
+ a->init = 0;
+ }
+ return 1;
+}
+
+static int acpt_state(BIO *b, BIO_ACCEPT *c)
+{
+ BIO *bio = NULL, *dbio;
+ int s = -1, ret = -1;
+
+ for (;;) {
+ switch (c->state) {
+ case ACPT_S_BEFORE:
+ if (c->param_addr == NULL && c->param_serv == NULL) {
+ BIOerr(BIO_F_ACPT_STATE, BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED);
+ ERR_add_error_data(4,
+ "hostname=", c->param_addr,
+ " service=", c->param_serv);
+ goto exit_loop;
+ }
+
+ /* Because we're starting a new bind, any cached name and serv
+ * are now obsolete and need to be cleaned out.
+ * QUESTION: should this be done in acpt_close_socket() instead?
+ */
+ OPENSSL_free(c->cache_accepting_name);
+ c->cache_accepting_name = NULL;
+ OPENSSL_free(c->cache_accepting_serv);
+ c->cache_accepting_serv = NULL;
+ OPENSSL_free(c->cache_peer_name);
+ c->cache_peer_name = NULL;
+ OPENSSL_free(c->cache_peer_serv);
+ c->cache_peer_serv = NULL;
+
+ c->state = ACPT_S_GET_ADDR;
+ break;
+
+ case ACPT_S_GET_ADDR:
+ {
+ int family = AF_UNSPEC;
+ switch (c->accept_family) {
+ case BIO_FAMILY_IPV6:
+ if (1) { /* This is a trick we use to avoid bit rot.
+ * at least the "else" part will always be
+ * compiled.
+ */
+#ifdef AF_INET6
+ family = AF_INET6;
+ } else {
+#endif
+ BIOerr(BIO_F_ACPT_STATE, BIO_R_UNAVAILABLE_IP_FAMILY);
+ goto exit_loop;
+ }
+ break;
+ case BIO_FAMILY_IPV4:
+ family = AF_INET;
+ break;
+ case BIO_FAMILY_IPANY:
+ family = AF_UNSPEC;
+ break;
+ default:
+ BIOerr(BIO_F_ACPT_STATE, BIO_R_UNSUPPORTED_IP_FAMILY);
+ goto exit_loop;
+ }
+ if (BIO_lookup(c->param_addr, c->param_serv, BIO_LOOKUP_SERVER,
+ family, SOCK_STREAM, &c->addr_first) == 0)
+ goto exit_loop;
+ }
+ if (c->addr_first == NULL) {
+ BIOerr(BIO_F_ACPT_STATE, BIO_R_LOOKUP_RETURNED_NOTHING);
+ goto exit_loop;
+ }
+ /* We're currently not iterating, but set this as preparation
+ * for possible future development in that regard
+ */
+ c->addr_iter = c->addr_first;
+ c->state = ACPT_S_CREATE_SOCKET;
+ break;
+
+ case ACPT_S_CREATE_SOCKET:
s = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
BIO_ADDRINFO_socktype(c->addr_iter),
BIO_ADDRINFO_protocol(c->addr_iter), 0);
if (s == (int)INVALID_SOCKET) {
- SYSerr(SYS_F_SOCKET, get_last_socket_error());
- ERR_add_error_data(4,
- "hostname=", c->param_addr,
- " service=", c->param_serv);
- BIOerr(BIO_F_ACPT_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET);
- goto exit_loop;
- }
+ SYSerr(SYS_F_SOCKET, get_last_socket_error());
+ ERR_add_error_data(4,
+ "hostname=", c->param_addr,
+ " service=", c->param_serv);
+ BIOerr(BIO_F_ACPT_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET);
+ goto exit_loop;
+ }
c->accept_sock = s;
b->num = s;
- c->state = ACPT_S_LISTEN;
+ c->state = ACPT_S_LISTEN;
s = -1;
- break;
-
- case ACPT_S_LISTEN:
- {
- if (!BIO_listen(c->accept_sock,
- BIO_ADDRINFO_address(c->addr_iter),
- c->bind_mode)) {
- BIO_closesocket(c->accept_sock);
- goto exit_loop;
- }
- }
-
- {
- union BIO_sock_info_u info;
-
- info.addr = &c->cache_accepting_addr;
- if (!BIO_sock_info(c->accept_sock, BIO_SOCK_INFO_ADDRESS,
- &info)) {
- BIO_closesocket(c->accept_sock);
- goto exit_loop;
- }
- }
-
- c->cache_accepting_name =
- BIO_ADDR_hostname_string(&c->cache_accepting_addr, 1);
- c->cache_accepting_serv =
- BIO_ADDR_service_string(&c->cache_accepting_addr, 1);
- c->state = ACPT_S_ACCEPT;
- s = -1;
- ret = 1;
- goto end;
-
- case ACPT_S_ACCEPT:
- if (b->next_bio != NULL) {
- c->state = ACPT_S_OK;
- break;
- }
- BIO_clear_retry_flags(b);
- b->retry_reason = 0;
-
- OPENSSL_free(c->cache_peer_name);
- c->cache_peer_name = NULL;
- OPENSSL_free(c->cache_peer_serv);
- c->cache_peer_serv = NULL;
-
- s = BIO_accept_ex(c->accept_sock, &c->cache_peer_addr,
- c->accepted_mode);
-
- /* If the returned socket is invalid, this might still be
- * retryable
- */
- if (s < 0) {
- if (BIO_sock_should_retry(s)) {
- BIO_set_retry_special(b);
- b->retry_reason = BIO_RR_ACCEPT;
- goto end;
- }
- }
-
- /* If it wasn't retryable, we fail */
- if (s < 0) {
- ret = s;
- goto exit_loop;
- }
-
- bio = BIO_new_socket(s, BIO_CLOSE);
- if (bio == NULL)
- goto exit_loop;
-
- BIO_set_callback(bio, BIO_get_callback(b));
- BIO_set_callback_arg(bio, BIO_get_callback_arg(b));
-
- /*
- * If the accept BIO has an bio_chain, we dup it and put the new
- * socket at the end.
- */
- if (c->bio_chain != NULL) {
- if ((dbio = BIO_dup_chain(c->bio_chain)) == NULL)
- goto exit_loop;
- if (!BIO_push(dbio, bio))
- goto exit_loop;
- bio = dbio;
- }
- if (BIO_push(b, bio) == NULL)
- goto exit_loop;
-
- c->cache_peer_name =
- BIO_ADDR_hostname_string(&c->cache_peer_addr, 1);
- c->cache_peer_serv =
- BIO_ADDR_service_string(&c->cache_peer_addr, 1);
- c->state = ACPT_S_OK;
- bio = NULL;
- ret = 1;
- goto end;
-
- case ACPT_S_OK:
- if (b->next_bio == NULL) {
- c->state = ACPT_S_ACCEPT;
- break;
- }
- ret = 1;
- goto end;
-
- default:
- ret = 0;
- goto end;
- }
- }
-
- exit_loop:
- if (bio != NULL)
- BIO_free(bio);
- else if (s >= 0)
- BIO_closesocket(s);
- end:
- return ret;
-}
-
-static int acpt_read(BIO *b, char *out, int outl)
-{
- int ret = 0;
- BIO_ACCEPT *data;
-
- BIO_clear_retry_flags(b);
- data = (BIO_ACCEPT *)b->ptr;
-
- while (b->next_bio == NULL) {
- ret = acpt_state(b, data);
- if (ret <= 0)
- return ret;
- }
-
- ret = BIO_read(b->next_bio, out, outl);
- BIO_copy_next_retry(b);
- return ret;
-}
-
-static int acpt_write(BIO *b, const char *in, int inl)
-{
- int ret;
- BIO_ACCEPT *data;
-
- BIO_clear_retry_flags(b);
- data = (BIO_ACCEPT *)b->ptr;
-
- while (b->next_bio == NULL) {
- ret = acpt_state(b, data);
- if (ret <= 0)
- return ret;
- }
-
- ret = BIO_write(b->next_bio, in, inl);
- BIO_copy_next_retry(b);
- return ret;
-}
-
-static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
-{
- int *ip;
- long ret = 1;
- BIO_ACCEPT *data;
- char **pp;
-
- data = (BIO_ACCEPT *)b->ptr;
-
- switch (cmd) {
- case BIO_CTRL_RESET:
- ret = 0;
- data->state = ACPT_S_BEFORE;
- acpt_close_socket(b);
- BIO_ADDRINFO_free(data->addr_first);
- data->addr_first = NULL;
- b->flags = 0;
- break;
- case BIO_C_DO_STATE_MACHINE:
- /* use this one to start the connection */
- ret = (long)acpt_state(b, data);
- break;
- case BIO_C_SET_ACCEPT:
- if (ptr != NULL) {
- if (num == 0) {
- char *hold_serv = data->param_serv;
- /* We affect the hostname regardless. However, the input
- * string might contain a host:service spec, so we must
- * parse it, which might or might not affect the service
- */
- OPENSSL_free(data->param_addr);
- data->param_addr = NULL;
- ret = BIO_parse_hostserv(ptr,
- &data->param_addr,
- &data->param_serv,
- BIO_PARSE_PRIO_SERV);
- if (hold_serv != data->param_serv)
- OPENSSL_free(hold_serv);
- b->init = 1;
- } else if (num == 1) {
- OPENSSL_free(data->param_serv);
+ break;
+
+ case ACPT_S_LISTEN:
+ {
+ if (!BIO_listen(c->accept_sock,
+ BIO_ADDRINFO_address(c->addr_iter),
+ c->bind_mode)) {
+ BIO_closesocket(c->accept_sock);
+ goto exit_loop;
+ }
+ }
+
+ {
+ union BIO_sock_info_u info;
+
+ info.addr = &c->cache_accepting_addr;
+ if (!BIO_sock_info(c->accept_sock, BIO_SOCK_INFO_ADDRESS,
+ &info)) {
+ BIO_closesocket(c->accept_sock);
+ goto exit_loop;
+ }
+ }
+
+ c->cache_accepting_name =
+ BIO_ADDR_hostname_string(&c->cache_accepting_addr, 1);
+ c->cache_accepting_serv =
+ BIO_ADDR_service_string(&c->cache_accepting_addr, 1);
+ c->state = ACPT_S_ACCEPT;
+ s = -1;
+ ret = 1;
+ goto end;
+
+ case ACPT_S_ACCEPT:
+ if (b->next_bio != NULL) {
+ c->state = ACPT_S_OK;
+ break;
+ }
+ BIO_clear_retry_flags(b);
+ b->retry_reason = 0;
+
+ OPENSSL_free(c->cache_peer_name);
+ c->cache_peer_name = NULL;
+ OPENSSL_free(c->cache_peer_serv);
+ c->cache_peer_serv = NULL;
+
+ s = BIO_accept_ex(c->accept_sock, &c->cache_peer_addr,
+ c->accepted_mode);
+
+ /* If the returned socket is invalid, this might still be
+ * retryable
+ */
+ if (s < 0) {
+ if (BIO_sock_should_retry(s)) {
+ BIO_set_retry_special(b);
+ b->retry_reason = BIO_RR_ACCEPT;
+ goto end;
+ }
+ }
+
+ /* If it wasn't retryable, we fail */
+ if (s < 0) {
+ ret = s;
+ goto exit_loop;
+ }
+
+ bio = BIO_new_socket(s, BIO_CLOSE);
+ if (bio == NULL)
+ goto exit_loop;
+
+ BIO_set_callback(bio, BIO_get_callback(b));
+ BIO_set_callback_arg(bio, BIO_get_callback_arg(b));
+
+ /*
+ * If the accept BIO has an bio_chain, we dup it and put the new
+ * socket at the end.
+ */
+ if (c->bio_chain != NULL) {
+ if ((dbio = BIO_dup_chain(c->bio_chain)) == NULL)
+ goto exit_loop;
+ if (!BIO_push(dbio, bio))
+ goto exit_loop;
+ bio = dbio;
+ }
+ if (BIO_push(b, bio) == NULL)
+ goto exit_loop;
+
+ c->cache_peer_name =
+ BIO_ADDR_hostname_string(&c->cache_peer_addr, 1);
+ c->cache_peer_serv =
+ BIO_ADDR_service_string(&c->cache_peer_addr, 1);
+ c->state = ACPT_S_OK;
+ bio = NULL;
+ ret = 1;
+ goto end;
+
+ case ACPT_S_OK:
+ if (b->next_bio == NULL) {
+ c->state = ACPT_S_ACCEPT;
+ break;
+ }
+ ret = 1;
+ goto end;
+
+ default:
+ ret = 0;
+ goto end;
+ }
+ }
+
+ exit_loop:
+ if (bio != NULL)
+ BIO_free(bio);
+ else if (s >= 0)
+ BIO_closesocket(s);
+ end:
+ return ret;
+}
+
+static int acpt_read(BIO *b, char *out, int outl)
+{
+ int ret = 0;
+ BIO_ACCEPT *data;
+
+ BIO_clear_retry_flags(b);
+ data = (BIO_ACCEPT *)b->ptr;
+
+ while (b->next_bio == NULL) {
+ ret = acpt_state(b, data);
+ if (ret <= 0)
+ return ret;
+ }
+
+ ret = BIO_read(b->next_bio, out, outl);
+ BIO_copy_next_retry(b);
+ return ret;
+}
+
+static int acpt_write(BIO *b, const char *in, int inl)
+{
+ int ret;
+ BIO_ACCEPT *data;
+
+ BIO_clear_retry_flags(b);
+ data = (BIO_ACCEPT *)b->ptr;
+
+ while (b->next_bio == NULL) {
+ ret = acpt_state(b, data);
+ if (ret <= 0)
+ return ret;
+ }
+
+ ret = BIO_write(b->next_bio, in, inl);
+ BIO_copy_next_retry(b);
+ return ret;
+}
+
+static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ int *ip;
+ long ret = 1;
+ BIO_ACCEPT *data;
+ char **pp;
+
+ data = (BIO_ACCEPT *)b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ ret = 0;
+ data->state = ACPT_S_BEFORE;
+ acpt_close_socket(b);
+ BIO_ADDRINFO_free(data->addr_first);
+ data->addr_first = NULL;
+ b->flags = 0;
+ break;
+ case BIO_C_DO_STATE_MACHINE:
+ /* use this one to start the connection */
+ ret = (long)acpt_state(b, data);
+ break;
+ case BIO_C_SET_ACCEPT:
+ if (ptr != NULL) {
+ if (num == 0) {
+ char *hold_serv = data->param_serv;
+ /* We affect the hostname regardless. However, the input
+ * string might contain a host:service spec, so we must
+ * parse it, which might or might not affect the service
+ */
+ OPENSSL_free(data->param_addr);
+ data->param_addr = NULL;
+ ret = BIO_parse_hostserv(ptr,
+ &data->param_addr,
+ &data->param_serv,
+ BIO_PARSE_PRIO_SERV);
+ if (hold_serv != data->param_serv)
+ OPENSSL_free(hold_serv);
+ b->init = 1;
+ } else if (num == 1) {
+ OPENSSL_free(data->param_serv);
if ((data->param_serv = OPENSSL_strdup(ptr)) == NULL)
ret = 0;
else
b->init = 1;
- } else if (num == 2) {
- data->bind_mode |= BIO_SOCK_NONBLOCK;
- } else if (num == 3) {
- BIO_free(data->bio_chain);
- data->bio_chain = (BIO *)ptr;
- } else if (num == 4) {
- data->accept_family = *(int *)ptr;
- }
- } else {
- if (num == 2) {
- data->bind_mode &= ~BIO_SOCK_NONBLOCK;
- }
- }
- break;
- case BIO_C_SET_NBIO:
- if (num != 0)
- data->accepted_mode |= BIO_SOCK_NONBLOCK;
- else
- data->accepted_mode &= ~BIO_SOCK_NONBLOCK;
- break;
- case BIO_C_SET_FD:
- b->num = *((int *)ptr);
- data->accept_sock = b->num;
- data->state = ACPT_S_ACCEPT;
- b->shutdown = (int)num;
- b->init = 1;
- break;
- case BIO_C_GET_FD:
- if (b->init) {
- ip = (int *)ptr;
- if (ip != NULL)
- *ip = data->accept_sock;
- ret = data->accept_sock;
- } else
- ret = -1;
- break;
- case BIO_C_GET_ACCEPT:
- if (b->init) {
- if (num == 0 && ptr != NULL) {
- pp = (char **)ptr;
- *pp = data->cache_accepting_name;
- } else if (num == 1 && ptr != NULL) {
- pp = (char **)ptr;
- *pp = data->cache_accepting_serv;
- } else if (num == 2 && ptr != NULL) {
- pp = (char **)ptr;
- *pp = data->cache_peer_name;
- } else if (num == 3 && ptr != NULL) {
- pp = (char **)ptr;
- *pp = data->cache_peer_serv;
- } else if (num == 4) {
- switch (BIO_ADDRINFO_family(data->addr_iter)) {
-#ifdef AF_INET6
- case AF_INET6:
- ret = BIO_FAMILY_IPV6;
- break;
-#endif
- case AF_INET:
- ret = BIO_FAMILY_IPV4;
- break;
- case 0:
- ret = data->accept_family;
- break;
- default:
- ret = -1;
- break;
- }
- } else
- ret = -1;
- } else
- ret = -1;
- break;
- case BIO_CTRL_GET_CLOSE:
- ret = b->shutdown;
- break;
- case BIO_CTRL_SET_CLOSE:
- b->shutdown = (int)num;
- break;
- case BIO_CTRL_PENDING:
- case BIO_CTRL_WPENDING:
- ret = 0;
- break;
- case BIO_CTRL_FLUSH:
- break;
- case BIO_C_SET_BIND_MODE:
- data->bind_mode = (int)num;
- break;
- case BIO_C_GET_BIND_MODE:
- ret = (long)data->bind_mode;
- break;
- case BIO_CTRL_DUP:
- break;
+ } else if (num == 2) {
+ data->bind_mode |= BIO_SOCK_NONBLOCK;
+ } else if (num == 3) {
+ BIO_free(data->bio_chain);
+ data->bio_chain = (BIO *)ptr;
+ } else if (num == 4) {
+ data->accept_family = *(int *)ptr;
+ }
+ } else {
+ if (num == 2) {
+ data->bind_mode &= ~BIO_SOCK_NONBLOCK;
+ }
+ }
+ break;
+ case BIO_C_SET_NBIO:
+ if (num != 0)
+ data->accepted_mode |= BIO_SOCK_NONBLOCK;
+ else
+ data->accepted_mode &= ~BIO_SOCK_NONBLOCK;
+ break;
+ case BIO_C_SET_FD:
+ b->num = *((int *)ptr);
+ data->accept_sock = b->num;
+ data->state = ACPT_S_ACCEPT;
+ b->shutdown = (int)num;
+ b->init = 1;
+ break;
+ case BIO_C_GET_FD:
+ if (b->init) {
+ ip = (int *)ptr;
+ if (ip != NULL)
+ *ip = data->accept_sock;
+ ret = data->accept_sock;
+ } else
+ ret = -1;
+ break;
+ case BIO_C_GET_ACCEPT:
+ if (b->init) {
+ if (num == 0 && ptr != NULL) {
+ pp = (char **)ptr;
+ *pp = data->cache_accepting_name;
+ } else if (num == 1 && ptr != NULL) {
+ pp = (char **)ptr;
+ *pp = data->cache_accepting_serv;
+ } else if (num == 2 && ptr != NULL) {
+ pp = (char **)ptr;
+ *pp = data->cache_peer_name;
+ } else if (num == 3 && ptr != NULL) {
+ pp = (char **)ptr;
+ *pp = data->cache_peer_serv;
+ } else if (num == 4) {
+ switch (BIO_ADDRINFO_family(data->addr_iter)) {
+#ifdef AF_INET6
+ case AF_INET6:
+ ret = BIO_FAMILY_IPV6;
+ break;
+#endif
+ case AF_INET:
+ ret = BIO_FAMILY_IPV4;
+ break;
+ case 0:
+ ret = data->accept_family;
+ break;
+ default:
+ ret = -1;
+ break;
+ }
+ } else
+ ret = -1;
+ } else
+ ret = -1;
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret = b->shutdown;
+ break;
+ case BIO_CTRL_SET_CLOSE:
+ b->shutdown = (int)num;
+ break;
+ case BIO_CTRL_PENDING:
+ case BIO_CTRL_WPENDING:
+ ret = 0;
+ break;
+ case BIO_CTRL_FLUSH:
+ break;
+ case BIO_C_SET_BIND_MODE:
+ data->bind_mode = (int)num;
+ break;
+ case BIO_C_GET_BIND_MODE:
+ ret = (long)data->bind_mode;
+ break;
+ case BIO_CTRL_DUP:
+ break;
case BIO_CTRL_EOF:
if (b->next_bio == NULL)
ret = 0;
else
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
- default:
- ret = 0;
- break;
- }
- return ret;
-}
-
-static int acpt_puts(BIO *bp, const char *str)
-{
- int n, ret;
-
- n = strlen(str);
- ret = acpt_write(bp, str, n);
- return ret;
-}
-
-BIO *BIO_new_accept(const char *str)
-{
- BIO *ret;
-
- ret = BIO_new(BIO_s_accept());
- if (ret == NULL)
- return NULL;
- if (BIO_set_accept_name(ret, str))
- return ret;
- BIO_free(ret);
- return NULL;
-}
-
-#endif
+ default:
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+static int acpt_puts(BIO *bp, const char *str)
+{
+ int n, ret;
+
+ n = strlen(str);
+ ret = acpt_write(bp, str, n);
+ return ret;
+}
+
+BIO *BIO_new_accept(const char *str)
+{
+ BIO *ret;
+
+ ret = BIO_new(BIO_s_accept());
+ if (ret == NULL)
+ return NULL;
+ if (BIO_set_accept_name(ret, str))
+ return ret;
+ BIO_free(ret);
+ return NULL;
+}
+
+#endif
diff --git a/contrib/libs/openssl/crypto/bio/bss_bio.c b/contrib/libs/openssl/crypto/bio/bss_bio.c
index d0d00ab442..c97349e432 100644
--- a/contrib/libs/openssl/crypto/bio/bss_bio.c
+++ b/contrib/libs/openssl/crypto/bio/bss_bio.c
@@ -1,808 +1,808 @@
-/*
- * Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-/*
- * Special method for a BIO where the other endpoint is also a BIO of this
- * kind, handled by the same thread (i.e. the "peer" is actually ourselves,
- * wearing a different hat). Such "BIO pairs" are mainly for using the SSL
- * library with I/O interfaces for which no specific BIO method is available.
- * See ssl/ssltest.c for some hints on how this can be used.
- */
-
-#include "e_os.h"
-#include <assert.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <string.h>
-
+/*
+ * Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * Special method for a BIO where the other endpoint is also a BIO of this
+ * kind, handled by the same thread (i.e. the "peer" is actually ourselves,
+ * wearing a different hat). Such "BIO pairs" are mainly for using the SSL
+ * library with I/O interfaces for which no specific BIO method is available.
+ * See ssl/ssltest.c for some hints on how this can be used.
+ */
+
+#include "e_os.h"
+#include <assert.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
#include "bio_local.h"
-#include <openssl/err.h>
-#include <openssl/crypto.h>
-
-static int bio_new(BIO *bio);
-static int bio_free(BIO *bio);
-static int bio_read(BIO *bio, char *buf, int size);
-static int bio_write(BIO *bio, const char *buf, int num);
-static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr);
-static int bio_puts(BIO *bio, const char *str);
-
-static int bio_make_pair(BIO *bio1, BIO *bio2);
-static void bio_destroy_pair(BIO *bio);
-
-static const BIO_METHOD methods_biop = {
- BIO_TYPE_BIO,
- "BIO pair",
- /* TODO: Convert to new style write function */
- bwrite_conv,
- bio_write,
- /* TODO: Convert to new style read function */
- bread_conv,
- bio_read,
- bio_puts,
- NULL /* no bio_gets */ ,
- bio_ctrl,
- bio_new,
- bio_free,
- NULL /* no bio_callback_ctrl */
-};
-
-const BIO_METHOD *BIO_s_bio(void)
-{
- return &methods_biop;
-}
-
-struct bio_bio_st {
- BIO *peer; /* NULL if buf == NULL. If peer != NULL, then
- * peer->ptr is also a bio_bio_st, and its
- * "peer" member points back to us. peer !=
- * NULL iff init != 0 in the BIO. */
- /* This is for what we write (i.e. reading uses peer's struct): */
- int closed; /* valid iff peer != NULL */
- size_t len; /* valid iff buf != NULL; 0 if peer == NULL */
- size_t offset; /* valid iff buf != NULL; 0 if len == 0 */
- size_t size;
- char *buf; /* "size" elements (if != NULL) */
- size_t request; /* valid iff peer != NULL; 0 if len != 0,
- * otherwise set by peer to number of bytes
- * it (unsuccessfully) tried to read, never
- * more than buffer space (size-len)
- * warrants. */
-};
-
-static int bio_new(BIO *bio)
-{
- struct bio_bio_st *b = OPENSSL_zalloc(sizeof(*b));
-
- if (b == NULL)
- return 0;
-
- /* enough for one TLS record (just a default) */
- b->size = 17 * 1024;
-
- bio->ptr = b;
- return 1;
-}
-
-static int bio_free(BIO *bio)
-{
- struct bio_bio_st *b;
-
- if (bio == NULL)
- return 0;
- b = bio->ptr;
-
- assert(b != NULL);
-
- if (b->peer)
- bio_destroy_pair(bio);
-
- OPENSSL_free(b->buf);
- OPENSSL_free(b);
-
- return 1;
-}
-
-static int bio_read(BIO *bio, char *buf, int size_)
-{
- size_t size = size_;
- size_t rest;
- struct bio_bio_st *b, *peer_b;
-
- BIO_clear_retry_flags(bio);
-
- if (!bio->init)
- return 0;
-
- b = bio->ptr;
- assert(b != NULL);
- assert(b->peer != NULL);
- peer_b = b->peer->ptr;
- assert(peer_b != NULL);
- assert(peer_b->buf != NULL);
-
- peer_b->request = 0; /* will be set in "retry_read" situation */
-
- if (buf == NULL || size == 0)
- return 0;
-
- if (peer_b->len == 0) {
- if (peer_b->closed)
- return 0; /* writer has closed, and no data is left */
- else {
- BIO_set_retry_read(bio); /* buffer is empty */
- if (size <= peer_b->size)
- peer_b->request = size;
- else
- /*
- * don't ask for more than the peer can deliver in one write
- */
- peer_b->request = peer_b->size;
- return -1;
- }
- }
-
- /* we can read */
- if (peer_b->len < size)
- size = peer_b->len;
-
- /* now read "size" bytes */
-
- rest = size;
-
- assert(rest > 0);
- do { /* one or two iterations */
- size_t chunk;
-
- assert(rest <= peer_b->len);
- if (peer_b->offset + rest <= peer_b->size)
- chunk = rest;
- else
- /* wrap around ring buffer */
- chunk = peer_b->size - peer_b->offset;
- assert(peer_b->offset + chunk <= peer_b->size);
-
- memcpy(buf, peer_b->buf + peer_b->offset, chunk);
-
- peer_b->len -= chunk;
- if (peer_b->len) {
- peer_b->offset += chunk;
- assert(peer_b->offset <= peer_b->size);
- if (peer_b->offset == peer_b->size)
- peer_b->offset = 0;
- buf += chunk;
- } else {
- /* buffer now empty, no need to advance "buf" */
- assert(chunk == rest);
- peer_b->offset = 0;
- }
- rest -= chunk;
- }
- while (rest);
-
- return size;
-}
-
-/*-
- * non-copying interface: provide pointer to available data in buffer
- * bio_nread0: return number of available bytes
- * bio_nread: also advance index
- * (example usage: bio_nread0(), read from buffer, bio_nread()
- * or just bio_nread(), read from buffer)
- */
-/*
- * WARNING: The non-copying interface is largely untested as of yet and may
- * contain bugs.
- */
-static ossl_ssize_t bio_nread0(BIO *bio, char **buf)
-{
- struct bio_bio_st *b, *peer_b;
- ossl_ssize_t num;
-
- BIO_clear_retry_flags(bio);
-
- if (!bio->init)
- return 0;
-
- b = bio->ptr;
- assert(b != NULL);
- assert(b->peer != NULL);
- peer_b = b->peer->ptr;
- assert(peer_b != NULL);
- assert(peer_b->buf != NULL);
-
- peer_b->request = 0;
-
- if (peer_b->len == 0) {
- char dummy;
-
- /* avoid code duplication -- nothing available for reading */
- return bio_read(bio, &dummy, 1); /* returns 0 or -1 */
- }
-
- num = peer_b->len;
- if (peer_b->size < peer_b->offset + num)
- /* no ring buffer wrap-around for non-copying interface */
- num = peer_b->size - peer_b->offset;
- assert(num > 0);
-
- if (buf != NULL)
- *buf = peer_b->buf + peer_b->offset;
- return num;
-}
-
-static ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_)
-{
- struct bio_bio_st *b, *peer_b;
- ossl_ssize_t num, available;
-
- if (num_ > OSSL_SSIZE_MAX)
- num = OSSL_SSIZE_MAX;
- else
- num = (ossl_ssize_t) num_;
-
- available = bio_nread0(bio, buf);
- if (num > available)
- num = available;
- if (num <= 0)
- return num;
-
- b = bio->ptr;
- peer_b = b->peer->ptr;
-
- peer_b->len -= num;
- if (peer_b->len) {
- peer_b->offset += num;
- assert(peer_b->offset <= peer_b->size);
- if (peer_b->offset == peer_b->size)
- peer_b->offset = 0;
- } else
- peer_b->offset = 0;
-
- return num;
-}
-
-static int bio_write(BIO *bio, const char *buf, int num_)
-{
- size_t num = num_;
- size_t rest;
- struct bio_bio_st *b;
-
- BIO_clear_retry_flags(bio);
-
- if (!bio->init || buf == NULL || num == 0)
- return 0;
-
- b = bio->ptr;
- assert(b != NULL);
- assert(b->peer != NULL);
- assert(b->buf != NULL);
-
- b->request = 0;
- if (b->closed) {
- /* we already closed */
- BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE);
- return -1;
- }
-
- assert(b->len <= b->size);
-
- if (b->len == b->size) {
- BIO_set_retry_write(bio); /* buffer is full */
- return -1;
- }
-
- /* we can write */
- if (num > b->size - b->len)
- num = b->size - b->len;
-
- /* now write "num" bytes */
-
- rest = num;
-
- assert(rest > 0);
- do { /* one or two iterations */
- size_t write_offset;
- size_t chunk;
-
- assert(b->len + rest <= b->size);
-
- write_offset = b->offset + b->len;
- if (write_offset >= b->size)
- write_offset -= b->size;
- /* b->buf[write_offset] is the first byte we can write to. */
-
- if (write_offset + rest <= b->size)
- chunk = rest;
- else
- /* wrap around ring buffer */
- chunk = b->size - write_offset;
-
- memcpy(b->buf + write_offset, buf, chunk);
-
- b->len += chunk;
-
- assert(b->len <= b->size);
-
- rest -= chunk;
- buf += chunk;
- }
- while (rest);
-
- return num;
-}
-
-/*-
- * non-copying interface: provide pointer to region to write to
- * bio_nwrite0: check how much space is available
- * bio_nwrite: also increase length
- * (example usage: bio_nwrite0(), write to buffer, bio_nwrite()
- * or just bio_nwrite(), write to buffer)
- */
-static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf)
-{
- struct bio_bio_st *b;
- size_t num;
- size_t write_offset;
-
- BIO_clear_retry_flags(bio);
-
- if (!bio->init)
- return 0;
-
- b = bio->ptr;
- assert(b != NULL);
- assert(b->peer != NULL);
- assert(b->buf != NULL);
-
- b->request = 0;
- if (b->closed) {
- BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE);
- return -1;
- }
-
- assert(b->len <= b->size);
-
- if (b->len == b->size) {
- BIO_set_retry_write(bio);
- return -1;
- }
-
- num = b->size - b->len;
- write_offset = b->offset + b->len;
- if (write_offset >= b->size)
- write_offset -= b->size;
- if (write_offset + num > b->size)
- /*
- * no ring buffer wrap-around for non-copying interface (to fulfil
- * the promise by BIO_ctrl_get_write_guarantee, BIO_nwrite may have
- * to be called twice)
- */
- num = b->size - write_offset;
-
- if (buf != NULL)
- *buf = b->buf + write_offset;
- assert(write_offset + num <= b->size);
-
- return num;
-}
-
-static ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_)
-{
- struct bio_bio_st *b;
- ossl_ssize_t num, space;
-
- if (num_ > OSSL_SSIZE_MAX)
- num = OSSL_SSIZE_MAX;
- else
- num = (ossl_ssize_t) num_;
-
- space = bio_nwrite0(bio, buf);
- if (num > space)
- num = space;
- if (num <= 0)
- return num;
- b = bio->ptr;
- assert(b != NULL);
- b->len += num;
- assert(b->len <= b->size);
-
- return num;
-}
-
-static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
-{
- long ret;
- struct bio_bio_st *b = bio->ptr;
-
- assert(b != NULL);
-
- switch (cmd) {
- /* specific CTRL codes */
-
- case BIO_C_SET_WRITE_BUF_SIZE:
- if (b->peer) {
- BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE);
- ret = 0;
- } else if (num == 0) {
- BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT);
- ret = 0;
- } else {
- size_t new_size = num;
-
- if (b->size != new_size) {
- OPENSSL_free(b->buf);
- b->buf = NULL;
- b->size = new_size;
- }
- ret = 1;
- }
- break;
-
- case BIO_C_GET_WRITE_BUF_SIZE:
- ret = (long)b->size;
- break;
-
- case BIO_C_MAKE_BIO_PAIR:
- {
- BIO *other_bio = ptr;
-
- if (bio_make_pair(bio, other_bio))
- ret = 1;
- else
- ret = 0;
- }
- break;
-
- case BIO_C_DESTROY_BIO_PAIR:
- /*
- * Affects both BIOs in the pair -- call just once! Or let
- * BIO_free(bio1); BIO_free(bio2); do the job.
- */
- bio_destroy_pair(bio);
- ret = 1;
- break;
-
- case BIO_C_GET_WRITE_GUARANTEE:
- /*
- * How many bytes can the caller feed to the next write without
- * having to keep any?
- */
- if (b->peer == NULL || b->closed)
- ret = 0;
- else
- ret = (long)b->size - b->len;
- break;
-
- case BIO_C_GET_READ_REQUEST:
- /*
- * If the peer unsuccessfully tried to read, how many bytes were
- * requested? (As with BIO_CTRL_PENDING, that number can usually be
- * treated as boolean.)
- */
- ret = (long)b->request;
- break;
-
- case BIO_C_RESET_READ_REQUEST:
- /*
- * Reset request. (Can be useful after read attempts at the other
- * side that are meant to be non-blocking, e.g. when probing SSL_read
- * to see if any data is available.)
- */
- b->request = 0;
- ret = 1;
- break;
-
- case BIO_C_SHUTDOWN_WR:
- /* similar to shutdown(..., SHUT_WR) */
- b->closed = 1;
- ret = 1;
- break;
-
- case BIO_C_NREAD0:
- /* prepare for non-copying read */
- ret = (long)bio_nread0(bio, ptr);
- break;
-
- case BIO_C_NREAD:
- /* non-copying read */
- ret = (long)bio_nread(bio, ptr, (size_t)num);
- break;
-
- case BIO_C_NWRITE0:
- /* prepare for non-copying write */
- ret = (long)bio_nwrite0(bio, ptr);
- break;
-
- case BIO_C_NWRITE:
- /* non-copying write */
- ret = (long)bio_nwrite(bio, ptr, (size_t)num);
- break;
-
- /* standard CTRL codes follow */
-
- case BIO_CTRL_RESET:
- if (b->buf != NULL) {
- b->len = 0;
- b->offset = 0;
- }
- ret = 0;
- break;
-
- case BIO_CTRL_GET_CLOSE:
- ret = bio->shutdown;
- break;
-
- case BIO_CTRL_SET_CLOSE:
- bio->shutdown = (int)num;
- ret = 1;
- break;
-
- case BIO_CTRL_PENDING:
- if (b->peer != NULL) {
- struct bio_bio_st *peer_b = b->peer->ptr;
-
- ret = (long)peer_b->len;
- } else
- ret = 0;
- break;
-
- case BIO_CTRL_WPENDING:
- if (b->buf != NULL)
- ret = (long)b->len;
- else
- ret = 0;
- break;
-
- case BIO_CTRL_DUP:
- /* See BIO_dup_chain for circumstances we have to expect. */
- {
- BIO *other_bio = ptr;
- struct bio_bio_st *other_b;
-
- assert(other_bio != NULL);
- other_b = other_bio->ptr;
- assert(other_b != NULL);
-
- assert(other_b->buf == NULL); /* other_bio is always fresh */
-
- other_b->size = b->size;
- }
-
- ret = 1;
- break;
-
- case BIO_CTRL_FLUSH:
- ret = 1;
- break;
-
- case BIO_CTRL_EOF:
- if (b->peer != NULL) {
- struct bio_bio_st *peer_b = b->peer->ptr;
-
- if (peer_b->len == 0 && peer_b->closed)
- ret = 1;
- else
- ret = 0;
- } else {
- ret = 1;
- }
- break;
-
- default:
- ret = 0;
- }
- return ret;
-}
-
-static int bio_puts(BIO *bio, const char *str)
-{
- return bio_write(bio, str, strlen(str));
-}
-
-static int bio_make_pair(BIO *bio1, BIO *bio2)
-{
- struct bio_bio_st *b1, *b2;
-
- assert(bio1 != NULL);
- assert(bio2 != NULL);
-
- b1 = bio1->ptr;
- b2 = bio2->ptr;
-
- if (b1->peer != NULL || b2->peer != NULL) {
- BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE);
- return 0;
- }
-
- if (b1->buf == NULL) {
- b1->buf = OPENSSL_malloc(b1->size);
- if (b1->buf == NULL) {
- BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- b1->len = 0;
- b1->offset = 0;
- }
-
- if (b2->buf == NULL) {
- b2->buf = OPENSSL_malloc(b2->size);
- if (b2->buf == NULL) {
- BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- b2->len = 0;
- b2->offset = 0;
- }
-
- b1->peer = bio2;
- b1->closed = 0;
- b1->request = 0;
- b2->peer = bio1;
- b2->closed = 0;
- b2->request = 0;
-
- bio1->init = 1;
- bio2->init = 1;
-
- return 1;
-}
-
-static void bio_destroy_pair(BIO *bio)
-{
- struct bio_bio_st *b = bio->ptr;
-
- if (b != NULL) {
- BIO *peer_bio = b->peer;
-
- if (peer_bio != NULL) {
- struct bio_bio_st *peer_b = peer_bio->ptr;
-
- assert(peer_b != NULL);
- assert(peer_b->peer == bio);
-
- peer_b->peer = NULL;
- peer_bio->init = 0;
- assert(peer_b->buf != NULL);
- peer_b->len = 0;
- peer_b->offset = 0;
-
- b->peer = NULL;
- bio->init = 0;
- assert(b->buf != NULL);
- b->len = 0;
- b->offset = 0;
- }
- }
-}
-
-/* Exported convenience functions */
-int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1,
- BIO **bio2_p, size_t writebuf2)
-{
- BIO *bio1 = NULL, *bio2 = NULL;
- long r;
- int ret = 0;
-
- bio1 = BIO_new(BIO_s_bio());
- if (bio1 == NULL)
- goto err;
- bio2 = BIO_new(BIO_s_bio());
- if (bio2 == NULL)
- goto err;
-
- if (writebuf1) {
- r = BIO_set_write_buf_size(bio1, writebuf1);
- if (!r)
- goto err;
- }
- if (writebuf2) {
- r = BIO_set_write_buf_size(bio2, writebuf2);
- if (!r)
- goto err;
- }
-
- r = BIO_make_bio_pair(bio1, bio2);
- if (!r)
- goto err;
- ret = 1;
-
- err:
- if (ret == 0) {
- BIO_free(bio1);
- bio1 = NULL;
- BIO_free(bio2);
- bio2 = NULL;
- }
-
- *bio1_p = bio1;
- *bio2_p = bio2;
- return ret;
-}
-
-size_t BIO_ctrl_get_write_guarantee(BIO *bio)
-{
- return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
-}
-
-size_t BIO_ctrl_get_read_request(BIO *bio)
-{
- return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
-}
-
-int BIO_ctrl_reset_read_request(BIO *bio)
-{
- return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0);
-}
-
-/*
- * BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now
- * (conceivably some other BIOs could allow non-copying reads and writes
- * too.)
- */
-int BIO_nread0(BIO *bio, char **buf)
-{
- long ret;
-
- if (!bio->init) {
- BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED);
- return -2;
- }
-
- ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf);
- if (ret > INT_MAX)
- return INT_MAX;
- else
- return (int)ret;
-}
-
-int BIO_nread(BIO *bio, char **buf, int num)
-{
- int ret;
-
- if (!bio->init) {
- BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED);
- return -2;
- }
-
- ret = (int)BIO_ctrl(bio, BIO_C_NREAD, num, buf);
- if (ret > 0)
- bio->num_read += ret;
- return ret;
-}
-
-int BIO_nwrite0(BIO *bio, char **buf)
-{
- long ret;
-
- if (!bio->init) {
- BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED);
- return -2;
- }
-
- ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf);
- if (ret > INT_MAX)
- return INT_MAX;
- else
- return (int)ret;
-}
-
-int BIO_nwrite(BIO *bio, char **buf, int num)
-{
- int ret;
-
- if (!bio->init) {
- BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED);
- return -2;
- }
-
- ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf);
- if (ret > 0)
- bio->num_write += ret;
- return ret;
-}
+#include <openssl/err.h>
+#include <openssl/crypto.h>
+
+static int bio_new(BIO *bio);
+static int bio_free(BIO *bio);
+static int bio_read(BIO *bio, char *buf, int size);
+static int bio_write(BIO *bio, const char *buf, int num);
+static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr);
+static int bio_puts(BIO *bio, const char *str);
+
+static int bio_make_pair(BIO *bio1, BIO *bio2);
+static void bio_destroy_pair(BIO *bio);
+
+static const BIO_METHOD methods_biop = {
+ BIO_TYPE_BIO,
+ "BIO pair",
+ /* TODO: Convert to new style write function */
+ bwrite_conv,
+ bio_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
+ bio_read,
+ bio_puts,
+ NULL /* no bio_gets */ ,
+ bio_ctrl,
+ bio_new,
+ bio_free,
+ NULL /* no bio_callback_ctrl */
+};
+
+const BIO_METHOD *BIO_s_bio(void)
+{
+ return &methods_biop;
+}
+
+struct bio_bio_st {
+ BIO *peer; /* NULL if buf == NULL. If peer != NULL, then
+ * peer->ptr is also a bio_bio_st, and its
+ * "peer" member points back to us. peer !=
+ * NULL iff init != 0 in the BIO. */
+ /* This is for what we write (i.e. reading uses peer's struct): */
+ int closed; /* valid iff peer != NULL */
+ size_t len; /* valid iff buf != NULL; 0 if peer == NULL */
+ size_t offset; /* valid iff buf != NULL; 0 if len == 0 */
+ size_t size;
+ char *buf; /* "size" elements (if != NULL) */
+ size_t request; /* valid iff peer != NULL; 0 if len != 0,
+ * otherwise set by peer to number of bytes
+ * it (unsuccessfully) tried to read, never
+ * more than buffer space (size-len)
+ * warrants. */
+};
+
+static int bio_new(BIO *bio)
+{
+ struct bio_bio_st *b = OPENSSL_zalloc(sizeof(*b));
+
+ if (b == NULL)
+ return 0;
+
+ /* enough for one TLS record (just a default) */
+ b->size = 17 * 1024;
+
+ bio->ptr = b;
+ return 1;
+}
+
+static int bio_free(BIO *bio)
+{
+ struct bio_bio_st *b;
+
+ if (bio == NULL)
+ return 0;
+ b = bio->ptr;
+
+ assert(b != NULL);
+
+ if (b->peer)
+ bio_destroy_pair(bio);
+
+ OPENSSL_free(b->buf);
+ OPENSSL_free(b);
+
+ return 1;
+}
+
+static int bio_read(BIO *bio, char *buf, int size_)
+{
+ size_t size = size_;
+ size_t rest;
+ struct bio_bio_st *b, *peer_b;
+
+ BIO_clear_retry_flags(bio);
+
+ if (!bio->init)
+ return 0;
+
+ b = bio->ptr;
+ assert(b != NULL);
+ assert(b->peer != NULL);
+ peer_b = b->peer->ptr;
+ assert(peer_b != NULL);
+ assert(peer_b->buf != NULL);
+
+ peer_b->request = 0; /* will be set in "retry_read" situation */
+
+ if (buf == NULL || size == 0)
+ return 0;
+
+ if (peer_b->len == 0) {
+ if (peer_b->closed)
+ return 0; /* writer has closed, and no data is left */
+ else {
+ BIO_set_retry_read(bio); /* buffer is empty */
+ if (size <= peer_b->size)
+ peer_b->request = size;
+ else
+ /*
+ * don't ask for more than the peer can deliver in one write
+ */
+ peer_b->request = peer_b->size;
+ return -1;
+ }
+ }
+
+ /* we can read */
+ if (peer_b->len < size)
+ size = peer_b->len;
+
+ /* now read "size" bytes */
+
+ rest = size;
+
+ assert(rest > 0);
+ do { /* one or two iterations */
+ size_t chunk;
+
+ assert(rest <= peer_b->len);
+ if (peer_b->offset + rest <= peer_b->size)
+ chunk = rest;
+ else
+ /* wrap around ring buffer */
+ chunk = peer_b->size - peer_b->offset;
+ assert(peer_b->offset + chunk <= peer_b->size);
+
+ memcpy(buf, peer_b->buf + peer_b->offset, chunk);
+
+ peer_b->len -= chunk;
+ if (peer_b->len) {
+ peer_b->offset += chunk;
+ assert(peer_b->offset <= peer_b->size);
+ if (peer_b->offset == peer_b->size)
+ peer_b->offset = 0;
+ buf += chunk;
+ } else {
+ /* buffer now empty, no need to advance "buf" */
+ assert(chunk == rest);
+ peer_b->offset = 0;
+ }
+ rest -= chunk;
+ }
+ while (rest);
+
+ return size;
+}
+
+/*-
+ * non-copying interface: provide pointer to available data in buffer
+ * bio_nread0: return number of available bytes
+ * bio_nread: also advance index
+ * (example usage: bio_nread0(), read from buffer, bio_nread()
+ * or just bio_nread(), read from buffer)
+ */
+/*
+ * WARNING: The non-copying interface is largely untested as of yet and may
+ * contain bugs.
+ */
+static ossl_ssize_t bio_nread0(BIO *bio, char **buf)
+{
+ struct bio_bio_st *b, *peer_b;
+ ossl_ssize_t num;
+
+ BIO_clear_retry_flags(bio);
+
+ if (!bio->init)
+ return 0;
+
+ b = bio->ptr;
+ assert(b != NULL);
+ assert(b->peer != NULL);
+ peer_b = b->peer->ptr;
+ assert(peer_b != NULL);
+ assert(peer_b->buf != NULL);
+
+ peer_b->request = 0;
+
+ if (peer_b->len == 0) {
+ char dummy;
+
+ /* avoid code duplication -- nothing available for reading */
+ return bio_read(bio, &dummy, 1); /* returns 0 or -1 */
+ }
+
+ num = peer_b->len;
+ if (peer_b->size < peer_b->offset + num)
+ /* no ring buffer wrap-around for non-copying interface */
+ num = peer_b->size - peer_b->offset;
+ assert(num > 0);
+
+ if (buf != NULL)
+ *buf = peer_b->buf + peer_b->offset;
+ return num;
+}
+
+static ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_)
+{
+ struct bio_bio_st *b, *peer_b;
+ ossl_ssize_t num, available;
+
+ if (num_ > OSSL_SSIZE_MAX)
+ num = OSSL_SSIZE_MAX;
+ else
+ num = (ossl_ssize_t) num_;
+
+ available = bio_nread0(bio, buf);
+ if (num > available)
+ num = available;
+ if (num <= 0)
+ return num;
+
+ b = bio->ptr;
+ peer_b = b->peer->ptr;
+
+ peer_b->len -= num;
+ if (peer_b->len) {
+ peer_b->offset += num;
+ assert(peer_b->offset <= peer_b->size);
+ if (peer_b->offset == peer_b->size)
+ peer_b->offset = 0;
+ } else
+ peer_b->offset = 0;
+
+ return num;
+}
+
+static int bio_write(BIO *bio, const char *buf, int num_)
+{
+ size_t num = num_;
+ size_t rest;
+ struct bio_bio_st *b;
+
+ BIO_clear_retry_flags(bio);
+
+ if (!bio->init || buf == NULL || num == 0)
+ return 0;
+
+ b = bio->ptr;
+ assert(b != NULL);
+ assert(b->peer != NULL);
+ assert(b->buf != NULL);
+
+ b->request = 0;
+ if (b->closed) {
+ /* we already closed */
+ BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE);
+ return -1;
+ }
+
+ assert(b->len <= b->size);
+
+ if (b->len == b->size) {
+ BIO_set_retry_write(bio); /* buffer is full */
+ return -1;
+ }
+
+ /* we can write */
+ if (num > b->size - b->len)
+ num = b->size - b->len;
+
+ /* now write "num" bytes */
+
+ rest = num;
+
+ assert(rest > 0);
+ do { /* one or two iterations */
+ size_t write_offset;
+ size_t chunk;
+
+ assert(b->len + rest <= b->size);
+
+ write_offset = b->offset + b->len;
+ if (write_offset >= b->size)
+ write_offset -= b->size;
+ /* b->buf[write_offset] is the first byte we can write to. */
+
+ if (write_offset + rest <= b->size)
+ chunk = rest;
+ else
+ /* wrap around ring buffer */
+ chunk = b->size - write_offset;
+
+ memcpy(b->buf + write_offset, buf, chunk);
+
+ b->len += chunk;
+
+ assert(b->len <= b->size);
+
+ rest -= chunk;
+ buf += chunk;
+ }
+ while (rest);
+
+ return num;
+}
+
+/*-
+ * non-copying interface: provide pointer to region to write to
+ * bio_nwrite0: check how much space is available
+ * bio_nwrite: also increase length
+ * (example usage: bio_nwrite0(), write to buffer, bio_nwrite()
+ * or just bio_nwrite(), write to buffer)
+ */
+static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf)
+{
+ struct bio_bio_st *b;
+ size_t num;
+ size_t write_offset;
+
+ BIO_clear_retry_flags(bio);
+
+ if (!bio->init)
+ return 0;
+
+ b = bio->ptr;
+ assert(b != NULL);
+ assert(b->peer != NULL);
+ assert(b->buf != NULL);
+
+ b->request = 0;
+ if (b->closed) {
+ BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE);
+ return -1;
+ }
+
+ assert(b->len <= b->size);
+
+ if (b->len == b->size) {
+ BIO_set_retry_write(bio);
+ return -1;
+ }
+
+ num = b->size - b->len;
+ write_offset = b->offset + b->len;
+ if (write_offset >= b->size)
+ write_offset -= b->size;
+ if (write_offset + num > b->size)
+ /*
+ * no ring buffer wrap-around for non-copying interface (to fulfil
+ * the promise by BIO_ctrl_get_write_guarantee, BIO_nwrite may have
+ * to be called twice)
+ */
+ num = b->size - write_offset;
+
+ if (buf != NULL)
+ *buf = b->buf + write_offset;
+ assert(write_offset + num <= b->size);
+
+ return num;
+}
+
+static ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_)
+{
+ struct bio_bio_st *b;
+ ossl_ssize_t num, space;
+
+ if (num_ > OSSL_SSIZE_MAX)
+ num = OSSL_SSIZE_MAX;
+ else
+ num = (ossl_ssize_t) num_;
+
+ space = bio_nwrite0(bio, buf);
+ if (num > space)
+ num = space;
+ if (num <= 0)
+ return num;
+ b = bio->ptr;
+ assert(b != NULL);
+ b->len += num;
+ assert(b->len <= b->size);
+
+ return num;
+}
+
+static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
+{
+ long ret;
+ struct bio_bio_st *b = bio->ptr;
+
+ assert(b != NULL);
+
+ switch (cmd) {
+ /* specific CTRL codes */
+
+ case BIO_C_SET_WRITE_BUF_SIZE:
+ if (b->peer) {
+ BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE);
+ ret = 0;
+ } else if (num == 0) {
+ BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT);
+ ret = 0;
+ } else {
+ size_t new_size = num;
+
+ if (b->size != new_size) {
+ OPENSSL_free(b->buf);
+ b->buf = NULL;
+ b->size = new_size;
+ }
+ ret = 1;
+ }
+ break;
+
+ case BIO_C_GET_WRITE_BUF_SIZE:
+ ret = (long)b->size;
+ break;
+
+ case BIO_C_MAKE_BIO_PAIR:
+ {
+ BIO *other_bio = ptr;
+
+ if (bio_make_pair(bio, other_bio))
+ ret = 1;
+ else
+ ret = 0;
+ }
+ break;
+
+ case BIO_C_DESTROY_BIO_PAIR:
+ /*
+ * Affects both BIOs in the pair -- call just once! Or let
+ * BIO_free(bio1); BIO_free(bio2); do the job.
+ */
+ bio_destroy_pair(bio);
+ ret = 1;
+ break;
+
+ case BIO_C_GET_WRITE_GUARANTEE:
+ /*
+ * How many bytes can the caller feed to the next write without
+ * having to keep any?
+ */
+ if (b->peer == NULL || b->closed)
+ ret = 0;
+ else
+ ret = (long)b->size - b->len;
+ break;
+
+ case BIO_C_GET_READ_REQUEST:
+ /*
+ * If the peer unsuccessfully tried to read, how many bytes were
+ * requested? (As with BIO_CTRL_PENDING, that number can usually be
+ * treated as boolean.)
+ */
+ ret = (long)b->request;
+ break;
+
+ case BIO_C_RESET_READ_REQUEST:
+ /*
+ * Reset request. (Can be useful after read attempts at the other
+ * side that are meant to be non-blocking, e.g. when probing SSL_read
+ * to see if any data is available.)
+ */
+ b->request = 0;
+ ret = 1;
+ break;
+
+ case BIO_C_SHUTDOWN_WR:
+ /* similar to shutdown(..., SHUT_WR) */
+ b->closed = 1;
+ ret = 1;
+ break;
+
+ case BIO_C_NREAD0:
+ /* prepare for non-copying read */
+ ret = (long)bio_nread0(bio, ptr);
+ break;
+
+ case BIO_C_NREAD:
+ /* non-copying read */
+ ret = (long)bio_nread(bio, ptr, (size_t)num);
+ break;
+
+ case BIO_C_NWRITE0:
+ /* prepare for non-copying write */
+ ret = (long)bio_nwrite0(bio, ptr);
+ break;
+
+ case BIO_C_NWRITE:
+ /* non-copying write */
+ ret = (long)bio_nwrite(bio, ptr, (size_t)num);
+ break;
+
+ /* standard CTRL codes follow */
+
+ case BIO_CTRL_RESET:
+ if (b->buf != NULL) {
+ b->len = 0;
+ b->offset = 0;
+ }
+ ret = 0;
+ break;
+
+ case BIO_CTRL_GET_CLOSE:
+ ret = bio->shutdown;
+ break;
+
+ case BIO_CTRL_SET_CLOSE:
+ bio->shutdown = (int)num;
+ ret = 1;
+ break;
+
+ case BIO_CTRL_PENDING:
+ if (b->peer != NULL) {
+ struct bio_bio_st *peer_b = b->peer->ptr;
+
+ ret = (long)peer_b->len;
+ } else
+ ret = 0;
+ break;
+
+ case BIO_CTRL_WPENDING:
+ if (b->buf != NULL)
+ ret = (long)b->len;
+ else
+ ret = 0;
+ break;
+
+ case BIO_CTRL_DUP:
+ /* See BIO_dup_chain for circumstances we have to expect. */
+ {
+ BIO *other_bio = ptr;
+ struct bio_bio_st *other_b;
+
+ assert(other_bio != NULL);
+ other_b = other_bio->ptr;
+ assert(other_b != NULL);
+
+ assert(other_b->buf == NULL); /* other_bio is always fresh */
+
+ other_b->size = b->size;
+ }
+
+ ret = 1;
+ break;
+
+ case BIO_CTRL_FLUSH:
+ ret = 1;
+ break;
+
+ case BIO_CTRL_EOF:
+ if (b->peer != NULL) {
+ struct bio_bio_st *peer_b = b->peer->ptr;
+
+ if (peer_b->len == 0 && peer_b->closed)
+ ret = 1;
+ else
+ ret = 0;
+ } else {
+ ret = 1;
+ }
+ break;
+
+ default:
+ ret = 0;
+ }
+ return ret;
+}
+
+static int bio_puts(BIO *bio, const char *str)
+{
+ return bio_write(bio, str, strlen(str));
+}
+
+static int bio_make_pair(BIO *bio1, BIO *bio2)
+{
+ struct bio_bio_st *b1, *b2;
+
+ assert(bio1 != NULL);
+ assert(bio2 != NULL);
+
+ b1 = bio1->ptr;
+ b2 = bio2->ptr;
+
+ if (b1->peer != NULL || b2->peer != NULL) {
+ BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE);
+ return 0;
+ }
+
+ if (b1->buf == NULL) {
+ b1->buf = OPENSSL_malloc(b1->size);
+ if (b1->buf == NULL) {
+ BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ b1->len = 0;
+ b1->offset = 0;
+ }
+
+ if (b2->buf == NULL) {
+ b2->buf = OPENSSL_malloc(b2->size);
+ if (b2->buf == NULL) {
+ BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ b2->len = 0;
+ b2->offset = 0;
+ }
+
+ b1->peer = bio2;
+ b1->closed = 0;
+ b1->request = 0;
+ b2->peer = bio1;
+ b2->closed = 0;
+ b2->request = 0;
+
+ bio1->init = 1;
+ bio2->init = 1;
+
+ return 1;
+}
+
+static void bio_destroy_pair(BIO *bio)
+{
+ struct bio_bio_st *b = bio->ptr;
+
+ if (b != NULL) {
+ BIO *peer_bio = b->peer;
+
+ if (peer_bio != NULL) {
+ struct bio_bio_st *peer_b = peer_bio->ptr;
+
+ assert(peer_b != NULL);
+ assert(peer_b->peer == bio);
+
+ peer_b->peer = NULL;
+ peer_bio->init = 0;
+ assert(peer_b->buf != NULL);
+ peer_b->len = 0;
+ peer_b->offset = 0;
+
+ b->peer = NULL;
+ bio->init = 0;
+ assert(b->buf != NULL);
+ b->len = 0;
+ b->offset = 0;
+ }
+ }
+}
+
+/* Exported convenience functions */
+int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1,
+ BIO **bio2_p, size_t writebuf2)
+{
+ BIO *bio1 = NULL, *bio2 = NULL;
+ long r;
+ int ret = 0;
+
+ bio1 = BIO_new(BIO_s_bio());
+ if (bio1 == NULL)
+ goto err;
+ bio2 = BIO_new(BIO_s_bio());
+ if (bio2 == NULL)
+ goto err;
+
+ if (writebuf1) {
+ r = BIO_set_write_buf_size(bio1, writebuf1);
+ if (!r)
+ goto err;
+ }
+ if (writebuf2) {
+ r = BIO_set_write_buf_size(bio2, writebuf2);
+ if (!r)
+ goto err;
+ }
+
+ r = BIO_make_bio_pair(bio1, bio2);
+ if (!r)
+ goto err;
+ ret = 1;
+
+ err:
+ if (ret == 0) {
+ BIO_free(bio1);
+ bio1 = NULL;
+ BIO_free(bio2);
+ bio2 = NULL;
+ }
+
+ *bio1_p = bio1;
+ *bio2_p = bio2;
+ return ret;
+}
+
+size_t BIO_ctrl_get_write_guarantee(BIO *bio)
+{
+ return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
+}
+
+size_t BIO_ctrl_get_read_request(BIO *bio)
+{
+ return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
+}
+
+int BIO_ctrl_reset_read_request(BIO *bio)
+{
+ return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0);
+}
+
+/*
+ * BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now
+ * (conceivably some other BIOs could allow non-copying reads and writes
+ * too.)
+ */
+int BIO_nread0(BIO *bio, char **buf)
+{
+ long ret;
+
+ if (!bio->init) {
+ BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED);
+ return -2;
+ }
+
+ ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf);
+ if (ret > INT_MAX)
+ return INT_MAX;
+ else
+ return (int)ret;
+}
+
+int BIO_nread(BIO *bio, char **buf, int num)
+{
+ int ret;
+
+ if (!bio->init) {
+ BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED);
+ return -2;
+ }
+
+ ret = (int)BIO_ctrl(bio, BIO_C_NREAD, num, buf);
+ if (ret > 0)
+ bio->num_read += ret;
+ return ret;
+}
+
+int BIO_nwrite0(BIO *bio, char **buf)
+{
+ long ret;
+
+ if (!bio->init) {
+ BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED);
+ return -2;
+ }
+
+ ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf);
+ if (ret > INT_MAX)
+ return INT_MAX;
+ else
+ return (int)ret;
+}
+
+int BIO_nwrite(BIO *bio, char **buf, int num)
+{
+ int ret;
+
+ if (!bio->init) {
+ BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED);
+ return -2;
+ }
+
+ ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf);
+ if (ret > 0)
+ bio->num_write += ret;
+ return ret;
+}
diff --git a/contrib/libs/openssl/crypto/bio/bss_conn.c b/contrib/libs/openssl/crypto/bio/bss_conn.c
index 338aaff555..807a82b23b 100644
--- a/contrib/libs/openssl/crypto/bio/bss_conn.c
+++ b/contrib/libs/openssl/crypto/bio/bss_conn.c
@@ -1,193 +1,193 @@
-/*
+/*
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include <errno.h>
-
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <errno.h>
+
#include "bio_local.h"
-
-#ifndef OPENSSL_NO_SOCK
-
-typedef struct bio_connect_st {
- int state;
- int connect_family;
- char *param_hostname;
- char *param_service;
- int connect_mode;
-
- BIO_ADDRINFO *addr_first;
- const BIO_ADDRINFO *addr_iter;
- /*
- * int socket; this will be kept in bio->num so that it is compatible
- * with the bss_sock bio
- */
- /*
- * called when the connection is initially made callback(BIO,state,ret);
- * The callback should return 'ret'. state is for compatibility with the
- * ssl info_callback
- */
- BIO_info_cb *info_callback;
-} BIO_CONNECT;
-
-static int conn_write(BIO *h, const char *buf, int num);
-static int conn_read(BIO *h, char *buf, int size);
-static int conn_puts(BIO *h, const char *str);
-static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-static int conn_new(BIO *h);
-static int conn_free(BIO *data);
-static long conn_callback_ctrl(BIO *h, int cmd, BIO_info_cb *);
-
-static int conn_state(BIO *b, BIO_CONNECT *c);
-static void conn_close_socket(BIO *data);
-BIO_CONNECT *BIO_CONNECT_new(void);
-void BIO_CONNECT_free(BIO_CONNECT *a);
-
-#define BIO_CONN_S_BEFORE 1
-#define BIO_CONN_S_GET_ADDR 2
-#define BIO_CONN_S_CREATE_SOCKET 3
-#define BIO_CONN_S_CONNECT 4
-#define BIO_CONN_S_OK 5
-#define BIO_CONN_S_BLOCKED_CONNECT 6
+
+#ifndef OPENSSL_NO_SOCK
+
+typedef struct bio_connect_st {
+ int state;
+ int connect_family;
+ char *param_hostname;
+ char *param_service;
+ int connect_mode;
+
+ BIO_ADDRINFO *addr_first;
+ const BIO_ADDRINFO *addr_iter;
+ /*
+ * int socket; this will be kept in bio->num so that it is compatible
+ * with the bss_sock bio
+ */
+ /*
+ * called when the connection is initially made callback(BIO,state,ret);
+ * The callback should return 'ret'. state is for compatibility with the
+ * ssl info_callback
+ */
+ BIO_info_cb *info_callback;
+} BIO_CONNECT;
+
+static int conn_write(BIO *h, const char *buf, int num);
+static int conn_read(BIO *h, char *buf, int size);
+static int conn_puts(BIO *h, const char *str);
+static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int conn_new(BIO *h);
+static int conn_free(BIO *data);
+static long conn_callback_ctrl(BIO *h, int cmd, BIO_info_cb *);
+
+static int conn_state(BIO *b, BIO_CONNECT *c);
+static void conn_close_socket(BIO *data);
+BIO_CONNECT *BIO_CONNECT_new(void);
+void BIO_CONNECT_free(BIO_CONNECT *a);
+
+#define BIO_CONN_S_BEFORE 1
+#define BIO_CONN_S_GET_ADDR 2
+#define BIO_CONN_S_CREATE_SOCKET 3
+#define BIO_CONN_S_CONNECT 4
+#define BIO_CONN_S_OK 5
+#define BIO_CONN_S_BLOCKED_CONNECT 6
#define BIO_CONN_S_CONNECT_ERROR 7
-
-static const BIO_METHOD methods_connectp = {
- BIO_TYPE_CONNECT,
- "socket connect",
- /* TODO: Convert to new style write function */
- bwrite_conv,
- conn_write,
- /* TODO: Convert to new style read function */
- bread_conv,
- conn_read,
- conn_puts,
- NULL, /* conn_gets, */
- conn_ctrl,
- conn_new,
- conn_free,
- conn_callback_ctrl,
-};
-
-static int conn_state(BIO *b, BIO_CONNECT *c)
-{
- int ret = -1, i;
- BIO_info_cb *cb = NULL;
-
- if (c->info_callback != NULL)
- cb = c->info_callback;
-
- for (;;) {
- switch (c->state) {
- case BIO_CONN_S_BEFORE:
- if (c->param_hostname == NULL && c->param_service == NULL) {
- BIOerr(BIO_F_CONN_STATE, BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED);
- ERR_add_error_data(4,
- "hostname=", c->param_hostname,
- " service=", c->param_service);
- goto exit_loop;
- }
- c->state = BIO_CONN_S_GET_ADDR;
- break;
-
- case BIO_CONN_S_GET_ADDR:
- {
- int family = AF_UNSPEC;
- switch (c->connect_family) {
- case BIO_FAMILY_IPV6:
- if (1) { /* This is a trick we use to avoid bit rot.
- * at least the "else" part will always be
- * compiled.
- */
-#ifdef AF_INET6
- family = AF_INET6;
- } else {
-#endif
- BIOerr(BIO_F_CONN_STATE, BIO_R_UNAVAILABLE_IP_FAMILY);
- goto exit_loop;
- }
- break;
- case BIO_FAMILY_IPV4:
- family = AF_INET;
- break;
- case BIO_FAMILY_IPANY:
- family = AF_UNSPEC;
- break;
- default:
- BIOerr(BIO_F_CONN_STATE, BIO_R_UNSUPPORTED_IP_FAMILY);
- goto exit_loop;
- }
- if (BIO_lookup(c->param_hostname, c->param_service,
- BIO_LOOKUP_CLIENT,
- family, SOCK_STREAM, &c->addr_first) == 0)
- goto exit_loop;
- }
- if (c->addr_first == NULL) {
- BIOerr(BIO_F_CONN_STATE, BIO_R_LOOKUP_RETURNED_NOTHING);
- goto exit_loop;
- }
- c->addr_iter = c->addr_first;
- c->state = BIO_CONN_S_CREATE_SOCKET;
- break;
-
- case BIO_CONN_S_CREATE_SOCKET:
- ret = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
- BIO_ADDRINFO_socktype(c->addr_iter),
- BIO_ADDRINFO_protocol(c->addr_iter), 0);
- if (ret == (int)INVALID_SOCKET) {
- SYSerr(SYS_F_SOCKET, get_last_socket_error());
- ERR_add_error_data(4,
- "hostname=", c->param_hostname,
- " service=", c->param_service);
- BIOerr(BIO_F_CONN_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET);
- goto exit_loop;
- }
- b->num = ret;
- c->state = BIO_CONN_S_CONNECT;
- break;
-
- case BIO_CONN_S_CONNECT:
- BIO_clear_retry_flags(b);
- ret = BIO_connect(b->num, BIO_ADDRINFO_address(c->addr_iter),
- BIO_SOCK_KEEPALIVE | c->connect_mode);
- b->retry_reason = 0;
- if (ret == 0) {
- if (BIO_sock_should_retry(ret)) {
- BIO_set_retry_special(b);
- c->state = BIO_CONN_S_BLOCKED_CONNECT;
- b->retry_reason = BIO_RR_CONNECT;
- ERR_clear_error();
- } else if ((c->addr_iter = BIO_ADDRINFO_next(c->addr_iter))
- != NULL) {
- /*
- * if there are more addresses to try, do that first
- */
- BIO_closesocket(b->num);
- c->state = BIO_CONN_S_CREATE_SOCKET;
- ERR_clear_error();
- break;
- } else {
- SYSerr(SYS_F_CONNECT, get_last_socket_error());
- ERR_add_error_data(4,
- "hostname=", c->param_hostname,
- " service=", c->param_service);
+
+static const BIO_METHOD methods_connectp = {
+ BIO_TYPE_CONNECT,
+ "socket connect",
+ /* TODO: Convert to new style write function */
+ bwrite_conv,
+ conn_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
+ conn_read,
+ conn_puts,
+ NULL, /* conn_gets, */
+ conn_ctrl,
+ conn_new,
+ conn_free,
+ conn_callback_ctrl,
+};
+
+static int conn_state(BIO *b, BIO_CONNECT *c)
+{
+ int ret = -1, i;
+ BIO_info_cb *cb = NULL;
+
+ if (c->info_callback != NULL)
+ cb = c->info_callback;
+
+ for (;;) {
+ switch (c->state) {
+ case BIO_CONN_S_BEFORE:
+ if (c->param_hostname == NULL && c->param_service == NULL) {
+ BIOerr(BIO_F_CONN_STATE, BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED);
+ ERR_add_error_data(4,
+ "hostname=", c->param_hostname,
+ " service=", c->param_service);
+ goto exit_loop;
+ }
+ c->state = BIO_CONN_S_GET_ADDR;
+ break;
+
+ case BIO_CONN_S_GET_ADDR:
+ {
+ int family = AF_UNSPEC;
+ switch (c->connect_family) {
+ case BIO_FAMILY_IPV6:
+ if (1) { /* This is a trick we use to avoid bit rot.
+ * at least the "else" part will always be
+ * compiled.
+ */
+#ifdef AF_INET6
+ family = AF_INET6;
+ } else {
+#endif
+ BIOerr(BIO_F_CONN_STATE, BIO_R_UNAVAILABLE_IP_FAMILY);
+ goto exit_loop;
+ }
+ break;
+ case BIO_FAMILY_IPV4:
+ family = AF_INET;
+ break;
+ case BIO_FAMILY_IPANY:
+ family = AF_UNSPEC;
+ break;
+ default:
+ BIOerr(BIO_F_CONN_STATE, BIO_R_UNSUPPORTED_IP_FAMILY);
+ goto exit_loop;
+ }
+ if (BIO_lookup(c->param_hostname, c->param_service,
+ BIO_LOOKUP_CLIENT,
+ family, SOCK_STREAM, &c->addr_first) == 0)
+ goto exit_loop;
+ }
+ if (c->addr_first == NULL) {
+ BIOerr(BIO_F_CONN_STATE, BIO_R_LOOKUP_RETURNED_NOTHING);
+ goto exit_loop;
+ }
+ c->addr_iter = c->addr_first;
+ c->state = BIO_CONN_S_CREATE_SOCKET;
+ break;
+
+ case BIO_CONN_S_CREATE_SOCKET:
+ ret = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
+ BIO_ADDRINFO_socktype(c->addr_iter),
+ BIO_ADDRINFO_protocol(c->addr_iter), 0);
+ if (ret == (int)INVALID_SOCKET) {
+ SYSerr(SYS_F_SOCKET, get_last_socket_error());
+ ERR_add_error_data(4,
+ "hostname=", c->param_hostname,
+ " service=", c->param_service);
+ BIOerr(BIO_F_CONN_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET);
+ goto exit_loop;
+ }
+ b->num = ret;
+ c->state = BIO_CONN_S_CONNECT;
+ break;
+
+ case BIO_CONN_S_CONNECT:
+ BIO_clear_retry_flags(b);
+ ret = BIO_connect(b->num, BIO_ADDRINFO_address(c->addr_iter),
+ BIO_SOCK_KEEPALIVE | c->connect_mode);
+ b->retry_reason = 0;
+ if (ret == 0) {
+ if (BIO_sock_should_retry(ret)) {
+ BIO_set_retry_special(b);
+ c->state = BIO_CONN_S_BLOCKED_CONNECT;
+ b->retry_reason = BIO_RR_CONNECT;
+ ERR_clear_error();
+ } else if ((c->addr_iter = BIO_ADDRINFO_next(c->addr_iter))
+ != NULL) {
+ /*
+ * if there are more addresses to try, do that first
+ */
+ BIO_closesocket(b->num);
+ c->state = BIO_CONN_S_CREATE_SOCKET;
+ ERR_clear_error();
+ break;
+ } else {
+ SYSerr(SYS_F_CONNECT, get_last_socket_error());
+ ERR_add_error_data(4,
+ "hostname=", c->param_hostname,
+ " service=", c->param_service);
c->state = BIO_CONN_S_CONNECT_ERROR;
break;
- }
- goto exit_loop;
- } else {
- c->state = BIO_CONN_S_OK;
- }
- break;
-
- case BIO_CONN_S_BLOCKED_CONNECT:
- i = BIO_sock_error(b->num);
+ }
+ goto exit_loop;
+ } else {
+ c->state = BIO_CONN_S_OK;
+ }
+ break;
+
+ case BIO_CONN_S_BLOCKED_CONNECT:
+ i = BIO_sock_error(b->num);
if (i != 0) {
- BIO_clear_retry_flags(b);
+ BIO_clear_retry_flags(b);
if ((c->addr_iter = BIO_ADDRINFO_next(c->addr_iter)) != NULL) {
/*
* if there are more addresses to try, do that first
@@ -197,376 +197,376 @@ static int conn_state(BIO *b, BIO_CONNECT *c)
ERR_clear_error();
break;
}
- SYSerr(SYS_F_CONNECT, i);
- ERR_add_error_data(4,
- "hostname=", c->param_hostname,
- " service=", c->param_service);
- BIOerr(BIO_F_CONN_STATE, BIO_R_NBIO_CONNECT_ERROR);
- ret = 0;
- goto exit_loop;
- } else
- c->state = BIO_CONN_S_OK;
- break;
-
+ SYSerr(SYS_F_CONNECT, i);
+ ERR_add_error_data(4,
+ "hostname=", c->param_hostname,
+ " service=", c->param_service);
+ BIOerr(BIO_F_CONN_STATE, BIO_R_NBIO_CONNECT_ERROR);
+ ret = 0;
+ goto exit_loop;
+ } else
+ c->state = BIO_CONN_S_OK;
+ break;
+
case BIO_CONN_S_CONNECT_ERROR:
BIOerr(BIO_F_CONN_STATE, BIO_R_CONNECT_ERROR);
ret = 0;
goto exit_loop;
- case BIO_CONN_S_OK:
- ret = 1;
- goto exit_loop;
- default:
- /* abort(); */
- goto exit_loop;
- }
-
- if (cb != NULL) {
- if ((ret = cb((BIO *)b, c->state, ret)) == 0)
- goto end;
- }
- }
-
- /* Loop does not exit */
- exit_loop:
- if (cb != NULL)
- ret = cb((BIO *)b, c->state, ret);
- end:
- return ret;
-}
-
-BIO_CONNECT *BIO_CONNECT_new(void)
-{
- BIO_CONNECT *ret;
-
- if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
- BIOerr(BIO_F_BIO_CONNECT_NEW, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- ret->state = BIO_CONN_S_BEFORE;
- ret->connect_family = BIO_FAMILY_IPANY;
- return ret;
-}
-
-void BIO_CONNECT_free(BIO_CONNECT *a)
-{
- if (a == NULL)
- return;
- OPENSSL_free(a->param_hostname);
- OPENSSL_free(a->param_service);
- BIO_ADDRINFO_free(a->addr_first);
- OPENSSL_free(a);
-}
-
-const BIO_METHOD *BIO_s_connect(void)
-{
- return &methods_connectp;
-}
-
-static int conn_new(BIO *bi)
-{
- bi->init = 0;
- bi->num = (int)INVALID_SOCKET;
- bi->flags = 0;
- if ((bi->ptr = (char *)BIO_CONNECT_new()) == NULL)
- return 0;
- else
- return 1;
-}
-
-static void conn_close_socket(BIO *bio)
-{
- BIO_CONNECT *c;
-
- c = (BIO_CONNECT *)bio->ptr;
- if (bio->num != (int)INVALID_SOCKET) {
- /* Only do a shutdown if things were established */
- if (c->state == BIO_CONN_S_OK)
- shutdown(bio->num, 2);
- BIO_closesocket(bio->num);
- bio->num = (int)INVALID_SOCKET;
- }
-}
-
-static int conn_free(BIO *a)
-{
- BIO_CONNECT *data;
-
- if (a == NULL)
- return 0;
- data = (BIO_CONNECT *)a->ptr;
-
- if (a->shutdown) {
- conn_close_socket(a);
- BIO_CONNECT_free(data);
- a->ptr = NULL;
- a->flags = 0;
- a->init = 0;
- }
- return 1;
-}
-
-static int conn_read(BIO *b, char *out, int outl)
-{
- int ret = 0;
- BIO_CONNECT *data;
-
- data = (BIO_CONNECT *)b->ptr;
- if (data->state != BIO_CONN_S_OK) {
- ret = conn_state(b, data);
- if (ret <= 0)
- return ret;
- }
-
- if (out != NULL) {
- clear_socket_error();
- ret = readsocket(b->num, out, outl);
- BIO_clear_retry_flags(b);
- if (ret <= 0) {
- if (BIO_sock_should_retry(ret))
- BIO_set_retry_read(b);
+ case BIO_CONN_S_OK:
+ ret = 1;
+ goto exit_loop;
+ default:
+ /* abort(); */
+ goto exit_loop;
+ }
+
+ if (cb != NULL) {
+ if ((ret = cb((BIO *)b, c->state, ret)) == 0)
+ goto end;
+ }
+ }
+
+ /* Loop does not exit */
+ exit_loop:
+ if (cb != NULL)
+ ret = cb((BIO *)b, c->state, ret);
+ end:
+ return ret;
+}
+
+BIO_CONNECT *BIO_CONNECT_new(void)
+{
+ BIO_CONNECT *ret;
+
+ if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
+ BIOerr(BIO_F_BIO_CONNECT_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ ret->state = BIO_CONN_S_BEFORE;
+ ret->connect_family = BIO_FAMILY_IPANY;
+ return ret;
+}
+
+void BIO_CONNECT_free(BIO_CONNECT *a)
+{
+ if (a == NULL)
+ return;
+ OPENSSL_free(a->param_hostname);
+ OPENSSL_free(a->param_service);
+ BIO_ADDRINFO_free(a->addr_first);
+ OPENSSL_free(a);
+}
+
+const BIO_METHOD *BIO_s_connect(void)
+{
+ return &methods_connectp;
+}
+
+static int conn_new(BIO *bi)
+{
+ bi->init = 0;
+ bi->num = (int)INVALID_SOCKET;
+ bi->flags = 0;
+ if ((bi->ptr = (char *)BIO_CONNECT_new()) == NULL)
+ return 0;
+ else
+ return 1;
+}
+
+static void conn_close_socket(BIO *bio)
+{
+ BIO_CONNECT *c;
+
+ c = (BIO_CONNECT *)bio->ptr;
+ if (bio->num != (int)INVALID_SOCKET) {
+ /* Only do a shutdown if things were established */
+ if (c->state == BIO_CONN_S_OK)
+ shutdown(bio->num, 2);
+ BIO_closesocket(bio->num);
+ bio->num = (int)INVALID_SOCKET;
+ }
+}
+
+static int conn_free(BIO *a)
+{
+ BIO_CONNECT *data;
+
+ if (a == NULL)
+ return 0;
+ data = (BIO_CONNECT *)a->ptr;
+
+ if (a->shutdown) {
+ conn_close_socket(a);
+ BIO_CONNECT_free(data);
+ a->ptr = NULL;
+ a->flags = 0;
+ a->init = 0;
+ }
+ return 1;
+}
+
+static int conn_read(BIO *b, char *out, int outl)
+{
+ int ret = 0;
+ BIO_CONNECT *data;
+
+ data = (BIO_CONNECT *)b->ptr;
+ if (data->state != BIO_CONN_S_OK) {
+ ret = conn_state(b, data);
+ if (ret <= 0)
+ return ret;
+ }
+
+ if (out != NULL) {
+ clear_socket_error();
+ ret = readsocket(b->num, out, outl);
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_sock_should_retry(ret))
+ BIO_set_retry_read(b);
else if (ret == 0)
b->flags |= BIO_FLAGS_IN_EOF;
- }
- }
- return ret;
-}
-
-static int conn_write(BIO *b, const char *in, int inl)
-{
- int ret;
- BIO_CONNECT *data;
-
- data = (BIO_CONNECT *)b->ptr;
- if (data->state != BIO_CONN_S_OK) {
- ret = conn_state(b, data);
- if (ret <= 0)
- return ret;
- }
-
- clear_socket_error();
- ret = writesocket(b->num, in, inl);
- BIO_clear_retry_flags(b);
- if (ret <= 0) {
- if (BIO_sock_should_retry(ret))
- BIO_set_retry_write(b);
- }
- return ret;
-}
-
-static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
-{
- BIO *dbio;
- int *ip;
- const char **pptr = NULL;
- long ret = 1;
- BIO_CONNECT *data;
-
- data = (BIO_CONNECT *)b->ptr;
-
- switch (cmd) {
- case BIO_CTRL_RESET:
- ret = 0;
- data->state = BIO_CONN_S_BEFORE;
- conn_close_socket(b);
- BIO_ADDRINFO_free(data->addr_first);
- data->addr_first = NULL;
- b->flags = 0;
- break;
- case BIO_C_DO_STATE_MACHINE:
- /* use this one to start the connection */
- if (data->state != BIO_CONN_S_OK)
- ret = (long)conn_state(b, data);
- else
- ret = 1;
- break;
- case BIO_C_GET_CONNECT:
- if (ptr != NULL) {
- pptr = (const char **)ptr;
- if (num == 0) {
- *pptr = data->param_hostname;
- } else if (num == 1) {
- *pptr = data->param_service;
- } else if (num == 2) {
- *pptr = (const char *)BIO_ADDRINFO_address(data->addr_iter);
- } else if (num == 3) {
- switch (BIO_ADDRINFO_family(data->addr_iter)) {
-# ifdef AF_INET6
- case AF_INET6:
- ret = BIO_FAMILY_IPV6;
- break;
-# endif
- case AF_INET:
- ret = BIO_FAMILY_IPV4;
- break;
- case 0:
- ret = data->connect_family;
- break;
- default:
- ret = -1;
- break;
- }
- } else {
- ret = 0;
- }
- } else {
- ret = 0;
- }
- break;
- case BIO_C_SET_CONNECT:
- if (ptr != NULL) {
- b->init = 1;
+ }
+ }
+ return ret;
+}
+
+static int conn_write(BIO *b, const char *in, int inl)
+{
+ int ret;
+ BIO_CONNECT *data;
+
+ data = (BIO_CONNECT *)b->ptr;
+ if (data->state != BIO_CONN_S_OK) {
+ ret = conn_state(b, data);
+ if (ret <= 0)
+ return ret;
+ }
+
+ clear_socket_error();
+ ret = writesocket(b->num, in, inl);
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_sock_should_retry(ret))
+ BIO_set_retry_write(b);
+ }
+ return ret;
+}
+
+static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ BIO *dbio;
+ int *ip;
+ const char **pptr = NULL;
+ long ret = 1;
+ BIO_CONNECT *data;
+
+ data = (BIO_CONNECT *)b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ ret = 0;
+ data->state = BIO_CONN_S_BEFORE;
+ conn_close_socket(b);
+ BIO_ADDRINFO_free(data->addr_first);
+ data->addr_first = NULL;
+ b->flags = 0;
+ break;
+ case BIO_C_DO_STATE_MACHINE:
+ /* use this one to start the connection */
+ if (data->state != BIO_CONN_S_OK)
+ ret = (long)conn_state(b, data);
+ else
+ ret = 1;
+ break;
+ case BIO_C_GET_CONNECT:
+ if (ptr != NULL) {
+ pptr = (const char **)ptr;
+ if (num == 0) {
+ *pptr = data->param_hostname;
+ } else if (num == 1) {
+ *pptr = data->param_service;
+ } else if (num == 2) {
+ *pptr = (const char *)BIO_ADDRINFO_address(data->addr_iter);
+ } else if (num == 3) {
+ switch (BIO_ADDRINFO_family(data->addr_iter)) {
+# ifdef AF_INET6
+ case AF_INET6:
+ ret = BIO_FAMILY_IPV6;
+ break;
+# endif
+ case AF_INET:
+ ret = BIO_FAMILY_IPV4;
+ break;
+ case 0:
+ ret = data->connect_family;
+ break;
+ default:
+ ret = -1;
+ break;
+ }
+ } else {
+ ret = 0;
+ }
+ } else {
+ ret = 0;
+ }
+ break;
+ case BIO_C_SET_CONNECT:
+ if (ptr != NULL) {
+ b->init = 1;
if (num == 0) { /* BIO_set_conn_hostname */
- char *hold_service = data->param_service;
- /* We affect the hostname regardless. However, the input
- * string might contain a host:service spec, so we must
- * parse it, which might or might not affect the service
- */
-
- OPENSSL_free(data->param_hostname);
- data->param_hostname = NULL;
- ret = BIO_parse_hostserv(ptr,
- &data->param_hostname,
- &data->param_service,
- BIO_PARSE_PRIO_HOST);
- if (hold_service != data->param_service)
- OPENSSL_free(hold_service);
+ char *hold_service = data->param_service;
+ /* We affect the hostname regardless. However, the input
+ * string might contain a host:service spec, so we must
+ * parse it, which might or might not affect the service
+ */
+
+ OPENSSL_free(data->param_hostname);
+ data->param_hostname = NULL;
+ ret = BIO_parse_hostserv(ptr,
+ &data->param_hostname,
+ &data->param_service,
+ BIO_PARSE_PRIO_HOST);
+ if (hold_service != data->param_service)
+ OPENSSL_free(hold_service);
} else if (num == 1) { /* BIO_set_conn_port */
- OPENSSL_free(data->param_service);
+ OPENSSL_free(data->param_service);
if ((data->param_service = OPENSSL_strdup(ptr)) == NULL)
ret = 0;
} else if (num == 2) { /* BIO_set_conn_address */
- const BIO_ADDR *addr = (const BIO_ADDR *)ptr;
+ const BIO_ADDR *addr = (const BIO_ADDR *)ptr;
char *host = BIO_ADDR_hostname_string(addr, 1);
char *service = BIO_ADDR_service_string(addr, 1);
ret = host != NULL && service != NULL;
- if (ret) {
+ if (ret) {
OPENSSL_free(data->param_hostname);
data->param_hostname = host;
OPENSSL_free(data->param_service);
data->param_service = service;
- BIO_ADDRINFO_free(data->addr_first);
- data->addr_first = NULL;
- data->addr_iter = NULL;
+ BIO_ADDRINFO_free(data->addr_first);
+ data->addr_first = NULL;
+ data->addr_iter = NULL;
} else {
OPENSSL_free(host);
OPENSSL_free(service);
- }
+ }
} else if (num == 3) { /* BIO_set_conn_ip_family */
- data->connect_family = *(int *)ptr;
- } else {
- ret = 0;
- }
- }
- break;
- case BIO_C_SET_NBIO:
- if (num != 0)
- data->connect_mode |= BIO_SOCK_NONBLOCK;
- else
- data->connect_mode &= ~BIO_SOCK_NONBLOCK;
- break;
- case BIO_C_SET_CONNECT_MODE:
- data->connect_mode = (int)num;
- break;
- case BIO_C_GET_FD:
- if (b->init) {
- ip = (int *)ptr;
- if (ip != NULL)
- *ip = b->num;
- ret = b->num;
- } else
- ret = -1;
- break;
- case BIO_CTRL_GET_CLOSE:
- ret = b->shutdown;
- break;
- case BIO_CTRL_SET_CLOSE:
- b->shutdown = (int)num;
- break;
- case BIO_CTRL_PENDING:
- case BIO_CTRL_WPENDING:
- ret = 0;
- break;
- case BIO_CTRL_FLUSH:
- break;
- case BIO_CTRL_DUP:
- {
- dbio = (BIO *)ptr;
- if (data->param_hostname)
- BIO_set_conn_hostname(dbio, data->param_hostname);
- if (data->param_service)
- BIO_set_conn_port(dbio, data->param_service);
- BIO_set_conn_ip_family(dbio, data->connect_family);
- BIO_set_conn_mode(dbio, data->connect_mode);
- /*
- * FIXME: the cast of the function seems unlikely to be a good
- * idea
- */
- (void)BIO_set_info_callback(dbio, data->info_callback);
- }
- break;
- case BIO_CTRL_SET_CALLBACK:
- ret = 0; /* use callback ctrl */
- break;
- case BIO_CTRL_GET_CALLBACK:
- {
- BIO_info_cb **fptr;
-
- fptr = (BIO_info_cb **)ptr;
- *fptr = data->info_callback;
- }
- break;
+ data->connect_family = *(int *)ptr;
+ } else {
+ ret = 0;
+ }
+ }
+ break;
+ case BIO_C_SET_NBIO:
+ if (num != 0)
+ data->connect_mode |= BIO_SOCK_NONBLOCK;
+ else
+ data->connect_mode &= ~BIO_SOCK_NONBLOCK;
+ break;
+ case BIO_C_SET_CONNECT_MODE:
+ data->connect_mode = (int)num;
+ break;
+ case BIO_C_GET_FD:
+ if (b->init) {
+ ip = (int *)ptr;
+ if (ip != NULL)
+ *ip = b->num;
+ ret = b->num;
+ } else
+ ret = -1;
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret = b->shutdown;
+ break;
+ case BIO_CTRL_SET_CLOSE:
+ b->shutdown = (int)num;
+ break;
+ case BIO_CTRL_PENDING:
+ case BIO_CTRL_WPENDING:
+ ret = 0;
+ break;
+ case BIO_CTRL_FLUSH:
+ break;
+ case BIO_CTRL_DUP:
+ {
+ dbio = (BIO *)ptr;
+ if (data->param_hostname)
+ BIO_set_conn_hostname(dbio, data->param_hostname);
+ if (data->param_service)
+ BIO_set_conn_port(dbio, data->param_service);
+ BIO_set_conn_ip_family(dbio, data->connect_family);
+ BIO_set_conn_mode(dbio, data->connect_mode);
+ /*
+ * FIXME: the cast of the function seems unlikely to be a good
+ * idea
+ */
+ (void)BIO_set_info_callback(dbio, data->info_callback);
+ }
+ break;
+ case BIO_CTRL_SET_CALLBACK:
+ ret = 0; /* use callback ctrl */
+ break;
+ case BIO_CTRL_GET_CALLBACK:
+ {
+ BIO_info_cb **fptr;
+
+ fptr = (BIO_info_cb **)ptr;
+ *fptr = data->info_callback;
+ }
+ break;
case BIO_CTRL_EOF:
ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0;
break;
- default:
- ret = 0;
- break;
- }
- return ret;
-}
-
-static long conn_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
-{
- long ret = 1;
- BIO_CONNECT *data;
-
- data = (BIO_CONNECT *)b->ptr;
-
- switch (cmd) {
- case BIO_CTRL_SET_CALLBACK:
- {
- data->info_callback = fp;
- }
- break;
- default:
- ret = 0;
- break;
- }
- return ret;
-}
-
-static int conn_puts(BIO *bp, const char *str)
-{
- int n, ret;
-
- n = strlen(str);
- ret = conn_write(bp, str, n);
- return ret;
-}
-
-BIO *BIO_new_connect(const char *str)
-{
- BIO *ret;
-
- ret = BIO_new(BIO_s_connect());
- if (ret == NULL)
- return NULL;
- if (BIO_set_conn_hostname(ret, str))
- return ret;
- BIO_free(ret);
- return NULL;
-}
-
-#endif
+ default:
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+static long conn_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
+{
+ long ret = 1;
+ BIO_CONNECT *data;
+
+ data = (BIO_CONNECT *)b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_SET_CALLBACK:
+ {
+ data->info_callback = fp;
+ }
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+static int conn_puts(BIO *bp, const char *str)
+{
+ int n, ret;
+
+ n = strlen(str);
+ ret = conn_write(bp, str, n);
+ return ret;
+}
+
+BIO *BIO_new_connect(const char *str)
+{
+ BIO *ret;
+
+ ret = BIO_new(BIO_s_connect());
+ if (ret == NULL)
+ return NULL;
+ if (BIO_set_conn_hostname(ret, str))
+ return ret;
+ BIO_free(ret);
+ return NULL;
+}
+
+#endif
diff --git a/contrib/libs/openssl/crypto/bio/bss_dgram.c b/contrib/libs/openssl/crypto/bio/bss_dgram.c
index 745766826d..942fd8b514 100644
--- a/contrib/libs/openssl/crypto/bio/bss_dgram.c
+++ b/contrib/libs/openssl/crypto/bio/bss_dgram.c
@@ -1,1925 +1,1925 @@
-/*
+/*
* Copyright 2005-2019 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include <errno.h>
-
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <errno.h>
+
#include "bio_local.h"
-#ifndef OPENSSL_NO_DGRAM
-
-# ifndef OPENSSL_NO_SCTP
-# include <netinet/sctp.h>
-# include <fcntl.h>
-# define OPENSSL_SCTP_DATA_CHUNK_TYPE 0x00
-# define OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE 0xc0
-# endif
-
-# if defined(OPENSSL_SYS_LINUX) && !defined(IP_MTU)
-# define IP_MTU 14 /* linux is lame */
-# endif
-
-# if OPENSSL_USE_IPV6 && !defined(IPPROTO_IPV6)
-# define IPPROTO_IPV6 41 /* windows is lame */
-# endif
-
-# if defined(__FreeBSD__) && defined(IN6_IS_ADDR_V4MAPPED)
-/* Standard definition causes type-punning problems. */
-# undef IN6_IS_ADDR_V4MAPPED
-# define s6_addr32 __u6_addr.__u6_addr32
-# define IN6_IS_ADDR_V4MAPPED(a) \
- (((a)->s6_addr32[0] == 0) && \
- ((a)->s6_addr32[1] == 0) && \
- ((a)->s6_addr32[2] == htonl(0x0000ffff)))
-# endif
-
-static int dgram_write(BIO *h, const char *buf, int num);
-static int dgram_read(BIO *h, char *buf, int size);
-static int dgram_puts(BIO *h, const char *str);
-static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-static int dgram_new(BIO *h);
-static int dgram_free(BIO *data);
-static int dgram_clear(BIO *bio);
-
-# ifndef OPENSSL_NO_SCTP
-static int dgram_sctp_write(BIO *h, const char *buf, int num);
-static int dgram_sctp_read(BIO *h, char *buf, int size);
-static int dgram_sctp_puts(BIO *h, const char *str);
-static long dgram_sctp_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-static int dgram_sctp_new(BIO *h);
-static int dgram_sctp_free(BIO *data);
-# ifdef SCTP_AUTHENTICATION_EVENT
-static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification
- *snp);
-# endif
-# endif
-
-static int BIO_dgram_should_retry(int s);
-
-static void get_current_time(struct timeval *t);
-
-static const BIO_METHOD methods_dgramp = {
- BIO_TYPE_DGRAM,
- "datagram socket",
- /* TODO: Convert to new style write function */
- bwrite_conv,
- dgram_write,
- /* TODO: Convert to new style read function */
- bread_conv,
- dgram_read,
- dgram_puts,
- NULL, /* dgram_gets, */
- dgram_ctrl,
- dgram_new,
- dgram_free,
- NULL, /* dgram_callback_ctrl */
-};
-
-# ifndef OPENSSL_NO_SCTP
-static const BIO_METHOD methods_dgramp_sctp = {
- BIO_TYPE_DGRAM_SCTP,
- "datagram sctp socket",
- /* TODO: Convert to new style write function */
- bwrite_conv,
- dgram_sctp_write,
- /* TODO: Convert to new style write function */
- bread_conv,
- dgram_sctp_read,
- dgram_sctp_puts,
- NULL, /* dgram_gets, */
- dgram_sctp_ctrl,
- dgram_sctp_new,
- dgram_sctp_free,
- NULL, /* dgram_callback_ctrl */
-};
-# endif
-
-typedef struct bio_dgram_data_st {
- BIO_ADDR peer;
- unsigned int connected;
- unsigned int _errno;
- unsigned int mtu;
- struct timeval next_timeout;
- struct timeval socket_timeout;
- unsigned int peekmode;
-} bio_dgram_data;
-
-# ifndef OPENSSL_NO_SCTP
-typedef struct bio_dgram_sctp_save_message_st {
- BIO *bio;
- char *data;
- int length;
-} bio_dgram_sctp_save_message;
-
-typedef struct bio_dgram_sctp_data_st {
- BIO_ADDR peer;
- unsigned int connected;
- unsigned int _errno;
- unsigned int mtu;
- struct bio_dgram_sctp_sndinfo sndinfo;
- struct bio_dgram_sctp_rcvinfo rcvinfo;
- struct bio_dgram_sctp_prinfo prinfo;
- void (*handle_notifications) (BIO *bio, void *context, void *buf);
- void *notification_context;
- int in_handshake;
- int ccs_rcvd;
- int ccs_sent;
- int save_shutdown;
- int peer_auth_tested;
-} bio_dgram_sctp_data;
-# endif
-
-const BIO_METHOD *BIO_s_datagram(void)
-{
- return &methods_dgramp;
-}
-
-BIO *BIO_new_dgram(int fd, int close_flag)
-{
- BIO *ret;
-
- ret = BIO_new(BIO_s_datagram());
- if (ret == NULL)
- return NULL;
- BIO_set_fd(ret, fd, close_flag);
- return ret;
-}
-
-static int dgram_new(BIO *bi)
-{
- bio_dgram_data *data = OPENSSL_zalloc(sizeof(*data));
-
- if (data == NULL)
- return 0;
- bi->ptr = data;
- return 1;
-}
-
-static int dgram_free(BIO *a)
-{
- bio_dgram_data *data;
-
- if (a == NULL)
- return 0;
- if (!dgram_clear(a))
- return 0;
-
- data = (bio_dgram_data *)a->ptr;
- OPENSSL_free(data);
-
- return 1;
-}
-
-static int dgram_clear(BIO *a)
-{
- if (a == NULL)
- return 0;
- if (a->shutdown) {
- if (a->init) {
- BIO_closesocket(a->num);
- }
- a->init = 0;
- a->flags = 0;
- }
- return 1;
-}
-
-static void dgram_adjust_rcv_timeout(BIO *b)
-{
-# if defined(SO_RCVTIMEO)
- bio_dgram_data *data = (bio_dgram_data *)b->ptr;
- union {
- size_t s;
- int i;
- } sz = {
- 0
- };
-
- /* Is a timer active? */
- if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
- struct timeval timenow, timeleft;
-
- /* Read current socket timeout */
-# ifdef OPENSSL_SYS_WINDOWS
- int timeout;
-
- sz.i = sizeof(timeout);
- if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
- (void *)&timeout, &sz.i) < 0) {
- perror("getsockopt");
- } else {
- data->socket_timeout.tv_sec = timeout / 1000;
- data->socket_timeout.tv_usec = (timeout % 1000) * 1000;
- }
-# else
- sz.i = sizeof(data->socket_timeout);
- if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
- &(data->socket_timeout), (void *)&sz) < 0) {
- perror("getsockopt");
- } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0)
- OPENSSL_assert(sz.s <= sizeof(data->socket_timeout));
-# endif
-
- /* Get current time */
- get_current_time(&timenow);
-
- /* Calculate time left until timer expires */
- memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval));
- if (timeleft.tv_usec < timenow.tv_usec) {
- timeleft.tv_usec = 1000000 - timenow.tv_usec + timeleft.tv_usec;
- timeleft.tv_sec--;
- } else {
- timeleft.tv_usec -= timenow.tv_usec;
- }
- if (timeleft.tv_sec < timenow.tv_sec) {
- timeleft.tv_sec = 0;
- timeleft.tv_usec = 1;
- } else {
- timeleft.tv_sec -= timenow.tv_sec;
- }
-
- /*
- * Adjust socket timeout if next handshake message timer will expire
- * earlier.
- */
- if ((data->socket_timeout.tv_sec == 0
- && data->socket_timeout.tv_usec == 0)
- || (data->socket_timeout.tv_sec > timeleft.tv_sec)
- || (data->socket_timeout.tv_sec == timeleft.tv_sec
- && data->socket_timeout.tv_usec >= timeleft.tv_usec)) {
-# ifdef OPENSSL_SYS_WINDOWS
- timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000;
- if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
- (void *)&timeout, sizeof(timeout)) < 0) {
- perror("setsockopt");
- }
-# else
- if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft,
- sizeof(struct timeval)) < 0) {
- perror("setsockopt");
- }
-# endif
- }
- }
-# endif
-}
-
-static void dgram_reset_rcv_timeout(BIO *b)
-{
-# if defined(SO_RCVTIMEO)
- bio_dgram_data *data = (bio_dgram_data *)b->ptr;
-
- /* Is a timer active? */
- if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
-# ifdef OPENSSL_SYS_WINDOWS
- int timeout = data->socket_timeout.tv_sec * 1000 +
- data->socket_timeout.tv_usec / 1000;
- if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
- (void *)&timeout, sizeof(timeout)) < 0) {
- perror("setsockopt");
- }
-# else
- if (setsockopt
- (b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout),
- sizeof(struct timeval)) < 0) {
- perror("setsockopt");
- }
-# endif
- }
-# endif
-}
-
-static int dgram_read(BIO *b, char *out, int outl)
-{
- int ret = 0;
- bio_dgram_data *data = (bio_dgram_data *)b->ptr;
- int flags = 0;
-
- BIO_ADDR peer;
- socklen_t len = sizeof(peer);
-
- if (out != NULL) {
- clear_socket_error();
- memset(&peer, 0, sizeof(peer));
- dgram_adjust_rcv_timeout(b);
- if (data->peekmode)
- flags = MSG_PEEK;
- ret = recvfrom(b->num, out, outl, flags,
- BIO_ADDR_sockaddr_noconst(&peer), &len);
-
- if (!data->connected && ret >= 0)
- BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &peer);
-
- BIO_clear_retry_flags(b);
- if (ret < 0) {
- if (BIO_dgram_should_retry(ret)) {
- BIO_set_retry_read(b);
- data->_errno = get_last_socket_error();
- }
- }
-
- dgram_reset_rcv_timeout(b);
- }
- return ret;
-}
-
-static int dgram_write(BIO *b, const char *in, int inl)
-{
- int ret;
- bio_dgram_data *data = (bio_dgram_data *)b->ptr;
- clear_socket_error();
-
- if (data->connected)
- ret = writesocket(b->num, in, inl);
- else {
- int peerlen = BIO_ADDR_sockaddr_size(&data->peer);
-
- ret = sendto(b->num, in, inl, 0,
- BIO_ADDR_sockaddr(&data->peer), peerlen);
- }
-
- BIO_clear_retry_flags(b);
- if (ret <= 0) {
- if (BIO_dgram_should_retry(ret)) {
- BIO_set_retry_write(b);
- data->_errno = get_last_socket_error();
- }
- }
- return ret;
-}
-
-static long dgram_get_mtu_overhead(bio_dgram_data *data)
-{
- long ret;
-
- switch (BIO_ADDR_family(&data->peer)) {
- case AF_INET:
- /*
- * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
- */
- ret = 28;
- break;
-# if OPENSSL_USE_IPV6
- case AF_INET6:
- {
-# ifdef IN6_IS_ADDR_V4MAPPED
- struct in6_addr tmp_addr;
- if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL)
- && IN6_IS_ADDR_V4MAPPED(&tmp_addr))
- /*
- * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
- */
- ret = 28;
- else
-# endif
- /*
- * Assume this is UDP - 40 bytes for IP, 8 bytes for UDP
- */
- ret = 48;
- }
- break;
-# endif
- default:
- /* We don't know. Go with the historical default */
- ret = 28;
- break;
- }
- return ret;
-}
-
-static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
-{
- long ret = 1;
- int *ip;
- bio_dgram_data *data = NULL;
- int sockopt_val = 0;
- int d_errno;
-# if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
- socklen_t sockopt_len; /* assume that system supporting IP_MTU is
- * modern enough to define socklen_t */
- socklen_t addr_len;
- BIO_ADDR addr;
-# endif
-
- data = (bio_dgram_data *)b->ptr;
-
- switch (cmd) {
- case BIO_CTRL_RESET:
- num = 0;
- ret = 0;
- break;
- case BIO_CTRL_INFO:
- ret = 0;
- break;
- case BIO_C_SET_FD:
- dgram_clear(b);
- b->num = *((int *)ptr);
- b->shutdown = (int)num;
- b->init = 1;
- break;
- case BIO_C_GET_FD:
- if (b->init) {
- ip = (int *)ptr;
- if (ip != NULL)
- *ip = b->num;
- ret = b->num;
- } else
- ret = -1;
- break;
- case BIO_CTRL_GET_CLOSE:
- ret = b->shutdown;
- break;
- case BIO_CTRL_SET_CLOSE:
- b->shutdown = (int)num;
- break;
- case BIO_CTRL_PENDING:
- case BIO_CTRL_WPENDING:
- ret = 0;
- break;
- case BIO_CTRL_DUP:
- case BIO_CTRL_FLUSH:
- ret = 1;
- break;
- case BIO_CTRL_DGRAM_CONNECT:
- BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
- break;
- /* (Linux)kernel sets DF bit on outgoing IP packets */
- case BIO_CTRL_DGRAM_MTU_DISCOVER:
-# if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
- addr_len = (socklen_t) sizeof(addr);
- memset(&addr, 0, sizeof(addr));
- if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
- ret = 0;
- break;
- }
- switch (addr.sa.sa_family) {
- case AF_INET:
- sockopt_val = IP_PMTUDISC_DO;
- if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
- &sockopt_val, sizeof(sockopt_val))) < 0)
- perror("setsockopt");
- break;
-# if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
- case AF_INET6:
- sockopt_val = IPV6_PMTUDISC_DO;
- if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
- &sockopt_val, sizeof(sockopt_val))) < 0)
- perror("setsockopt");
- break;
-# endif
- default:
- ret = -1;
- break;
- }
-# else
- ret = -1;
-# endif
- break;
- case BIO_CTRL_DGRAM_QUERY_MTU:
-# if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU)
- addr_len = (socklen_t) sizeof(addr);
- memset(&addr, 0, sizeof(addr));
- if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
- ret = 0;
- break;
- }
- sockopt_len = sizeof(sockopt_val);
- switch (addr.sa.sa_family) {
- case AF_INET:
- if ((ret =
- getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val,
- &sockopt_len)) < 0 || sockopt_val < 0) {
- ret = 0;
- } else {
- /*
- * we assume that the transport protocol is UDP and no IP
- * options are used.
- */
- data->mtu = sockopt_val - 8 - 20;
- ret = data->mtu;
- }
- break;
-# if OPENSSL_USE_IPV6 && defined(IPV6_MTU)
- case AF_INET6:
- if ((ret =
- getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU,
- (void *)&sockopt_val, &sockopt_len)) < 0
- || sockopt_val < 0) {
- ret = 0;
- } else {
- /*
- * we assume that the transport protocol is UDP and no IPV6
- * options are used.
- */
- data->mtu = sockopt_val - 8 - 40;
- ret = data->mtu;
- }
- break;
-# endif
- default:
- ret = 0;
- break;
- }
-# else
- ret = 0;
-# endif
- break;
- case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
- ret = -dgram_get_mtu_overhead(data);
- switch (BIO_ADDR_family(&data->peer)) {
- case AF_INET:
- ret += 576;
- break;
-# if OPENSSL_USE_IPV6
- case AF_INET6:
- {
-# ifdef IN6_IS_ADDR_V4MAPPED
- struct in6_addr tmp_addr;
- if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL)
- && IN6_IS_ADDR_V4MAPPED(&tmp_addr))
- ret += 576;
- else
-# endif
- ret += 1280;
- }
- break;
-# endif
- default:
- ret += 576;
- break;
- }
- break;
- case BIO_CTRL_DGRAM_GET_MTU:
- return data->mtu;
- case BIO_CTRL_DGRAM_SET_MTU:
- data->mtu = num;
- ret = num;
- break;
- case BIO_CTRL_DGRAM_SET_CONNECTED:
- if (ptr != NULL) {
- data->connected = 1;
- BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
- } else {
- data->connected = 0;
- memset(&data->peer, 0, sizeof(data->peer));
- }
- break;
- case BIO_CTRL_DGRAM_GET_PEER:
- ret = BIO_ADDR_sockaddr_size(&data->peer);
- /* FIXME: if num < ret, we will only return part of an address.
- That should bee an error, no? */
- if (num == 0 || num > ret)
- num = ret;
- memcpy(ptr, &data->peer, (ret = num));
- break;
- case BIO_CTRL_DGRAM_SET_PEER:
- BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
- break;
- case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
- memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
- break;
-# if defined(SO_RCVTIMEO)
- case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
-# ifdef OPENSSL_SYS_WINDOWS
- {
- struct timeval *tv = (struct timeval *)ptr;
- int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;
- if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
- (void *)&timeout, sizeof(timeout)) < 0) {
- perror("setsockopt");
- ret = -1;
- }
- }
-# else
- if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr,
- sizeof(struct timeval)) < 0) {
- perror("setsockopt");
- ret = -1;
- }
-# endif
- break;
- case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
- {
- union {
- size_t s;
- int i;
- } sz = {
- 0
- };
-# ifdef OPENSSL_SYS_WINDOWS
- int timeout;
- struct timeval *tv = (struct timeval *)ptr;
-
- sz.i = sizeof(timeout);
- if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
- (void *)&timeout, &sz.i) < 0) {
- perror("getsockopt");
- ret = -1;
- } else {
- tv->tv_sec = timeout / 1000;
- tv->tv_usec = (timeout % 1000) * 1000;
- ret = sizeof(*tv);
- }
-# else
- sz.i = sizeof(struct timeval);
- if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
- ptr, (void *)&sz) < 0) {
- perror("getsockopt");
- ret = -1;
- } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) {
- OPENSSL_assert(sz.s <= sizeof(struct timeval));
- ret = (int)sz.s;
- } else
- ret = sz.i;
-# endif
- }
- break;
-# endif
-# if defined(SO_SNDTIMEO)
- case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
-# ifdef OPENSSL_SYS_WINDOWS
- {
- struct timeval *tv = (struct timeval *)ptr;
- int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;
- if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
- (void *)&timeout, sizeof(timeout)) < 0) {
- perror("setsockopt");
- ret = -1;
- }
- }
-# else
- if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr,
- sizeof(struct timeval)) < 0) {
- perror("setsockopt");
- ret = -1;
- }
-# endif
- break;
- case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
- {
- union {
- size_t s;
- int i;
- } sz = {
- 0
- };
-# ifdef OPENSSL_SYS_WINDOWS
- int timeout;
- struct timeval *tv = (struct timeval *)ptr;
-
- sz.i = sizeof(timeout);
- if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
- (void *)&timeout, &sz.i) < 0) {
- perror("getsockopt");
- ret = -1;
- } else {
- tv->tv_sec = timeout / 1000;
- tv->tv_usec = (timeout % 1000) * 1000;
- ret = sizeof(*tv);
- }
-# else
- sz.i = sizeof(struct timeval);
- if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
- ptr, (void *)&sz) < 0) {
- perror("getsockopt");
- ret = -1;
- } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) {
- OPENSSL_assert(sz.s <= sizeof(struct timeval));
- ret = (int)sz.s;
- } else
- ret = sz.i;
-# endif
- }
- break;
-# endif
- case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
- /* fall-through */
- case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
-# ifdef OPENSSL_SYS_WINDOWS
- d_errno = (data->_errno == WSAETIMEDOUT);
-# else
- d_errno = (data->_errno == EAGAIN);
-# endif
- if (d_errno) {
- ret = 1;
- data->_errno = 0;
- } else
- ret = 0;
- break;
-# ifdef EMSGSIZE
- case BIO_CTRL_DGRAM_MTU_EXCEEDED:
- if (data->_errno == EMSGSIZE) {
- ret = 1;
- data->_errno = 0;
- } else
- ret = 0;
- break;
-# endif
- case BIO_CTRL_DGRAM_SET_DONT_FRAG:
- sockopt_val = num ? 1 : 0;
-
- switch (data->peer.sa.sa_family) {
- case AF_INET:
-# if defined(IP_DONTFRAG)
- if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAG,
- &sockopt_val, sizeof(sockopt_val))) < 0) {
- perror("setsockopt");
- ret = -1;
- }
-# elif defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined (IP_PMTUDISC_PROBE)
- if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT),
- (ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
- &sockopt_val, sizeof(sockopt_val))) < 0) {
- perror("setsockopt");
- ret = -1;
- }
-# elif defined(OPENSSL_SYS_WINDOWS) && defined(IP_DONTFRAGMENT)
- if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAGMENT,
- (const char *)&sockopt_val,
- sizeof(sockopt_val))) < 0) {
- perror("setsockopt");
- ret = -1;
- }
-# else
- ret = -1;
-# endif
- break;
-# if OPENSSL_USE_IPV6
- case AF_INET6:
-# if defined(IPV6_DONTFRAG)
- if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_DONTFRAG,
- (const void *)&sockopt_val,
- sizeof(sockopt_val))) < 0) {
- perror("setsockopt");
- ret = -1;
- }
-# elif defined(OPENSSL_SYS_LINUX) && defined(IPV6_MTUDISCOVER)
- if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT),
- (ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
- &sockopt_val, sizeof(sockopt_val))) < 0) {
- perror("setsockopt");
- ret = -1;
- }
-# else
- ret = -1;
-# endif
- break;
-# endif
- default:
- ret = -1;
- break;
- }
- break;
- case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
- ret = dgram_get_mtu_overhead(data);
- break;
-
- /*
- * BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE is used here for compatibility
- * reasons. When BIO_CTRL_DGRAM_SET_PEEK_MODE was first defined its value
- * was incorrectly clashing with BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE. The
- * value has been updated to a non-clashing value. However to preserve
+#ifndef OPENSSL_NO_DGRAM
+
+# ifndef OPENSSL_NO_SCTP
+# include <netinet/sctp.h>
+# include <fcntl.h>
+# define OPENSSL_SCTP_DATA_CHUNK_TYPE 0x00
+# define OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE 0xc0
+# endif
+
+# if defined(OPENSSL_SYS_LINUX) && !defined(IP_MTU)
+# define IP_MTU 14 /* linux is lame */
+# endif
+
+# if OPENSSL_USE_IPV6 && !defined(IPPROTO_IPV6)
+# define IPPROTO_IPV6 41 /* windows is lame */
+# endif
+
+# if defined(__FreeBSD__) && defined(IN6_IS_ADDR_V4MAPPED)
+/* Standard definition causes type-punning problems. */
+# undef IN6_IS_ADDR_V4MAPPED
+# define s6_addr32 __u6_addr.__u6_addr32
+# define IN6_IS_ADDR_V4MAPPED(a) \
+ (((a)->s6_addr32[0] == 0) && \
+ ((a)->s6_addr32[1] == 0) && \
+ ((a)->s6_addr32[2] == htonl(0x0000ffff)))
+# endif
+
+static int dgram_write(BIO *h, const char *buf, int num);
+static int dgram_read(BIO *h, char *buf, int size);
+static int dgram_puts(BIO *h, const char *str);
+static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int dgram_new(BIO *h);
+static int dgram_free(BIO *data);
+static int dgram_clear(BIO *bio);
+
+# ifndef OPENSSL_NO_SCTP
+static int dgram_sctp_write(BIO *h, const char *buf, int num);
+static int dgram_sctp_read(BIO *h, char *buf, int size);
+static int dgram_sctp_puts(BIO *h, const char *str);
+static long dgram_sctp_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int dgram_sctp_new(BIO *h);
+static int dgram_sctp_free(BIO *data);
+# ifdef SCTP_AUTHENTICATION_EVENT
+static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification
+ *snp);
+# endif
+# endif
+
+static int BIO_dgram_should_retry(int s);
+
+static void get_current_time(struct timeval *t);
+
+static const BIO_METHOD methods_dgramp = {
+ BIO_TYPE_DGRAM,
+ "datagram socket",
+ /* TODO: Convert to new style write function */
+ bwrite_conv,
+ dgram_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
+ dgram_read,
+ dgram_puts,
+ NULL, /* dgram_gets, */
+ dgram_ctrl,
+ dgram_new,
+ dgram_free,
+ NULL, /* dgram_callback_ctrl */
+};
+
+# ifndef OPENSSL_NO_SCTP
+static const BIO_METHOD methods_dgramp_sctp = {
+ BIO_TYPE_DGRAM_SCTP,
+ "datagram sctp socket",
+ /* TODO: Convert to new style write function */
+ bwrite_conv,
+ dgram_sctp_write,
+ /* TODO: Convert to new style write function */
+ bread_conv,
+ dgram_sctp_read,
+ dgram_sctp_puts,
+ NULL, /* dgram_gets, */
+ dgram_sctp_ctrl,
+ dgram_sctp_new,
+ dgram_sctp_free,
+ NULL, /* dgram_callback_ctrl */
+};
+# endif
+
+typedef struct bio_dgram_data_st {
+ BIO_ADDR peer;
+ unsigned int connected;
+ unsigned int _errno;
+ unsigned int mtu;
+ struct timeval next_timeout;
+ struct timeval socket_timeout;
+ unsigned int peekmode;
+} bio_dgram_data;
+
+# ifndef OPENSSL_NO_SCTP
+typedef struct bio_dgram_sctp_save_message_st {
+ BIO *bio;
+ char *data;
+ int length;
+} bio_dgram_sctp_save_message;
+
+typedef struct bio_dgram_sctp_data_st {
+ BIO_ADDR peer;
+ unsigned int connected;
+ unsigned int _errno;
+ unsigned int mtu;
+ struct bio_dgram_sctp_sndinfo sndinfo;
+ struct bio_dgram_sctp_rcvinfo rcvinfo;
+ struct bio_dgram_sctp_prinfo prinfo;
+ void (*handle_notifications) (BIO *bio, void *context, void *buf);
+ void *notification_context;
+ int in_handshake;
+ int ccs_rcvd;
+ int ccs_sent;
+ int save_shutdown;
+ int peer_auth_tested;
+} bio_dgram_sctp_data;
+# endif
+
+const BIO_METHOD *BIO_s_datagram(void)
+{
+ return &methods_dgramp;
+}
+
+BIO *BIO_new_dgram(int fd, int close_flag)
+{
+ BIO *ret;
+
+ ret = BIO_new(BIO_s_datagram());
+ if (ret == NULL)
+ return NULL;
+ BIO_set_fd(ret, fd, close_flag);
+ return ret;
+}
+
+static int dgram_new(BIO *bi)
+{
+ bio_dgram_data *data = OPENSSL_zalloc(sizeof(*data));
+
+ if (data == NULL)
+ return 0;
+ bi->ptr = data;
+ return 1;
+}
+
+static int dgram_free(BIO *a)
+{
+ bio_dgram_data *data;
+
+ if (a == NULL)
+ return 0;
+ if (!dgram_clear(a))
+ return 0;
+
+ data = (bio_dgram_data *)a->ptr;
+ OPENSSL_free(data);
+
+ return 1;
+}
+
+static int dgram_clear(BIO *a)
+{
+ if (a == NULL)
+ return 0;
+ if (a->shutdown) {
+ if (a->init) {
+ BIO_closesocket(a->num);
+ }
+ a->init = 0;
+ a->flags = 0;
+ }
+ return 1;
+}
+
+static void dgram_adjust_rcv_timeout(BIO *b)
+{
+# if defined(SO_RCVTIMEO)
+ bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+ union {
+ size_t s;
+ int i;
+ } sz = {
+ 0
+ };
+
+ /* Is a timer active? */
+ if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
+ struct timeval timenow, timeleft;
+
+ /* Read current socket timeout */
+# ifdef OPENSSL_SYS_WINDOWS
+ int timeout;
+
+ sz.i = sizeof(timeout);
+ if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ (void *)&timeout, &sz.i) < 0) {
+ perror("getsockopt");
+ } else {
+ data->socket_timeout.tv_sec = timeout / 1000;
+ data->socket_timeout.tv_usec = (timeout % 1000) * 1000;
+ }
+# else
+ sz.i = sizeof(data->socket_timeout);
+ if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ &(data->socket_timeout), (void *)&sz) < 0) {
+ perror("getsockopt");
+ } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0)
+ OPENSSL_assert(sz.s <= sizeof(data->socket_timeout));
+# endif
+
+ /* Get current time */
+ get_current_time(&timenow);
+
+ /* Calculate time left until timer expires */
+ memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval));
+ if (timeleft.tv_usec < timenow.tv_usec) {
+ timeleft.tv_usec = 1000000 - timenow.tv_usec + timeleft.tv_usec;
+ timeleft.tv_sec--;
+ } else {
+ timeleft.tv_usec -= timenow.tv_usec;
+ }
+ if (timeleft.tv_sec < timenow.tv_sec) {
+ timeleft.tv_sec = 0;
+ timeleft.tv_usec = 1;
+ } else {
+ timeleft.tv_sec -= timenow.tv_sec;
+ }
+
+ /*
+ * Adjust socket timeout if next handshake message timer will expire
+ * earlier.
+ */
+ if ((data->socket_timeout.tv_sec == 0
+ && data->socket_timeout.tv_usec == 0)
+ || (data->socket_timeout.tv_sec > timeleft.tv_sec)
+ || (data->socket_timeout.tv_sec == timeleft.tv_sec
+ && data->socket_timeout.tv_usec >= timeleft.tv_usec)) {
+# ifdef OPENSSL_SYS_WINDOWS
+ timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000;
+ if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ (void *)&timeout, sizeof(timeout)) < 0) {
+ perror("setsockopt");
+ }
+# else
+ if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft,
+ sizeof(struct timeval)) < 0) {
+ perror("setsockopt");
+ }
+# endif
+ }
+ }
+# endif
+}
+
+static void dgram_reset_rcv_timeout(BIO *b)
+{
+# if defined(SO_RCVTIMEO)
+ bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+
+ /* Is a timer active? */
+ if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
+# ifdef OPENSSL_SYS_WINDOWS
+ int timeout = data->socket_timeout.tv_sec * 1000 +
+ data->socket_timeout.tv_usec / 1000;
+ if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ (void *)&timeout, sizeof(timeout)) < 0) {
+ perror("setsockopt");
+ }
+# else
+ if (setsockopt
+ (b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout),
+ sizeof(struct timeval)) < 0) {
+ perror("setsockopt");
+ }
+# endif
+ }
+# endif
+}
+
+static int dgram_read(BIO *b, char *out, int outl)
+{
+ int ret = 0;
+ bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+ int flags = 0;
+
+ BIO_ADDR peer;
+ socklen_t len = sizeof(peer);
+
+ if (out != NULL) {
+ clear_socket_error();
+ memset(&peer, 0, sizeof(peer));
+ dgram_adjust_rcv_timeout(b);
+ if (data->peekmode)
+ flags = MSG_PEEK;
+ ret = recvfrom(b->num, out, outl, flags,
+ BIO_ADDR_sockaddr_noconst(&peer), &len);
+
+ if (!data->connected && ret >= 0)
+ BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &peer);
+
+ BIO_clear_retry_flags(b);
+ if (ret < 0) {
+ if (BIO_dgram_should_retry(ret)) {
+ BIO_set_retry_read(b);
+ data->_errno = get_last_socket_error();
+ }
+ }
+
+ dgram_reset_rcv_timeout(b);
+ }
+ return ret;
+}
+
+static int dgram_write(BIO *b, const char *in, int inl)
+{
+ int ret;
+ bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+ clear_socket_error();
+
+ if (data->connected)
+ ret = writesocket(b->num, in, inl);
+ else {
+ int peerlen = BIO_ADDR_sockaddr_size(&data->peer);
+
+ ret = sendto(b->num, in, inl, 0,
+ BIO_ADDR_sockaddr(&data->peer), peerlen);
+ }
+
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_dgram_should_retry(ret)) {
+ BIO_set_retry_write(b);
+ data->_errno = get_last_socket_error();
+ }
+ }
+ return ret;
+}
+
+static long dgram_get_mtu_overhead(bio_dgram_data *data)
+{
+ long ret;
+
+ switch (BIO_ADDR_family(&data->peer)) {
+ case AF_INET:
+ /*
+ * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
+ */
+ ret = 28;
+ break;
+# if OPENSSL_USE_IPV6
+ case AF_INET6:
+ {
+# ifdef IN6_IS_ADDR_V4MAPPED
+ struct in6_addr tmp_addr;
+ if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL)
+ && IN6_IS_ADDR_V4MAPPED(&tmp_addr))
+ /*
+ * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
+ */
+ ret = 28;
+ else
+# endif
+ /*
+ * Assume this is UDP - 40 bytes for IP, 8 bytes for UDP
+ */
+ ret = 48;
+ }
+ break;
+# endif
+ default:
+ /* We don't know. Go with the historical default */
+ ret = 28;
+ break;
+ }
+ return ret;
+}
+
+static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ long ret = 1;
+ int *ip;
+ bio_dgram_data *data = NULL;
+ int sockopt_val = 0;
+ int d_errno;
+# if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
+ socklen_t sockopt_len; /* assume that system supporting IP_MTU is
+ * modern enough to define socklen_t */
+ socklen_t addr_len;
+ BIO_ADDR addr;
+# endif
+
+ data = (bio_dgram_data *)b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ num = 0;
+ ret = 0;
+ break;
+ case BIO_CTRL_INFO:
+ ret = 0;
+ break;
+ case BIO_C_SET_FD:
+ dgram_clear(b);
+ b->num = *((int *)ptr);
+ b->shutdown = (int)num;
+ b->init = 1;
+ break;
+ case BIO_C_GET_FD:
+ if (b->init) {
+ ip = (int *)ptr;
+ if (ip != NULL)
+ *ip = b->num;
+ ret = b->num;
+ } else
+ ret = -1;
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret = b->shutdown;
+ break;
+ case BIO_CTRL_SET_CLOSE:
+ b->shutdown = (int)num;
+ break;
+ case BIO_CTRL_PENDING:
+ case BIO_CTRL_WPENDING:
+ ret = 0;
+ break;
+ case BIO_CTRL_DUP:
+ case BIO_CTRL_FLUSH:
+ ret = 1;
+ break;
+ case BIO_CTRL_DGRAM_CONNECT:
+ BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
+ break;
+ /* (Linux)kernel sets DF bit on outgoing IP packets */
+ case BIO_CTRL_DGRAM_MTU_DISCOVER:
+# if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
+ addr_len = (socklen_t) sizeof(addr);
+ memset(&addr, 0, sizeof(addr));
+ if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
+ ret = 0;
+ break;
+ }
+ switch (addr.sa.sa_family) {
+ case AF_INET:
+ sockopt_val = IP_PMTUDISC_DO;
+ if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
+ &sockopt_val, sizeof(sockopt_val))) < 0)
+ perror("setsockopt");
+ break;
+# if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
+ case AF_INET6:
+ sockopt_val = IPV6_PMTUDISC_DO;
+ if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
+ &sockopt_val, sizeof(sockopt_val))) < 0)
+ perror("setsockopt");
+ break;
+# endif
+ default:
+ ret = -1;
+ break;
+ }
+# else
+ ret = -1;
+# endif
+ break;
+ case BIO_CTRL_DGRAM_QUERY_MTU:
+# if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU)
+ addr_len = (socklen_t) sizeof(addr);
+ memset(&addr, 0, sizeof(addr));
+ if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
+ ret = 0;
+ break;
+ }
+ sockopt_len = sizeof(sockopt_val);
+ switch (addr.sa.sa_family) {
+ case AF_INET:
+ if ((ret =
+ getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val,
+ &sockopt_len)) < 0 || sockopt_val < 0) {
+ ret = 0;
+ } else {
+ /*
+ * we assume that the transport protocol is UDP and no IP
+ * options are used.
+ */
+ data->mtu = sockopt_val - 8 - 20;
+ ret = data->mtu;
+ }
+ break;
+# if OPENSSL_USE_IPV6 && defined(IPV6_MTU)
+ case AF_INET6:
+ if ((ret =
+ getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU,
+ (void *)&sockopt_val, &sockopt_len)) < 0
+ || sockopt_val < 0) {
+ ret = 0;
+ } else {
+ /*
+ * we assume that the transport protocol is UDP and no IPV6
+ * options are used.
+ */
+ data->mtu = sockopt_val - 8 - 40;
+ ret = data->mtu;
+ }
+ break;
+# endif
+ default:
+ ret = 0;
+ break;
+ }
+# else
+ ret = 0;
+# endif
+ break;
+ case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
+ ret = -dgram_get_mtu_overhead(data);
+ switch (BIO_ADDR_family(&data->peer)) {
+ case AF_INET:
+ ret += 576;
+ break;
+# if OPENSSL_USE_IPV6
+ case AF_INET6:
+ {
+# ifdef IN6_IS_ADDR_V4MAPPED
+ struct in6_addr tmp_addr;
+ if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL)
+ && IN6_IS_ADDR_V4MAPPED(&tmp_addr))
+ ret += 576;
+ else
+# endif
+ ret += 1280;
+ }
+ break;
+# endif
+ default:
+ ret += 576;
+ break;
+ }
+ break;
+ case BIO_CTRL_DGRAM_GET_MTU:
+ return data->mtu;
+ case BIO_CTRL_DGRAM_SET_MTU:
+ data->mtu = num;
+ ret = num;
+ break;
+ case BIO_CTRL_DGRAM_SET_CONNECTED:
+ if (ptr != NULL) {
+ data->connected = 1;
+ BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
+ } else {
+ data->connected = 0;
+ memset(&data->peer, 0, sizeof(data->peer));
+ }
+ break;
+ case BIO_CTRL_DGRAM_GET_PEER:
+ ret = BIO_ADDR_sockaddr_size(&data->peer);
+ /* FIXME: if num < ret, we will only return part of an address.
+ That should bee an error, no? */
+ if (num == 0 || num > ret)
+ num = ret;
+ memcpy(ptr, &data->peer, (ret = num));
+ break;
+ case BIO_CTRL_DGRAM_SET_PEER:
+ BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
+ break;
+ case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
+ memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
+ break;
+# if defined(SO_RCVTIMEO)
+ case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
+# ifdef OPENSSL_SYS_WINDOWS
+ {
+ struct timeval *tv = (struct timeval *)ptr;
+ int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;
+ if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ (void *)&timeout, sizeof(timeout)) < 0) {
+ perror("setsockopt");
+ ret = -1;
+ }
+ }
+# else
+ if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr,
+ sizeof(struct timeval)) < 0) {
+ perror("setsockopt");
+ ret = -1;
+ }
+# endif
+ break;
+ case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
+ {
+ union {
+ size_t s;
+ int i;
+ } sz = {
+ 0
+ };
+# ifdef OPENSSL_SYS_WINDOWS
+ int timeout;
+ struct timeval *tv = (struct timeval *)ptr;
+
+ sz.i = sizeof(timeout);
+ if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ (void *)&timeout, &sz.i) < 0) {
+ perror("getsockopt");
+ ret = -1;
+ } else {
+ tv->tv_sec = timeout / 1000;
+ tv->tv_usec = (timeout % 1000) * 1000;
+ ret = sizeof(*tv);
+ }
+# else
+ sz.i = sizeof(struct timeval);
+ if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ ptr, (void *)&sz) < 0) {
+ perror("getsockopt");
+ ret = -1;
+ } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) {
+ OPENSSL_assert(sz.s <= sizeof(struct timeval));
+ ret = (int)sz.s;
+ } else
+ ret = sz.i;
+# endif
+ }
+ break;
+# endif
+# if defined(SO_SNDTIMEO)
+ case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
+# ifdef OPENSSL_SYS_WINDOWS
+ {
+ struct timeval *tv = (struct timeval *)ptr;
+ int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;
+ if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
+ (void *)&timeout, sizeof(timeout)) < 0) {
+ perror("setsockopt");
+ ret = -1;
+ }
+ }
+# else
+ if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr,
+ sizeof(struct timeval)) < 0) {
+ perror("setsockopt");
+ ret = -1;
+ }
+# endif
+ break;
+ case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
+ {
+ union {
+ size_t s;
+ int i;
+ } sz = {
+ 0
+ };
+# ifdef OPENSSL_SYS_WINDOWS
+ int timeout;
+ struct timeval *tv = (struct timeval *)ptr;
+
+ sz.i = sizeof(timeout);
+ if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
+ (void *)&timeout, &sz.i) < 0) {
+ perror("getsockopt");
+ ret = -1;
+ } else {
+ tv->tv_sec = timeout / 1000;
+ tv->tv_usec = (timeout % 1000) * 1000;
+ ret = sizeof(*tv);
+ }
+# else
+ sz.i = sizeof(struct timeval);
+ if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
+ ptr, (void *)&sz) < 0) {
+ perror("getsockopt");
+ ret = -1;
+ } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) {
+ OPENSSL_assert(sz.s <= sizeof(struct timeval));
+ ret = (int)sz.s;
+ } else
+ ret = sz.i;
+# endif
+ }
+ break;
+# endif
+ case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
+ /* fall-through */
+ case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
+# ifdef OPENSSL_SYS_WINDOWS
+ d_errno = (data->_errno == WSAETIMEDOUT);
+# else
+ d_errno = (data->_errno == EAGAIN);
+# endif
+ if (d_errno) {
+ ret = 1;
+ data->_errno = 0;
+ } else
+ ret = 0;
+ break;
+# ifdef EMSGSIZE
+ case BIO_CTRL_DGRAM_MTU_EXCEEDED:
+ if (data->_errno == EMSGSIZE) {
+ ret = 1;
+ data->_errno = 0;
+ } else
+ ret = 0;
+ break;
+# endif
+ case BIO_CTRL_DGRAM_SET_DONT_FRAG:
+ sockopt_val = num ? 1 : 0;
+
+ switch (data->peer.sa.sa_family) {
+ case AF_INET:
+# if defined(IP_DONTFRAG)
+ if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAG,
+ &sockopt_val, sizeof(sockopt_val))) < 0) {
+ perror("setsockopt");
+ ret = -1;
+ }
+# elif defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined (IP_PMTUDISC_PROBE)
+ if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT),
+ (ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
+ &sockopt_val, sizeof(sockopt_val))) < 0) {
+ perror("setsockopt");
+ ret = -1;
+ }
+# elif defined(OPENSSL_SYS_WINDOWS) && defined(IP_DONTFRAGMENT)
+ if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAGMENT,
+ (const char *)&sockopt_val,
+ sizeof(sockopt_val))) < 0) {
+ perror("setsockopt");
+ ret = -1;
+ }
+# else
+ ret = -1;
+# endif
+ break;
+# if OPENSSL_USE_IPV6
+ case AF_INET6:
+# if defined(IPV6_DONTFRAG)
+ if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_DONTFRAG,
+ (const void *)&sockopt_val,
+ sizeof(sockopt_val))) < 0) {
+ perror("setsockopt");
+ ret = -1;
+ }
+# elif defined(OPENSSL_SYS_LINUX) && defined(IPV6_MTUDISCOVER)
+ if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT),
+ (ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
+ &sockopt_val, sizeof(sockopt_val))) < 0) {
+ perror("setsockopt");
+ ret = -1;
+ }
+# else
+ ret = -1;
+# endif
+ break;
+# endif
+ default:
+ ret = -1;
+ break;
+ }
+ break;
+ case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
+ ret = dgram_get_mtu_overhead(data);
+ break;
+
+ /*
+ * BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE is used here for compatibility
+ * reasons. When BIO_CTRL_DGRAM_SET_PEEK_MODE was first defined its value
+ * was incorrectly clashing with BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE. The
+ * value has been updated to a non-clashing value. However to preserve
* binary compatibility we now respond to both the old value and the new one
- */
- case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
- case BIO_CTRL_DGRAM_SET_PEEK_MODE:
- data->peekmode = (unsigned int)num;
- break;
- default:
- ret = 0;
- break;
- }
- return ret;
-}
-
-static int dgram_puts(BIO *bp, const char *str)
-{
- int n, ret;
-
- n = strlen(str);
- ret = dgram_write(bp, str, n);
- return ret;
-}
-
-# ifndef OPENSSL_NO_SCTP
-const BIO_METHOD *BIO_s_datagram_sctp(void)
-{
- return &methods_dgramp_sctp;
-}
-
-BIO *BIO_new_dgram_sctp(int fd, int close_flag)
-{
- BIO *bio;
- int ret, optval = 20000;
- int auth_data = 0, auth_forward = 0;
- unsigned char *p;
- struct sctp_authchunk auth;
- struct sctp_authchunks *authchunks;
- socklen_t sockopt_len;
-# ifdef SCTP_AUTHENTICATION_EVENT
-# ifdef SCTP_EVENT
- struct sctp_event event;
-# else
- struct sctp_event_subscribe event;
-# endif
-# endif
-
- bio = BIO_new(BIO_s_datagram_sctp());
- if (bio == NULL)
- return NULL;
- BIO_set_fd(bio, fd, close_flag);
-
- /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */
- auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE;
- ret =
- setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth,
- sizeof(struct sctp_authchunk));
- if (ret < 0) {
- BIO_vfree(bio);
- BIOerr(BIO_F_BIO_NEW_DGRAM_SCTP, ERR_R_SYS_LIB);
- ERR_add_error_data(1, "Ensure SCTP AUTH chunks are enabled in kernel");
- return NULL;
- }
- auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE;
- ret =
- setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth,
- sizeof(struct sctp_authchunk));
- if (ret < 0) {
- BIO_vfree(bio);
- BIOerr(BIO_F_BIO_NEW_DGRAM_SCTP, ERR_R_SYS_LIB);
- ERR_add_error_data(1, "Ensure SCTP AUTH chunks are enabled in kernel");
- return NULL;
- }
-
- /*
- * Test if activation was successful. When using accept(), SCTP-AUTH has
- * to be activated for the listening socket already, otherwise the
- * connected socket won't use it. Similarly with connect(): the socket
- * prior to connection must be activated for SCTP-AUTH
- */
- sockopt_len = (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
- authchunks = OPENSSL_zalloc(sockopt_len);
- if (authchunks == NULL) {
- BIO_vfree(bio);
- return NULL;
- }
- ret = getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks,
- &sockopt_len);
- if (ret < 0) {
- OPENSSL_free(authchunks);
- BIO_vfree(bio);
- return NULL;
- }
-
- for (p = (unsigned char *)authchunks->gauth_chunks;
- p < (unsigned char *)authchunks + sockopt_len;
- p += sizeof(uint8_t)) {
- if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE)
- auth_data = 1;
- if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE)
- auth_forward = 1;
- }
-
- OPENSSL_free(authchunks);
-
- if (!auth_data || !auth_forward) {
- BIO_vfree(bio);
- BIOerr(BIO_F_BIO_NEW_DGRAM_SCTP, ERR_R_SYS_LIB);
- ERR_add_error_data(1,
- "Ensure SCTP AUTH chunks are enabled on the "
- "underlying socket");
- return NULL;
- }
-
-# ifdef SCTP_AUTHENTICATION_EVENT
-# ifdef SCTP_EVENT
- memset(&event, 0, sizeof(event));
- event.se_assoc_id = 0;
- event.se_type = SCTP_AUTHENTICATION_EVENT;
- event.se_on = 1;
- ret =
- setsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &event,
- sizeof(struct sctp_event));
- if (ret < 0) {
- BIO_vfree(bio);
- return NULL;
- }
-# else
- sockopt_len = (socklen_t) sizeof(struct sctp_event_subscribe);
- ret = getsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, &sockopt_len);
- if (ret < 0) {
- BIO_vfree(bio);
- return NULL;
- }
-
- event.sctp_authentication_event = 1;
-
- ret =
- setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event,
- sizeof(struct sctp_event_subscribe));
- if (ret < 0) {
- BIO_vfree(bio);
- return NULL;
- }
-# endif
-# endif
-
- /*
- * Disable partial delivery by setting the min size larger than the max
- * record size of 2^14 + 2048 + 13
- */
- ret =
- setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval,
- sizeof(optval));
- if (ret < 0) {
- BIO_vfree(bio);
- return NULL;
- }
-
- return bio;
-}
-
-int BIO_dgram_is_sctp(BIO *bio)
-{
- return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP);
-}
-
-static int dgram_sctp_new(BIO *bi)
-{
- bio_dgram_sctp_data *data = NULL;
-
- bi->init = 0;
- bi->num = 0;
- if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL) {
- BIOerr(BIO_F_DGRAM_SCTP_NEW, ERR_R_MALLOC_FAILURE);
- return 0;
- }
-# ifdef SCTP_PR_SCTP_NONE
- data->prinfo.pr_policy = SCTP_PR_SCTP_NONE;
-# endif
- bi->ptr = data;
-
- bi->flags = 0;
- return 1;
-}
-
-static int dgram_sctp_free(BIO *a)
-{
- bio_dgram_sctp_data *data;
-
- if (a == NULL)
- return 0;
- if (!dgram_clear(a))
- return 0;
-
- data = (bio_dgram_sctp_data *) a->ptr;
- if (data != NULL)
- OPENSSL_free(data);
-
- return 1;
-}
-
-# ifdef SCTP_AUTHENTICATION_EVENT
-void dgram_sctp_handle_auth_free_key_event(BIO *b,
- union sctp_notification *snp)
-{
- int ret;
- struct sctp_authkey_event *authkeyevent = &snp->sn_auth_event;
-
- if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY) {
- struct sctp_authkeyid authkeyid;
-
- /* delete key */
- authkeyid.scact_keynumber = authkeyevent->auth_keynumber;
- ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
- &authkeyid, sizeof(struct sctp_authkeyid));
- }
-}
-# endif
-
-static int dgram_sctp_read(BIO *b, char *out, int outl)
-{
- int ret = 0, n = 0, i, optval;
- socklen_t optlen;
- bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
- union sctp_notification *snp;
- struct msghdr msg;
- struct iovec iov;
- struct cmsghdr *cmsg;
- char cmsgbuf[512];
-
- if (out != NULL) {
- clear_socket_error();
-
- do {
- memset(&data->rcvinfo, 0, sizeof(data->rcvinfo));
- iov.iov_base = out;
- iov.iov_len = outl;
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = cmsgbuf;
- msg.msg_controllen = 512;
- msg.msg_flags = 0;
- n = recvmsg(b->num, &msg, 0);
-
- if (n <= 0) {
- if (n < 0)
- ret = n;
- break;
- }
-
- if (msg.msg_controllen > 0) {
- for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;
- cmsg = CMSG_NXTHDR(&msg, cmsg)) {
- if (cmsg->cmsg_level != IPPROTO_SCTP)
- continue;
-# ifdef SCTP_RCVINFO
- if (cmsg->cmsg_type == SCTP_RCVINFO) {
- struct sctp_rcvinfo *rcvinfo;
-
- rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg);
- data->rcvinfo.rcv_sid = rcvinfo->rcv_sid;
- data->rcvinfo.rcv_ssn = rcvinfo->rcv_ssn;
- data->rcvinfo.rcv_flags = rcvinfo->rcv_flags;
- data->rcvinfo.rcv_ppid = rcvinfo->rcv_ppid;
- data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn;
- data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn;
- data->rcvinfo.rcv_context = rcvinfo->rcv_context;
- }
-# endif
-# ifdef SCTP_SNDRCV
- if (cmsg->cmsg_type == SCTP_SNDRCV) {
- struct sctp_sndrcvinfo *sndrcvinfo;
-
- sndrcvinfo =
- (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
- data->rcvinfo.rcv_sid = sndrcvinfo->sinfo_stream;
- data->rcvinfo.rcv_ssn = sndrcvinfo->sinfo_ssn;
- data->rcvinfo.rcv_flags = sndrcvinfo->sinfo_flags;
- data->rcvinfo.rcv_ppid = sndrcvinfo->sinfo_ppid;
- data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn;
- data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn;
- data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context;
- }
-# endif
- }
- }
-
- if (msg.msg_flags & MSG_NOTIFICATION) {
- snp = (union sctp_notification *)out;
- if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
-# ifdef SCTP_EVENT
- struct sctp_event event;
-# else
- struct sctp_event_subscribe event;
- socklen_t eventsize;
-# endif
-
- /* disable sender dry event */
-# ifdef SCTP_EVENT
- memset(&event, 0, sizeof(event));
- event.se_assoc_id = 0;
- event.se_type = SCTP_SENDER_DRY_EVENT;
- event.se_on = 0;
- i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
- sizeof(struct sctp_event));
- if (i < 0) {
- ret = i;
- break;
- }
-# else
- eventsize = sizeof(struct sctp_event_subscribe);
- i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
- &eventsize);
- if (i < 0) {
- ret = i;
- break;
- }
-
- event.sctp_sender_dry_event = 0;
-
- i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
- sizeof(struct sctp_event_subscribe));
- if (i < 0) {
- ret = i;
- break;
- }
-# endif
- }
-# ifdef SCTP_AUTHENTICATION_EVENT
- if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
- dgram_sctp_handle_auth_free_key_event(b, snp);
-# endif
-
- if (data->handle_notifications != NULL)
- data->handle_notifications(b, data->notification_context,
- (void *)out);
-
- memset(out, 0, outl);
- } else
- ret += n;
- }
- while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR)
- && (ret < outl));
-
- if (ret > 0 && !(msg.msg_flags & MSG_EOR)) {
- /* Partial message read, this should never happen! */
-
- /*
- * The buffer was too small, this means the peer sent a message
- * that was larger than allowed.
- */
- if (ret == outl)
- return -1;
-
- /*
- * Test if socket buffer can handle max record size (2^14 + 2048
- * + 13)
- */
- optlen = (socklen_t) sizeof(int);
- ret = getsockopt(b->num, SOL_SOCKET, SO_RCVBUF, &optval, &optlen);
- if (ret >= 0)
- OPENSSL_assert(optval >= 18445);
-
- /*
- * Test if SCTP doesn't partially deliver below max record size
- * (2^14 + 2048 + 13)
- */
- optlen = (socklen_t) sizeof(int);
- ret =
- getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT,
- &optval, &optlen);
- if (ret >= 0)
- OPENSSL_assert(optval >= 18445);
-
- /*
- * Partially delivered notification??? Probably a bug....
- */
- OPENSSL_assert(!(msg.msg_flags & MSG_NOTIFICATION));
-
- /*
- * Everything seems ok till now, so it's most likely a message
- * dropped by PR-SCTP.
- */
- memset(out, 0, outl);
- BIO_set_retry_read(b);
- return -1;
- }
-
- BIO_clear_retry_flags(b);
- if (ret < 0) {
- if (BIO_dgram_should_retry(ret)) {
- BIO_set_retry_read(b);
- data->_errno = get_last_socket_error();
- }
- }
-
- /* Test if peer uses SCTP-AUTH before continuing */
- if (!data->peer_auth_tested) {
- int ii, auth_data = 0, auth_forward = 0;
- unsigned char *p;
- struct sctp_authchunks *authchunks;
-
- optlen =
- (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
- authchunks = OPENSSL_malloc(optlen);
- if (authchunks == NULL) {
- BIOerr(BIO_F_DGRAM_SCTP_READ, ERR_R_MALLOC_FAILURE);
- return -1;
- }
- memset(authchunks, 0, optlen);
- ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS,
- authchunks, &optlen);
-
- if (ii >= 0)
- for (p = (unsigned char *)authchunks->gauth_chunks;
- p < (unsigned char *)authchunks + optlen;
- p += sizeof(uint8_t)) {
- if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE)
- auth_data = 1;
- if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE)
- auth_forward = 1;
- }
-
- OPENSSL_free(authchunks);
-
- if (!auth_data || !auth_forward) {
- BIOerr(BIO_F_DGRAM_SCTP_READ, BIO_R_CONNECT_ERROR);
- return -1;
- }
-
- data->peer_auth_tested = 1;
- }
- }
- return ret;
-}
-
-/*
- * dgram_sctp_write - send message on SCTP socket
- * @b: BIO to write to
- * @in: data to send
- * @inl: amount of bytes in @in to send
- *
- * Returns -1 on error or the sent amount of bytes on success
- */
-static int dgram_sctp_write(BIO *b, const char *in, int inl)
-{
- int ret;
- bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
- struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo);
- struct bio_dgram_sctp_prinfo *pinfo = &(data->prinfo);
- struct bio_dgram_sctp_sndinfo handshake_sinfo;
- struct iovec iov[1];
- struct msghdr msg;
- struct cmsghdr *cmsg;
-# if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
- char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo)) +
- CMSG_SPACE(sizeof(struct sctp_prinfo))];
- struct sctp_sndinfo *sndinfo;
- struct sctp_prinfo *prinfo;
-# else
- char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
- struct sctp_sndrcvinfo *sndrcvinfo;
-# endif
-
- clear_socket_error();
-
- /*
- * If we're send anything else than application data, disable all user
- * parameters and flags.
- */
- if (in[0] != 23) {
- memset(&handshake_sinfo, 0, sizeof(handshake_sinfo));
-# ifdef SCTP_SACK_IMMEDIATELY
- handshake_sinfo.snd_flags = SCTP_SACK_IMMEDIATELY;
-# endif
- sinfo = &handshake_sinfo;
- }
-
- /* We can only send a shutdown alert if the socket is dry */
- if (data->save_shutdown) {
- ret = BIO_dgram_sctp_wait_for_dry(b);
- if (ret < 0)
- return -1;
- if (ret == 0) {
- BIO_clear_retry_flags(b);
- BIO_set_retry_write(b);
- return -1;
- }
- }
-
- iov[0].iov_base = (char *)in;
- iov[0].iov_len = inl;
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_iov = iov;
- msg.msg_iovlen = 1;
- msg.msg_control = (caddr_t) cmsgbuf;
- msg.msg_controllen = 0;
- msg.msg_flags = 0;
-# if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
- cmsg = (struct cmsghdr *)cmsgbuf;
- cmsg->cmsg_level = IPPROTO_SCTP;
- cmsg->cmsg_type = SCTP_SNDINFO;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo));
- sndinfo = (struct sctp_sndinfo *)CMSG_DATA(cmsg);
- memset(sndinfo, 0, sizeof(*sndinfo));
- sndinfo->snd_sid = sinfo->snd_sid;
- sndinfo->snd_flags = sinfo->snd_flags;
- sndinfo->snd_ppid = sinfo->snd_ppid;
- sndinfo->snd_context = sinfo->snd_context;
- msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo));
-
- cmsg =
- (struct cmsghdr *)&cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo))];
- cmsg->cmsg_level = IPPROTO_SCTP;
- cmsg->cmsg_type = SCTP_PRINFO;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo));
- prinfo = (struct sctp_prinfo *)CMSG_DATA(cmsg);
- memset(prinfo, 0, sizeof(*prinfo));
- prinfo->pr_policy = pinfo->pr_policy;
- prinfo->pr_value = pinfo->pr_value;
- msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo));
-# else
- cmsg = (struct cmsghdr *)cmsgbuf;
- cmsg->cmsg_level = IPPROTO_SCTP;
- cmsg->cmsg_type = SCTP_SNDRCV;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
- sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
- memset(sndrcvinfo, 0, sizeof(*sndrcvinfo));
- sndrcvinfo->sinfo_stream = sinfo->snd_sid;
- sndrcvinfo->sinfo_flags = sinfo->snd_flags;
-# ifdef __FreeBSD__
- sndrcvinfo->sinfo_flags |= pinfo->pr_policy;
-# endif
- sndrcvinfo->sinfo_ppid = sinfo->snd_ppid;
- sndrcvinfo->sinfo_context = sinfo->snd_context;
- sndrcvinfo->sinfo_timetolive = pinfo->pr_value;
- msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo));
-# endif
-
- ret = sendmsg(b->num, &msg, 0);
-
- BIO_clear_retry_flags(b);
- if (ret <= 0) {
- if (BIO_dgram_should_retry(ret)) {
- BIO_set_retry_write(b);
- data->_errno = get_last_socket_error();
- }
- }
- return ret;
-}
-
-static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
-{
- long ret = 1;
- bio_dgram_sctp_data *data = NULL;
- socklen_t sockopt_len = 0;
- struct sctp_authkeyid authkeyid;
- struct sctp_authkey *authkey = NULL;
-
- data = (bio_dgram_sctp_data *) b->ptr;
-
- switch (cmd) {
- case BIO_CTRL_DGRAM_QUERY_MTU:
- /*
- * Set to maximum (2^14) and ignore user input to enable transport
- * protocol fragmentation. Returns always 2^14.
- */
- data->mtu = 16384;
- ret = data->mtu;
- break;
- case BIO_CTRL_DGRAM_SET_MTU:
- /*
- * Set to maximum (2^14) and ignore input to enable transport
- * protocol fragmentation. Returns always 2^14.
- */
- data->mtu = 16384;
- ret = data->mtu;
- break;
- case BIO_CTRL_DGRAM_SET_CONNECTED:
- case BIO_CTRL_DGRAM_CONNECT:
- /* Returns always -1. */
- ret = -1;
- break;
- case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
- /*
- * SCTP doesn't need the DTLS timer Returns always 1.
- */
- break;
- case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
- /*
- * We allow transport protocol fragmentation so this is irrelevant
- */
- ret = 0;
- break;
- case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
- if (num > 0)
- data->in_handshake = 1;
- else
- data->in_handshake = 0;
-
- ret =
- setsockopt(b->num, IPPROTO_SCTP, SCTP_NODELAY,
- &data->in_handshake, sizeof(int));
- break;
- case BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY:
- /*
- * New shared key for SCTP AUTH. Returns 0 on success, -1 otherwise.
- */
-
- /* Get active key */
- sockopt_len = sizeof(struct sctp_authkeyid);
- ret =
- getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid,
- &sockopt_len);
- if (ret < 0)
- break;
-
- /* Add new key */
- sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t);
- authkey = OPENSSL_malloc(sockopt_len);
- if (authkey == NULL) {
- ret = -1;
- break;
- }
- memset(authkey, 0, sockopt_len);
- authkey->sca_keynumber = authkeyid.scact_keynumber + 1;
-# ifndef __FreeBSD__
- /*
- * This field is missing in FreeBSD 8.2 and earlier, and FreeBSD 8.3
- * and higher work without it.
- */
- authkey->sca_keylength = 64;
-# endif
- memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t));
-
- ret =
- setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey,
- sockopt_len);
- OPENSSL_free(authkey);
- authkey = NULL;
- if (ret < 0)
- break;
-
- /* Reset active key */
- ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
- &authkeyid, sizeof(struct sctp_authkeyid));
- if (ret < 0)
- break;
-
- break;
- case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY:
- /* Returns 0 on success, -1 otherwise. */
-
- /* Get active key */
- sockopt_len = sizeof(struct sctp_authkeyid);
- ret =
- getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid,
- &sockopt_len);
- if (ret < 0)
- break;
-
- /* Set active key */
- authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1;
- ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
- &authkeyid, sizeof(struct sctp_authkeyid));
- if (ret < 0)
- break;
-
- /*
- * CCS has been sent, so remember that and fall through to check if
- * we need to deactivate an old key
- */
- data->ccs_sent = 1;
- /* fall-through */
-
- case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD:
- /* Returns 0 on success, -1 otherwise. */
-
- /*
- * Has this command really been called or is this just a
- * fall-through?
- */
- if (cmd == BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD)
- data->ccs_rcvd = 1;
-
- /*
- * CSS has been both, received and sent, so deactivate an old key
- */
- if (data->ccs_rcvd == 1 && data->ccs_sent == 1) {
- /* Get active key */
- sockopt_len = sizeof(struct sctp_authkeyid);
- ret =
- getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
- &authkeyid, &sockopt_len);
- if (ret < 0)
- break;
-
- /*
- * Deactivate key or delete second last key if
- * SCTP_AUTHENTICATION_EVENT is not available.
- */
- authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
-# ifdef SCTP_AUTH_DEACTIVATE_KEY
- sockopt_len = sizeof(struct sctp_authkeyid);
- ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY,
- &authkeyid, sockopt_len);
- if (ret < 0)
- break;
-# endif
-# ifndef SCTP_AUTHENTICATION_EVENT
- if (authkeyid.scact_keynumber > 0) {
- authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
- ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
- &authkeyid, sizeof(struct sctp_authkeyid));
- if (ret < 0)
- break;
- }
-# endif
-
- data->ccs_rcvd = 0;
- data->ccs_sent = 0;
- }
- break;
- case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO:
- /* Returns the size of the copied struct. */
- if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo))
- num = sizeof(struct bio_dgram_sctp_sndinfo);
-
- memcpy(ptr, &(data->sndinfo), num);
- ret = num;
- break;
- case BIO_CTRL_DGRAM_SCTP_SET_SNDINFO:
- /* Returns the size of the copied struct. */
- if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo))
- num = sizeof(struct bio_dgram_sctp_sndinfo);
-
- memcpy(&(data->sndinfo), ptr, num);
- break;
- case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO:
- /* Returns the size of the copied struct. */
- if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo))
- num = sizeof(struct bio_dgram_sctp_rcvinfo);
-
- memcpy(ptr, &data->rcvinfo, num);
-
- ret = num;
- break;
- case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO:
- /* Returns the size of the copied struct. */
- if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo))
- num = sizeof(struct bio_dgram_sctp_rcvinfo);
-
- memcpy(&(data->rcvinfo), ptr, num);
- break;
- case BIO_CTRL_DGRAM_SCTP_GET_PRINFO:
- /* Returns the size of the copied struct. */
- if (num > (long)sizeof(struct bio_dgram_sctp_prinfo))
- num = sizeof(struct bio_dgram_sctp_prinfo);
-
- memcpy(ptr, &(data->prinfo), num);
- ret = num;
- break;
- case BIO_CTRL_DGRAM_SCTP_SET_PRINFO:
- /* Returns the size of the copied struct. */
- if (num > (long)sizeof(struct bio_dgram_sctp_prinfo))
- num = sizeof(struct bio_dgram_sctp_prinfo);
-
- memcpy(&(data->prinfo), ptr, num);
- break;
- case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN:
- /* Returns always 1. */
- if (num > 0)
- data->save_shutdown = 1;
- else
- data->save_shutdown = 0;
- break;
-
- default:
- /*
- * Pass to default ctrl function to process SCTP unspecific commands
- */
- ret = dgram_ctrl(b, cmd, num, ptr);
- break;
- }
- return ret;
-}
-
-int BIO_dgram_sctp_notification_cb(BIO *b,
- void (*handle_notifications) (BIO *bio,
- void
- *context,
- void *buf),
- void *context)
-{
- bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
-
- if (handle_notifications != NULL) {
- data->handle_notifications = handle_notifications;
- data->notification_context = context;
- } else
- return -1;
-
- return 0;
-}
-
-/*
- * BIO_dgram_sctp_wait_for_dry - Wait for SCTP SENDER_DRY event
- * @b: The BIO to check for the dry event
- *
- * Wait until the peer confirms all packets have been received, and so that
- * our kernel doesn't have anything to send anymore. This is only received by
- * the peer's kernel, not the application.
- *
- * Returns:
- * -1 on error
- * 0 when not dry yet
- * 1 when dry
- */
-int BIO_dgram_sctp_wait_for_dry(BIO *b)
-{
- int is_dry = 0;
- int sockflags = 0;
- int n, ret;
- union sctp_notification snp;
- struct msghdr msg;
- struct iovec iov;
-# ifdef SCTP_EVENT
- struct sctp_event event;
-# else
- struct sctp_event_subscribe event;
- socklen_t eventsize;
-# endif
- bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
-
- /* set sender dry event */
-# ifdef SCTP_EVENT
- memset(&event, 0, sizeof(event));
- event.se_assoc_id = 0;
- event.se_type = SCTP_SENDER_DRY_EVENT;
- event.se_on = 1;
- ret =
- setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
- sizeof(struct sctp_event));
-# else
- eventsize = sizeof(struct sctp_event_subscribe);
- ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
- if (ret < 0)
- return -1;
-
- event.sctp_sender_dry_event = 1;
-
- ret =
- setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
- sizeof(struct sctp_event_subscribe));
-# endif
- if (ret < 0)
- return -1;
-
- /* peek for notification */
- memset(&snp, 0, sizeof(snp));
- iov.iov_base = (char *)&snp;
- iov.iov_len = sizeof(union sctp_notification);
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- msg.msg_flags = 0;
-
- n = recvmsg(b->num, &msg, MSG_PEEK);
- if (n <= 0) {
- if ((n < 0) && (get_last_socket_error() != EAGAIN)
- && (get_last_socket_error() != EWOULDBLOCK))
- return -1;
- else
- return 0;
- }
-
- /* if we find a notification, process it and try again if necessary */
- while (msg.msg_flags & MSG_NOTIFICATION) {
- memset(&snp, 0, sizeof(snp));
- iov.iov_base = (char *)&snp;
- iov.iov_len = sizeof(union sctp_notification);
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- msg.msg_flags = 0;
-
- n = recvmsg(b->num, &msg, 0);
- if (n <= 0) {
- if ((n < 0) && (get_last_socket_error() != EAGAIN)
- && (get_last_socket_error() != EWOULDBLOCK))
- return -1;
- else
- return is_dry;
- }
-
- if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
- is_dry = 1;
-
- /* disable sender dry event */
-# ifdef SCTP_EVENT
- memset(&event, 0, sizeof(event));
- event.se_assoc_id = 0;
- event.se_type = SCTP_SENDER_DRY_EVENT;
- event.se_on = 0;
- ret =
- setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
- sizeof(struct sctp_event));
-# else
- eventsize = (socklen_t) sizeof(struct sctp_event_subscribe);
- ret =
- getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
- &eventsize);
- if (ret < 0)
- return -1;
-
- event.sctp_sender_dry_event = 0;
-
- ret =
- setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
- sizeof(struct sctp_event_subscribe));
-# endif
- if (ret < 0)
- return -1;
- }
-# ifdef SCTP_AUTHENTICATION_EVENT
- if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
- dgram_sctp_handle_auth_free_key_event(b, &snp);
-# endif
-
- if (data->handle_notifications != NULL)
- data->handle_notifications(b, data->notification_context,
- (void *)&snp);
-
- /* found notification, peek again */
- memset(&snp, 0, sizeof(snp));
- iov.iov_base = (char *)&snp;
- iov.iov_len = sizeof(union sctp_notification);
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- msg.msg_flags = 0;
-
- /* if we have seen the dry already, don't wait */
- if (is_dry) {
- sockflags = fcntl(b->num, F_GETFL, 0);
- fcntl(b->num, F_SETFL, O_NONBLOCK);
- }
-
- n = recvmsg(b->num, &msg, MSG_PEEK);
-
- if (is_dry) {
- fcntl(b->num, F_SETFL, sockflags);
- }
-
- if (n <= 0) {
- if ((n < 0) && (get_last_socket_error() != EAGAIN)
- && (get_last_socket_error() != EWOULDBLOCK))
- return -1;
- else
- return is_dry;
- }
- }
-
- /* read anything else */
- return is_dry;
-}
-
-int BIO_dgram_sctp_msg_waiting(BIO *b)
-{
- int n, sockflags;
- union sctp_notification snp;
- struct msghdr msg;
- struct iovec iov;
- bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
-
- /* Check if there are any messages waiting to be read */
- do {
- memset(&snp, 0, sizeof(snp));
- iov.iov_base = (char *)&snp;
- iov.iov_len = sizeof(union sctp_notification);
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- msg.msg_flags = 0;
-
- sockflags = fcntl(b->num, F_GETFL, 0);
- fcntl(b->num, F_SETFL, O_NONBLOCK);
- n = recvmsg(b->num, &msg, MSG_PEEK);
- fcntl(b->num, F_SETFL, sockflags);
-
- /* if notification, process and try again */
- if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)) {
-# ifdef SCTP_AUTHENTICATION_EVENT
- if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
- dgram_sctp_handle_auth_free_key_event(b, &snp);
-# endif
-
- memset(&snp, 0, sizeof(snp));
- iov.iov_base = (char *)&snp;
- iov.iov_len = sizeof(union sctp_notification);
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- msg.msg_flags = 0;
- n = recvmsg(b->num, &msg, 0);
-
- if (data->handle_notifications != NULL)
- data->handle_notifications(b, data->notification_context,
- (void *)&snp);
- }
-
- } while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION));
-
- /* Return 1 if there is a message to be read, return 0 otherwise. */
- if (n > 0)
- return 1;
- else
- return 0;
-}
-
-static int dgram_sctp_puts(BIO *bp, const char *str)
-{
- int n, ret;
-
- n = strlen(str);
- ret = dgram_sctp_write(bp, str, n);
- return ret;
-}
-# endif
-
-static int BIO_dgram_should_retry(int i)
-{
- int err;
-
- if ((i == 0) || (i == -1)) {
- err = get_last_socket_error();
-
-# if defined(OPENSSL_SYS_WINDOWS)
- /*
- * If the socket return value (i) is -1 and err is unexpectedly 0 at
- * this point, the error code was overwritten by another system call
- * before this error handling is called.
- */
-# endif
-
- return BIO_dgram_non_fatal_error(err);
- }
- return 0;
-}
-
-int BIO_dgram_non_fatal_error(int err)
-{
- switch (err) {
-# if defined(OPENSSL_SYS_WINDOWS)
-# if defined(WSAEWOULDBLOCK)
- case WSAEWOULDBLOCK:
-# endif
-# endif
-
-# ifdef EWOULDBLOCK
-# ifdef WSAEWOULDBLOCK
-# if WSAEWOULDBLOCK != EWOULDBLOCK
- case EWOULDBLOCK:
-# endif
-# else
- case EWOULDBLOCK:
-# endif
-# endif
-
-# ifdef EINTR
- case EINTR:
-# endif
-
-# ifdef EAGAIN
-# if EWOULDBLOCK != EAGAIN
- case EAGAIN:
-# endif
-# endif
-
-# ifdef EPROTO
- case EPROTO:
-# endif
-
-# ifdef EINPROGRESS
- case EINPROGRESS:
-# endif
-
-# ifdef EALREADY
- case EALREADY:
-# endif
-
- return 1;
- default:
- break;
- }
- return 0;
-}
-
-static void get_current_time(struct timeval *t)
-{
-# if defined(_WIN32)
- SYSTEMTIME st;
- union {
- unsigned __int64 ul;
- FILETIME ft;
- } now;
-
- GetSystemTime(&st);
- SystemTimeToFileTime(&st, &now.ft);
-# ifdef __MINGW32__
- now.ul -= 116444736000000000ULL;
-# else
- now.ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */
-# endif
- t->tv_sec = (long)(now.ul / 10000000);
- t->tv_usec = ((int)(now.ul % 10000000)) / 10;
-# else
- gettimeofday(t, NULL);
-# endif
-}
-
-#endif
+ */
+ case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
+ case BIO_CTRL_DGRAM_SET_PEEK_MODE:
+ data->peekmode = (unsigned int)num;
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+static int dgram_puts(BIO *bp, const char *str)
+{
+ int n, ret;
+
+ n = strlen(str);
+ ret = dgram_write(bp, str, n);
+ return ret;
+}
+
+# ifndef OPENSSL_NO_SCTP
+const BIO_METHOD *BIO_s_datagram_sctp(void)
+{
+ return &methods_dgramp_sctp;
+}
+
+BIO *BIO_new_dgram_sctp(int fd, int close_flag)
+{
+ BIO *bio;
+ int ret, optval = 20000;
+ int auth_data = 0, auth_forward = 0;
+ unsigned char *p;
+ struct sctp_authchunk auth;
+ struct sctp_authchunks *authchunks;
+ socklen_t sockopt_len;
+# ifdef SCTP_AUTHENTICATION_EVENT
+# ifdef SCTP_EVENT
+ struct sctp_event event;
+# else
+ struct sctp_event_subscribe event;
+# endif
+# endif
+
+ bio = BIO_new(BIO_s_datagram_sctp());
+ if (bio == NULL)
+ return NULL;
+ BIO_set_fd(bio, fd, close_flag);
+
+ /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */
+ auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE;
+ ret =
+ setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth,
+ sizeof(struct sctp_authchunk));
+ if (ret < 0) {
+ BIO_vfree(bio);
+ BIOerr(BIO_F_BIO_NEW_DGRAM_SCTP, ERR_R_SYS_LIB);
+ ERR_add_error_data(1, "Ensure SCTP AUTH chunks are enabled in kernel");
+ return NULL;
+ }
+ auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE;
+ ret =
+ setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth,
+ sizeof(struct sctp_authchunk));
+ if (ret < 0) {
+ BIO_vfree(bio);
+ BIOerr(BIO_F_BIO_NEW_DGRAM_SCTP, ERR_R_SYS_LIB);
+ ERR_add_error_data(1, "Ensure SCTP AUTH chunks are enabled in kernel");
+ return NULL;
+ }
+
+ /*
+ * Test if activation was successful. When using accept(), SCTP-AUTH has
+ * to be activated for the listening socket already, otherwise the
+ * connected socket won't use it. Similarly with connect(): the socket
+ * prior to connection must be activated for SCTP-AUTH
+ */
+ sockopt_len = (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
+ authchunks = OPENSSL_zalloc(sockopt_len);
+ if (authchunks == NULL) {
+ BIO_vfree(bio);
+ return NULL;
+ }
+ ret = getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks,
+ &sockopt_len);
+ if (ret < 0) {
+ OPENSSL_free(authchunks);
+ BIO_vfree(bio);
+ return NULL;
+ }
+
+ for (p = (unsigned char *)authchunks->gauth_chunks;
+ p < (unsigned char *)authchunks + sockopt_len;
+ p += sizeof(uint8_t)) {
+ if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE)
+ auth_data = 1;
+ if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE)
+ auth_forward = 1;
+ }
+
+ OPENSSL_free(authchunks);
+
+ if (!auth_data || !auth_forward) {
+ BIO_vfree(bio);
+ BIOerr(BIO_F_BIO_NEW_DGRAM_SCTP, ERR_R_SYS_LIB);
+ ERR_add_error_data(1,
+ "Ensure SCTP AUTH chunks are enabled on the "
+ "underlying socket");
+ return NULL;
+ }
+
+# ifdef SCTP_AUTHENTICATION_EVENT
+# ifdef SCTP_EVENT
+ memset(&event, 0, sizeof(event));
+ event.se_assoc_id = 0;
+ event.se_type = SCTP_AUTHENTICATION_EVENT;
+ event.se_on = 1;
+ ret =
+ setsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &event,
+ sizeof(struct sctp_event));
+ if (ret < 0) {
+ BIO_vfree(bio);
+ return NULL;
+ }
+# else
+ sockopt_len = (socklen_t) sizeof(struct sctp_event_subscribe);
+ ret = getsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, &sockopt_len);
+ if (ret < 0) {
+ BIO_vfree(bio);
+ return NULL;
+ }
+
+ event.sctp_authentication_event = 1;
+
+ ret =
+ setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event,
+ sizeof(struct sctp_event_subscribe));
+ if (ret < 0) {
+ BIO_vfree(bio);
+ return NULL;
+ }
+# endif
+# endif
+
+ /*
+ * Disable partial delivery by setting the min size larger than the max
+ * record size of 2^14 + 2048 + 13
+ */
+ ret =
+ setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval,
+ sizeof(optval));
+ if (ret < 0) {
+ BIO_vfree(bio);
+ return NULL;
+ }
+
+ return bio;
+}
+
+int BIO_dgram_is_sctp(BIO *bio)
+{
+ return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP);
+}
+
+static int dgram_sctp_new(BIO *bi)
+{
+ bio_dgram_sctp_data *data = NULL;
+
+ bi->init = 0;
+ bi->num = 0;
+ if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL) {
+ BIOerr(BIO_F_DGRAM_SCTP_NEW, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+# ifdef SCTP_PR_SCTP_NONE
+ data->prinfo.pr_policy = SCTP_PR_SCTP_NONE;
+# endif
+ bi->ptr = data;
+
+ bi->flags = 0;
+ return 1;
+}
+
+static int dgram_sctp_free(BIO *a)
+{
+ bio_dgram_sctp_data *data;
+
+ if (a == NULL)
+ return 0;
+ if (!dgram_clear(a))
+ return 0;
+
+ data = (bio_dgram_sctp_data *) a->ptr;
+ if (data != NULL)
+ OPENSSL_free(data);
+
+ return 1;
+}
+
+# ifdef SCTP_AUTHENTICATION_EVENT
+void dgram_sctp_handle_auth_free_key_event(BIO *b,
+ union sctp_notification *snp)
+{
+ int ret;
+ struct sctp_authkey_event *authkeyevent = &snp->sn_auth_event;
+
+ if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY) {
+ struct sctp_authkeyid authkeyid;
+
+ /* delete key */
+ authkeyid.scact_keynumber = authkeyevent->auth_keynumber;
+ ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
+ &authkeyid, sizeof(struct sctp_authkeyid));
+ }
+}
+# endif
+
+static int dgram_sctp_read(BIO *b, char *out, int outl)
+{
+ int ret = 0, n = 0, i, optval;
+ socklen_t optlen;
+ bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
+ union sctp_notification *snp;
+ struct msghdr msg;
+ struct iovec iov;
+ struct cmsghdr *cmsg;
+ char cmsgbuf[512];
+
+ if (out != NULL) {
+ clear_socket_error();
+
+ do {
+ memset(&data->rcvinfo, 0, sizeof(data->rcvinfo));
+ iov.iov_base = out;
+ iov.iov_len = outl;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = 512;
+ msg.msg_flags = 0;
+ n = recvmsg(b->num, &msg, 0);
+
+ if (n <= 0) {
+ if (n < 0)
+ ret = n;
+ break;
+ }
+
+ if (msg.msg_controllen > 0) {
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ if (cmsg->cmsg_level != IPPROTO_SCTP)
+ continue;
+# ifdef SCTP_RCVINFO
+ if (cmsg->cmsg_type == SCTP_RCVINFO) {
+ struct sctp_rcvinfo *rcvinfo;
+
+ rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg);
+ data->rcvinfo.rcv_sid = rcvinfo->rcv_sid;
+ data->rcvinfo.rcv_ssn = rcvinfo->rcv_ssn;
+ data->rcvinfo.rcv_flags = rcvinfo->rcv_flags;
+ data->rcvinfo.rcv_ppid = rcvinfo->rcv_ppid;
+ data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn;
+ data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn;
+ data->rcvinfo.rcv_context = rcvinfo->rcv_context;
+ }
+# endif
+# ifdef SCTP_SNDRCV
+ if (cmsg->cmsg_type == SCTP_SNDRCV) {
+ struct sctp_sndrcvinfo *sndrcvinfo;
+
+ sndrcvinfo =
+ (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ data->rcvinfo.rcv_sid = sndrcvinfo->sinfo_stream;
+ data->rcvinfo.rcv_ssn = sndrcvinfo->sinfo_ssn;
+ data->rcvinfo.rcv_flags = sndrcvinfo->sinfo_flags;
+ data->rcvinfo.rcv_ppid = sndrcvinfo->sinfo_ppid;
+ data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn;
+ data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn;
+ data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context;
+ }
+# endif
+ }
+ }
+
+ if (msg.msg_flags & MSG_NOTIFICATION) {
+ snp = (union sctp_notification *)out;
+ if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
+# ifdef SCTP_EVENT
+ struct sctp_event event;
+# else
+ struct sctp_event_subscribe event;
+ socklen_t eventsize;
+# endif
+
+ /* disable sender dry event */
+# ifdef SCTP_EVENT
+ memset(&event, 0, sizeof(event));
+ event.se_assoc_id = 0;
+ event.se_type = SCTP_SENDER_DRY_EVENT;
+ event.se_on = 0;
+ i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
+ sizeof(struct sctp_event));
+ if (i < 0) {
+ ret = i;
+ break;
+ }
+# else
+ eventsize = sizeof(struct sctp_event_subscribe);
+ i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
+ &eventsize);
+ if (i < 0) {
+ ret = i;
+ break;
+ }
+
+ event.sctp_sender_dry_event = 0;
+
+ i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
+ sizeof(struct sctp_event_subscribe));
+ if (i < 0) {
+ ret = i;
+ break;
+ }
+# endif
+ }
+# ifdef SCTP_AUTHENTICATION_EVENT
+ if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
+ dgram_sctp_handle_auth_free_key_event(b, snp);
+# endif
+
+ if (data->handle_notifications != NULL)
+ data->handle_notifications(b, data->notification_context,
+ (void *)out);
+
+ memset(out, 0, outl);
+ } else
+ ret += n;
+ }
+ while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR)
+ && (ret < outl));
+
+ if (ret > 0 && !(msg.msg_flags & MSG_EOR)) {
+ /* Partial message read, this should never happen! */
+
+ /*
+ * The buffer was too small, this means the peer sent a message
+ * that was larger than allowed.
+ */
+ if (ret == outl)
+ return -1;
+
+ /*
+ * Test if socket buffer can handle max record size (2^14 + 2048
+ * + 13)
+ */
+ optlen = (socklen_t) sizeof(int);
+ ret = getsockopt(b->num, SOL_SOCKET, SO_RCVBUF, &optval, &optlen);
+ if (ret >= 0)
+ OPENSSL_assert(optval >= 18445);
+
+ /*
+ * Test if SCTP doesn't partially deliver below max record size
+ * (2^14 + 2048 + 13)
+ */
+ optlen = (socklen_t) sizeof(int);
+ ret =
+ getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT,
+ &optval, &optlen);
+ if (ret >= 0)
+ OPENSSL_assert(optval >= 18445);
+
+ /*
+ * Partially delivered notification??? Probably a bug....
+ */
+ OPENSSL_assert(!(msg.msg_flags & MSG_NOTIFICATION));
+
+ /*
+ * Everything seems ok till now, so it's most likely a message
+ * dropped by PR-SCTP.
+ */
+ memset(out, 0, outl);
+ BIO_set_retry_read(b);
+ return -1;
+ }
+
+ BIO_clear_retry_flags(b);
+ if (ret < 0) {
+ if (BIO_dgram_should_retry(ret)) {
+ BIO_set_retry_read(b);
+ data->_errno = get_last_socket_error();
+ }
+ }
+
+ /* Test if peer uses SCTP-AUTH before continuing */
+ if (!data->peer_auth_tested) {
+ int ii, auth_data = 0, auth_forward = 0;
+ unsigned char *p;
+ struct sctp_authchunks *authchunks;
+
+ optlen =
+ (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
+ authchunks = OPENSSL_malloc(optlen);
+ if (authchunks == NULL) {
+ BIOerr(BIO_F_DGRAM_SCTP_READ, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ memset(authchunks, 0, optlen);
+ ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS,
+ authchunks, &optlen);
+
+ if (ii >= 0)
+ for (p = (unsigned char *)authchunks->gauth_chunks;
+ p < (unsigned char *)authchunks + optlen;
+ p += sizeof(uint8_t)) {
+ if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE)
+ auth_data = 1;
+ if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE)
+ auth_forward = 1;
+ }
+
+ OPENSSL_free(authchunks);
+
+ if (!auth_data || !auth_forward) {
+ BIOerr(BIO_F_DGRAM_SCTP_READ, BIO_R_CONNECT_ERROR);
+ return -1;
+ }
+
+ data->peer_auth_tested = 1;
+ }
+ }
+ return ret;
+}
+
+/*
+ * dgram_sctp_write - send message on SCTP socket
+ * @b: BIO to write to
+ * @in: data to send
+ * @inl: amount of bytes in @in to send
+ *
+ * Returns -1 on error or the sent amount of bytes on success
+ */
+static int dgram_sctp_write(BIO *b, const char *in, int inl)
+{
+ int ret;
+ bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
+ struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo);
+ struct bio_dgram_sctp_prinfo *pinfo = &(data->prinfo);
+ struct bio_dgram_sctp_sndinfo handshake_sinfo;
+ struct iovec iov[1];
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+# if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
+ char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo)) +
+ CMSG_SPACE(sizeof(struct sctp_prinfo))];
+ struct sctp_sndinfo *sndinfo;
+ struct sctp_prinfo *prinfo;
+# else
+ char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct sctp_sndrcvinfo *sndrcvinfo;
+# endif
+
+ clear_socket_error();
+
+ /*
+ * If we're send anything else than application data, disable all user
+ * parameters and flags.
+ */
+ if (in[0] != 23) {
+ memset(&handshake_sinfo, 0, sizeof(handshake_sinfo));
+# ifdef SCTP_SACK_IMMEDIATELY
+ handshake_sinfo.snd_flags = SCTP_SACK_IMMEDIATELY;
+# endif
+ sinfo = &handshake_sinfo;
+ }
+
+ /* We can only send a shutdown alert if the socket is dry */
+ if (data->save_shutdown) {
+ ret = BIO_dgram_sctp_wait_for_dry(b);
+ if (ret < 0)
+ return -1;
+ if (ret == 0) {
+ BIO_clear_retry_flags(b);
+ BIO_set_retry_write(b);
+ return -1;
+ }
+ }
+
+ iov[0].iov_base = (char *)in;
+ iov[0].iov_len = inl;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = (caddr_t) cmsgbuf;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+# if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
+ cmsg = (struct cmsghdr *)cmsgbuf;
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDINFO;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo));
+ sndinfo = (struct sctp_sndinfo *)CMSG_DATA(cmsg);
+ memset(sndinfo, 0, sizeof(*sndinfo));
+ sndinfo->snd_sid = sinfo->snd_sid;
+ sndinfo->snd_flags = sinfo->snd_flags;
+ sndinfo->snd_ppid = sinfo->snd_ppid;
+ sndinfo->snd_context = sinfo->snd_context;
+ msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo));
+
+ cmsg =
+ (struct cmsghdr *)&cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo))];
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_PRINFO;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo));
+ prinfo = (struct sctp_prinfo *)CMSG_DATA(cmsg);
+ memset(prinfo, 0, sizeof(*prinfo));
+ prinfo->pr_policy = pinfo->pr_policy;
+ prinfo->pr_value = pinfo->pr_value;
+ msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo));
+# else
+ cmsg = (struct cmsghdr *)cmsgbuf;
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ memset(sndrcvinfo, 0, sizeof(*sndrcvinfo));
+ sndrcvinfo->sinfo_stream = sinfo->snd_sid;
+ sndrcvinfo->sinfo_flags = sinfo->snd_flags;
+# ifdef __FreeBSD__
+ sndrcvinfo->sinfo_flags |= pinfo->pr_policy;
+# endif
+ sndrcvinfo->sinfo_ppid = sinfo->snd_ppid;
+ sndrcvinfo->sinfo_context = sinfo->snd_context;
+ sndrcvinfo->sinfo_timetolive = pinfo->pr_value;
+ msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo));
+# endif
+
+ ret = sendmsg(b->num, &msg, 0);
+
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_dgram_should_retry(ret)) {
+ BIO_set_retry_write(b);
+ data->_errno = get_last_socket_error();
+ }
+ }
+ return ret;
+}
+
+static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ long ret = 1;
+ bio_dgram_sctp_data *data = NULL;
+ socklen_t sockopt_len = 0;
+ struct sctp_authkeyid authkeyid;
+ struct sctp_authkey *authkey = NULL;
+
+ data = (bio_dgram_sctp_data *) b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_DGRAM_QUERY_MTU:
+ /*
+ * Set to maximum (2^14) and ignore user input to enable transport
+ * protocol fragmentation. Returns always 2^14.
+ */
+ data->mtu = 16384;
+ ret = data->mtu;
+ break;
+ case BIO_CTRL_DGRAM_SET_MTU:
+ /*
+ * Set to maximum (2^14) and ignore input to enable transport
+ * protocol fragmentation. Returns always 2^14.
+ */
+ data->mtu = 16384;
+ ret = data->mtu;
+ break;
+ case BIO_CTRL_DGRAM_SET_CONNECTED:
+ case BIO_CTRL_DGRAM_CONNECT:
+ /* Returns always -1. */
+ ret = -1;
+ break;
+ case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
+ /*
+ * SCTP doesn't need the DTLS timer Returns always 1.
+ */
+ break;
+ case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
+ /*
+ * We allow transport protocol fragmentation so this is irrelevant
+ */
+ ret = 0;
+ break;
+ case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
+ if (num > 0)
+ data->in_handshake = 1;
+ else
+ data->in_handshake = 0;
+
+ ret =
+ setsockopt(b->num, IPPROTO_SCTP, SCTP_NODELAY,
+ &data->in_handshake, sizeof(int));
+ break;
+ case BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY:
+ /*
+ * New shared key for SCTP AUTH. Returns 0 on success, -1 otherwise.
+ */
+
+ /* Get active key */
+ sockopt_len = sizeof(struct sctp_authkeyid);
+ ret =
+ getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid,
+ &sockopt_len);
+ if (ret < 0)
+ break;
+
+ /* Add new key */
+ sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t);
+ authkey = OPENSSL_malloc(sockopt_len);
+ if (authkey == NULL) {
+ ret = -1;
+ break;
+ }
+ memset(authkey, 0, sockopt_len);
+ authkey->sca_keynumber = authkeyid.scact_keynumber + 1;
+# ifndef __FreeBSD__
+ /*
+ * This field is missing in FreeBSD 8.2 and earlier, and FreeBSD 8.3
+ * and higher work without it.
+ */
+ authkey->sca_keylength = 64;
+# endif
+ memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t));
+
+ ret =
+ setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey,
+ sockopt_len);
+ OPENSSL_free(authkey);
+ authkey = NULL;
+ if (ret < 0)
+ break;
+
+ /* Reset active key */
+ ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
+ &authkeyid, sizeof(struct sctp_authkeyid));
+ if (ret < 0)
+ break;
+
+ break;
+ case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY:
+ /* Returns 0 on success, -1 otherwise. */
+
+ /* Get active key */
+ sockopt_len = sizeof(struct sctp_authkeyid);
+ ret =
+ getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid,
+ &sockopt_len);
+ if (ret < 0)
+ break;
+
+ /* Set active key */
+ authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1;
+ ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
+ &authkeyid, sizeof(struct sctp_authkeyid));
+ if (ret < 0)
+ break;
+
+ /*
+ * CCS has been sent, so remember that and fall through to check if
+ * we need to deactivate an old key
+ */
+ data->ccs_sent = 1;
+ /* fall-through */
+
+ case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD:
+ /* Returns 0 on success, -1 otherwise. */
+
+ /*
+ * Has this command really been called or is this just a
+ * fall-through?
+ */
+ if (cmd == BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD)
+ data->ccs_rcvd = 1;
+
+ /*
+ * CSS has been both, received and sent, so deactivate an old key
+ */
+ if (data->ccs_rcvd == 1 && data->ccs_sent == 1) {
+ /* Get active key */
+ sockopt_len = sizeof(struct sctp_authkeyid);
+ ret =
+ getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
+ &authkeyid, &sockopt_len);
+ if (ret < 0)
+ break;
+
+ /*
+ * Deactivate key or delete second last key if
+ * SCTP_AUTHENTICATION_EVENT is not available.
+ */
+ authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
+# ifdef SCTP_AUTH_DEACTIVATE_KEY
+ sockopt_len = sizeof(struct sctp_authkeyid);
+ ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY,
+ &authkeyid, sockopt_len);
+ if (ret < 0)
+ break;
+# endif
+# ifndef SCTP_AUTHENTICATION_EVENT
+ if (authkeyid.scact_keynumber > 0) {
+ authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
+ ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
+ &authkeyid, sizeof(struct sctp_authkeyid));
+ if (ret < 0)
+ break;
+ }
+# endif
+
+ data->ccs_rcvd = 0;
+ data->ccs_sent = 0;
+ }
+ break;
+ case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO:
+ /* Returns the size of the copied struct. */
+ if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo))
+ num = sizeof(struct bio_dgram_sctp_sndinfo);
+
+ memcpy(ptr, &(data->sndinfo), num);
+ ret = num;
+ break;
+ case BIO_CTRL_DGRAM_SCTP_SET_SNDINFO:
+ /* Returns the size of the copied struct. */
+ if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo))
+ num = sizeof(struct bio_dgram_sctp_sndinfo);
+
+ memcpy(&(data->sndinfo), ptr, num);
+ break;
+ case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO:
+ /* Returns the size of the copied struct. */
+ if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo))
+ num = sizeof(struct bio_dgram_sctp_rcvinfo);
+
+ memcpy(ptr, &data->rcvinfo, num);
+
+ ret = num;
+ break;
+ case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO:
+ /* Returns the size of the copied struct. */
+ if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo))
+ num = sizeof(struct bio_dgram_sctp_rcvinfo);
+
+ memcpy(&(data->rcvinfo), ptr, num);
+ break;
+ case BIO_CTRL_DGRAM_SCTP_GET_PRINFO:
+ /* Returns the size of the copied struct. */
+ if (num > (long)sizeof(struct bio_dgram_sctp_prinfo))
+ num = sizeof(struct bio_dgram_sctp_prinfo);
+
+ memcpy(ptr, &(data->prinfo), num);
+ ret = num;
+ break;
+ case BIO_CTRL_DGRAM_SCTP_SET_PRINFO:
+ /* Returns the size of the copied struct. */
+ if (num > (long)sizeof(struct bio_dgram_sctp_prinfo))
+ num = sizeof(struct bio_dgram_sctp_prinfo);
+
+ memcpy(&(data->prinfo), ptr, num);
+ break;
+ case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN:
+ /* Returns always 1. */
+ if (num > 0)
+ data->save_shutdown = 1;
+ else
+ data->save_shutdown = 0;
+ break;
+
+ default:
+ /*
+ * Pass to default ctrl function to process SCTP unspecific commands
+ */
+ ret = dgram_ctrl(b, cmd, num, ptr);
+ break;
+ }
+ return ret;
+}
+
+int BIO_dgram_sctp_notification_cb(BIO *b,
+ void (*handle_notifications) (BIO *bio,
+ void
+ *context,
+ void *buf),
+ void *context)
+{
+ bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
+
+ if (handle_notifications != NULL) {
+ data->handle_notifications = handle_notifications;
+ data->notification_context = context;
+ } else
+ return -1;
+
+ return 0;
+}
+
+/*
+ * BIO_dgram_sctp_wait_for_dry - Wait for SCTP SENDER_DRY event
+ * @b: The BIO to check for the dry event
+ *
+ * Wait until the peer confirms all packets have been received, and so that
+ * our kernel doesn't have anything to send anymore. This is only received by
+ * the peer's kernel, not the application.
+ *
+ * Returns:
+ * -1 on error
+ * 0 when not dry yet
+ * 1 when dry
+ */
+int BIO_dgram_sctp_wait_for_dry(BIO *b)
+{
+ int is_dry = 0;
+ int sockflags = 0;
+ int n, ret;
+ union sctp_notification snp;
+ struct msghdr msg;
+ struct iovec iov;
+# ifdef SCTP_EVENT
+ struct sctp_event event;
+# else
+ struct sctp_event_subscribe event;
+ socklen_t eventsize;
+# endif
+ bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
+
+ /* set sender dry event */
+# ifdef SCTP_EVENT
+ memset(&event, 0, sizeof(event));
+ event.se_assoc_id = 0;
+ event.se_type = SCTP_SENDER_DRY_EVENT;
+ event.se_on = 1;
+ ret =
+ setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
+ sizeof(struct sctp_event));
+# else
+ eventsize = sizeof(struct sctp_event_subscribe);
+ ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
+ if (ret < 0)
+ return -1;
+
+ event.sctp_sender_dry_event = 1;
+
+ ret =
+ setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
+ sizeof(struct sctp_event_subscribe));
+# endif
+ if (ret < 0)
+ return -1;
+
+ /* peek for notification */
+ memset(&snp, 0, sizeof(snp));
+ iov.iov_base = (char *)&snp;
+ iov.iov_len = sizeof(union sctp_notification);
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+
+ n = recvmsg(b->num, &msg, MSG_PEEK);
+ if (n <= 0) {
+ if ((n < 0) && (get_last_socket_error() != EAGAIN)
+ && (get_last_socket_error() != EWOULDBLOCK))
+ return -1;
+ else
+ return 0;
+ }
+
+ /* if we find a notification, process it and try again if necessary */
+ while (msg.msg_flags & MSG_NOTIFICATION) {
+ memset(&snp, 0, sizeof(snp));
+ iov.iov_base = (char *)&snp;
+ iov.iov_len = sizeof(union sctp_notification);
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+
+ n = recvmsg(b->num, &msg, 0);
+ if (n <= 0) {
+ if ((n < 0) && (get_last_socket_error() != EAGAIN)
+ && (get_last_socket_error() != EWOULDBLOCK))
+ return -1;
+ else
+ return is_dry;
+ }
+
+ if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
+ is_dry = 1;
+
+ /* disable sender dry event */
+# ifdef SCTP_EVENT
+ memset(&event, 0, sizeof(event));
+ event.se_assoc_id = 0;
+ event.se_type = SCTP_SENDER_DRY_EVENT;
+ event.se_on = 0;
+ ret =
+ setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
+ sizeof(struct sctp_event));
+# else
+ eventsize = (socklen_t) sizeof(struct sctp_event_subscribe);
+ ret =
+ getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
+ &eventsize);
+ if (ret < 0)
+ return -1;
+
+ event.sctp_sender_dry_event = 0;
+
+ ret =
+ setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
+ sizeof(struct sctp_event_subscribe));
+# endif
+ if (ret < 0)
+ return -1;
+ }
+# ifdef SCTP_AUTHENTICATION_EVENT
+ if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
+ dgram_sctp_handle_auth_free_key_event(b, &snp);
+# endif
+
+ if (data->handle_notifications != NULL)
+ data->handle_notifications(b, data->notification_context,
+ (void *)&snp);
+
+ /* found notification, peek again */
+ memset(&snp, 0, sizeof(snp));
+ iov.iov_base = (char *)&snp;
+ iov.iov_len = sizeof(union sctp_notification);
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+
+ /* if we have seen the dry already, don't wait */
+ if (is_dry) {
+ sockflags = fcntl(b->num, F_GETFL, 0);
+ fcntl(b->num, F_SETFL, O_NONBLOCK);
+ }
+
+ n = recvmsg(b->num, &msg, MSG_PEEK);
+
+ if (is_dry) {
+ fcntl(b->num, F_SETFL, sockflags);
+ }
+
+ if (n <= 0) {
+ if ((n < 0) && (get_last_socket_error() != EAGAIN)
+ && (get_last_socket_error() != EWOULDBLOCK))
+ return -1;
+ else
+ return is_dry;
+ }
+ }
+
+ /* read anything else */
+ return is_dry;
+}
+
+int BIO_dgram_sctp_msg_waiting(BIO *b)
+{
+ int n, sockflags;
+ union sctp_notification snp;
+ struct msghdr msg;
+ struct iovec iov;
+ bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
+
+ /* Check if there are any messages waiting to be read */
+ do {
+ memset(&snp, 0, sizeof(snp));
+ iov.iov_base = (char *)&snp;
+ iov.iov_len = sizeof(union sctp_notification);
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+
+ sockflags = fcntl(b->num, F_GETFL, 0);
+ fcntl(b->num, F_SETFL, O_NONBLOCK);
+ n = recvmsg(b->num, &msg, MSG_PEEK);
+ fcntl(b->num, F_SETFL, sockflags);
+
+ /* if notification, process and try again */
+ if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)) {
+# ifdef SCTP_AUTHENTICATION_EVENT
+ if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
+ dgram_sctp_handle_auth_free_key_event(b, &snp);
+# endif
+
+ memset(&snp, 0, sizeof(snp));
+ iov.iov_base = (char *)&snp;
+ iov.iov_len = sizeof(union sctp_notification);
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+ n = recvmsg(b->num, &msg, 0);
+
+ if (data->handle_notifications != NULL)
+ data->handle_notifications(b, data->notification_context,
+ (void *)&snp);
+ }
+
+ } while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION));
+
+ /* Return 1 if there is a message to be read, return 0 otherwise. */
+ if (n > 0)
+ return 1;
+ else
+ return 0;
+}
+
+static int dgram_sctp_puts(BIO *bp, const char *str)
+{
+ int n, ret;
+
+ n = strlen(str);
+ ret = dgram_sctp_write(bp, str, n);
+ return ret;
+}
+# endif
+
+static int BIO_dgram_should_retry(int i)
+{
+ int err;
+
+ if ((i == 0) || (i == -1)) {
+ err = get_last_socket_error();
+
+# if defined(OPENSSL_SYS_WINDOWS)
+ /*
+ * If the socket return value (i) is -1 and err is unexpectedly 0 at
+ * this point, the error code was overwritten by another system call
+ * before this error handling is called.
+ */
+# endif
+
+ return BIO_dgram_non_fatal_error(err);
+ }
+ return 0;
+}
+
+int BIO_dgram_non_fatal_error(int err)
+{
+ switch (err) {
+# if defined(OPENSSL_SYS_WINDOWS)
+# if defined(WSAEWOULDBLOCK)
+ case WSAEWOULDBLOCK:
+# endif
+# endif
+
+# ifdef EWOULDBLOCK
+# ifdef WSAEWOULDBLOCK
+# if WSAEWOULDBLOCK != EWOULDBLOCK
+ case EWOULDBLOCK:
+# endif
+# else
+ case EWOULDBLOCK:
+# endif
+# endif
+
+# ifdef EINTR
+ case EINTR:
+# endif
+
+# ifdef EAGAIN
+# if EWOULDBLOCK != EAGAIN
+ case EAGAIN:
+# endif
+# endif
+
+# ifdef EPROTO
+ case EPROTO:
+# endif
+
+# ifdef EINPROGRESS
+ case EINPROGRESS:
+# endif
+
+# ifdef EALREADY
+ case EALREADY:
+# endif
+
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static void get_current_time(struct timeval *t)
+{
+# if defined(_WIN32)
+ SYSTEMTIME st;
+ union {
+ unsigned __int64 ul;
+ FILETIME ft;
+ } now;
+
+ GetSystemTime(&st);
+ SystemTimeToFileTime(&st, &now.ft);
+# ifdef __MINGW32__
+ now.ul -= 116444736000000000ULL;
+# else
+ now.ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */
+# endif
+ t->tv_sec = (long)(now.ul / 10000000);
+ t->tv_usec = ((int)(now.ul % 10000000)) / 10;
+# else
+ gettimeofday(t, NULL);
+# endif
+}
+
+#endif
diff --git a/contrib/libs/openssl/crypto/bio/bss_fd.c b/contrib/libs/openssl/crypto/bio/bss_fd.c
index 37702b778a..ccbe1626ba 100644
--- a/contrib/libs/openssl/crypto/bio/bss_fd.c
+++ b/contrib/libs/openssl/crypto/bio/bss_fd.c
@@ -1,285 +1,285 @@
-/*
+/*
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include <errno.h>
-
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <errno.h>
+
#include "bio_local.h"
-
-#if defined(OPENSSL_NO_POSIX_IO)
-/*
- * Dummy placeholder for BIO_s_fd...
- */
-BIO *BIO_new_fd(int fd, int close_flag)
-{
- return NULL;
-}
-
-int BIO_fd_non_fatal_error(int err)
-{
- return 0;
-}
-
-int BIO_fd_should_retry(int i)
-{
- return 0;
-}
-
-const BIO_METHOD *BIO_s_fd(void)
-{
- return NULL;
-}
-#else
-/*
- * As for unconditional usage of "UPLINK" interface in this module.
- * Trouble is that unlike Unix file descriptors [which are indexes
- * in kernel-side per-process table], corresponding descriptors on
- * platforms which require "UPLINK" interface seem to be indexes
- * in a user-land, non-global table. Well, in fact they are indexes
- * in stdio _iob[], and recall that _iob[] was the very reason why
- * "UPLINK" interface was introduced in first place. But one way on
- * another. Neither libcrypto or libssl use this BIO meaning that
- * file descriptors can only be provided by application. Therefore
- * "UPLINK" calls are due...
- */
-static int fd_write(BIO *h, const char *buf, int num);
-static int fd_read(BIO *h, char *buf, int size);
-static int fd_puts(BIO *h, const char *str);
-static int fd_gets(BIO *h, char *buf, int size);
-static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-static int fd_new(BIO *h);
-static int fd_free(BIO *data);
-int BIO_fd_should_retry(int s);
-
-static const BIO_METHOD methods_fdp = {
- BIO_TYPE_FD,
- "file descriptor",
- /* TODO: Convert to new style write function */
- bwrite_conv,
- fd_write,
- /* TODO: Convert to new style read function */
- bread_conv,
- fd_read,
- fd_puts,
- fd_gets,
- fd_ctrl,
- fd_new,
- fd_free,
- NULL, /* fd_callback_ctrl */
-};
-
-const BIO_METHOD *BIO_s_fd(void)
-{
- return &methods_fdp;
-}
-
-BIO *BIO_new_fd(int fd, int close_flag)
-{
- BIO *ret;
- ret = BIO_new(BIO_s_fd());
- if (ret == NULL)
- return NULL;
- BIO_set_fd(ret, fd, close_flag);
- return ret;
-}
-
-static int fd_new(BIO *bi)
-{
- bi->init = 0;
- bi->num = -1;
- bi->ptr = NULL;
- bi->flags = BIO_FLAGS_UPLINK; /* essentially redundant */
- return 1;
-}
-
-static int fd_free(BIO *a)
-{
- if (a == NULL)
- return 0;
- if (a->shutdown) {
- if (a->init) {
- UP_close(a->num);
- }
- a->init = 0;
- a->flags = BIO_FLAGS_UPLINK;
- }
- return 1;
-}
-
-static int fd_read(BIO *b, char *out, int outl)
-{
- int ret = 0;
-
- if (out != NULL) {
- clear_sys_error();
- ret = UP_read(b->num, out, outl);
- BIO_clear_retry_flags(b);
- if (ret <= 0) {
- if (BIO_fd_should_retry(ret))
- BIO_set_retry_read(b);
+
+#if defined(OPENSSL_NO_POSIX_IO)
+/*
+ * Dummy placeholder for BIO_s_fd...
+ */
+BIO *BIO_new_fd(int fd, int close_flag)
+{
+ return NULL;
+}
+
+int BIO_fd_non_fatal_error(int err)
+{
+ return 0;
+}
+
+int BIO_fd_should_retry(int i)
+{
+ return 0;
+}
+
+const BIO_METHOD *BIO_s_fd(void)
+{
+ return NULL;
+}
+#else
+/*
+ * As for unconditional usage of "UPLINK" interface in this module.
+ * Trouble is that unlike Unix file descriptors [which are indexes
+ * in kernel-side per-process table], corresponding descriptors on
+ * platforms which require "UPLINK" interface seem to be indexes
+ * in a user-land, non-global table. Well, in fact they are indexes
+ * in stdio _iob[], and recall that _iob[] was the very reason why
+ * "UPLINK" interface was introduced in first place. But one way on
+ * another. Neither libcrypto or libssl use this BIO meaning that
+ * file descriptors can only be provided by application. Therefore
+ * "UPLINK" calls are due...
+ */
+static int fd_write(BIO *h, const char *buf, int num);
+static int fd_read(BIO *h, char *buf, int size);
+static int fd_puts(BIO *h, const char *str);
+static int fd_gets(BIO *h, char *buf, int size);
+static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int fd_new(BIO *h);
+static int fd_free(BIO *data);
+int BIO_fd_should_retry(int s);
+
+static const BIO_METHOD methods_fdp = {
+ BIO_TYPE_FD,
+ "file descriptor",
+ /* TODO: Convert to new style write function */
+ bwrite_conv,
+ fd_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
+ fd_read,
+ fd_puts,
+ fd_gets,
+ fd_ctrl,
+ fd_new,
+ fd_free,
+ NULL, /* fd_callback_ctrl */
+};
+
+const BIO_METHOD *BIO_s_fd(void)
+{
+ return &methods_fdp;
+}
+
+BIO *BIO_new_fd(int fd, int close_flag)
+{
+ BIO *ret;
+ ret = BIO_new(BIO_s_fd());
+ if (ret == NULL)
+ return NULL;
+ BIO_set_fd(ret, fd, close_flag);
+ return ret;
+}
+
+static int fd_new(BIO *bi)
+{
+ bi->init = 0;
+ bi->num = -1;
+ bi->ptr = NULL;
+ bi->flags = BIO_FLAGS_UPLINK; /* essentially redundant */
+ return 1;
+}
+
+static int fd_free(BIO *a)
+{
+ if (a == NULL)
+ return 0;
+ if (a->shutdown) {
+ if (a->init) {
+ UP_close(a->num);
+ }
+ a->init = 0;
+ a->flags = BIO_FLAGS_UPLINK;
+ }
+ return 1;
+}
+
+static int fd_read(BIO *b, char *out, int outl)
+{
+ int ret = 0;
+
+ if (out != NULL) {
+ clear_sys_error();
+ ret = UP_read(b->num, out, outl);
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_fd_should_retry(ret))
+ BIO_set_retry_read(b);
else if (ret == 0)
b->flags |= BIO_FLAGS_IN_EOF;
- }
- }
- return ret;
-}
-
-static int fd_write(BIO *b, const char *in, int inl)
-{
- int ret;
- clear_sys_error();
- ret = UP_write(b->num, in, inl);
- BIO_clear_retry_flags(b);
- if (ret <= 0) {
- if (BIO_fd_should_retry(ret))
- BIO_set_retry_write(b);
- }
- return ret;
-}
-
-static long fd_ctrl(BIO *b, int cmd, long num, void *ptr)
-{
- long ret = 1;
- int *ip;
-
- switch (cmd) {
- case BIO_CTRL_RESET:
- num = 0;
- /* fall thru */
- case BIO_C_FILE_SEEK:
- ret = (long)UP_lseek(b->num, num, 0);
- break;
- case BIO_C_FILE_TELL:
- case BIO_CTRL_INFO:
- ret = (long)UP_lseek(b->num, 0, 1);
- break;
- case BIO_C_SET_FD:
- fd_free(b);
- b->num = *((int *)ptr);
- b->shutdown = (int)num;
- b->init = 1;
- break;
- case BIO_C_GET_FD:
- if (b->init) {
- ip = (int *)ptr;
- if (ip != NULL)
- *ip = b->num;
- ret = b->num;
- } else
- ret = -1;
- break;
- case BIO_CTRL_GET_CLOSE:
- ret = b->shutdown;
- break;
- case BIO_CTRL_SET_CLOSE:
- b->shutdown = (int)num;
- break;
- case BIO_CTRL_PENDING:
- case BIO_CTRL_WPENDING:
- ret = 0;
- break;
- case BIO_CTRL_DUP:
- case BIO_CTRL_FLUSH:
- ret = 1;
- break;
+ }
+ }
+ return ret;
+}
+
+static int fd_write(BIO *b, const char *in, int inl)
+{
+ int ret;
+ clear_sys_error();
+ ret = UP_write(b->num, in, inl);
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_fd_should_retry(ret))
+ BIO_set_retry_write(b);
+ }
+ return ret;
+}
+
+static long fd_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ long ret = 1;
+ int *ip;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ num = 0;
+ /* fall thru */
+ case BIO_C_FILE_SEEK:
+ ret = (long)UP_lseek(b->num, num, 0);
+ break;
+ case BIO_C_FILE_TELL:
+ case BIO_CTRL_INFO:
+ ret = (long)UP_lseek(b->num, 0, 1);
+ break;
+ case BIO_C_SET_FD:
+ fd_free(b);
+ b->num = *((int *)ptr);
+ b->shutdown = (int)num;
+ b->init = 1;
+ break;
+ case BIO_C_GET_FD:
+ if (b->init) {
+ ip = (int *)ptr;
+ if (ip != NULL)
+ *ip = b->num;
+ ret = b->num;
+ } else
+ ret = -1;
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret = b->shutdown;
+ break;
+ case BIO_CTRL_SET_CLOSE:
+ b->shutdown = (int)num;
+ break;
+ case BIO_CTRL_PENDING:
+ case BIO_CTRL_WPENDING:
+ ret = 0;
+ break;
+ case BIO_CTRL_DUP:
+ case BIO_CTRL_FLUSH:
+ ret = 1;
+ break;
case BIO_CTRL_EOF:
ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0;
break;
- default:
- ret = 0;
- break;
- }
- return ret;
-}
-
-static int fd_puts(BIO *bp, const char *str)
-{
- int n, ret;
-
- n = strlen(str);
- ret = fd_write(bp, str, n);
- return ret;
-}
-
-static int fd_gets(BIO *bp, char *buf, int size)
-{
- int ret = 0;
- char *ptr = buf;
- char *end = buf + size - 1;
-
- while (ptr < end && fd_read(bp, ptr, 1) > 0) {
- if (*ptr++ == '\n')
- break;
- }
-
- ptr[0] = '\0';
-
- if (buf[0] != '\0')
- ret = strlen(buf);
- return ret;
-}
-
-int BIO_fd_should_retry(int i)
-{
- int err;
-
- if ((i == 0) || (i == -1)) {
- err = get_last_sys_error();
-
- return BIO_fd_non_fatal_error(err);
- }
- return 0;
-}
-
-int BIO_fd_non_fatal_error(int err)
-{
- switch (err) {
-
-# ifdef EWOULDBLOCK
-# ifdef WSAEWOULDBLOCK
-# if WSAEWOULDBLOCK != EWOULDBLOCK
- case EWOULDBLOCK:
-# endif
-# else
- case EWOULDBLOCK:
-# endif
-# endif
-
-# if defined(ENOTCONN)
- case ENOTCONN:
-# endif
-
-# ifdef EINTR
- case EINTR:
-# endif
-
-# ifdef EAGAIN
-# if EWOULDBLOCK != EAGAIN
- case EAGAIN:
-# endif
-# endif
-
-# ifdef EPROTO
- case EPROTO:
-# endif
-
-# ifdef EINPROGRESS
- case EINPROGRESS:
-# endif
-
-# ifdef EALREADY
- case EALREADY:
-# endif
- return 1;
- default:
- break;
- }
- return 0;
-}
-#endif
+ default:
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+static int fd_puts(BIO *bp, const char *str)
+{
+ int n, ret;
+
+ n = strlen(str);
+ ret = fd_write(bp, str, n);
+ return ret;
+}
+
+static int fd_gets(BIO *bp, char *buf, int size)
+{
+ int ret = 0;
+ char *ptr = buf;
+ char *end = buf + size - 1;
+
+ while (ptr < end && fd_read(bp, ptr, 1) > 0) {
+ if (*ptr++ == '\n')
+ break;
+ }
+
+ ptr[0] = '\0';
+
+ if (buf[0] != '\0')
+ ret = strlen(buf);
+ return ret;
+}
+
+int BIO_fd_should_retry(int i)
+{
+ int err;
+
+ if ((i == 0) || (i == -1)) {
+ err = get_last_sys_error();
+
+ return BIO_fd_non_fatal_error(err);
+ }
+ return 0;
+}
+
+int BIO_fd_non_fatal_error(int err)
+{
+ switch (err) {
+
+# ifdef EWOULDBLOCK
+# ifdef WSAEWOULDBLOCK
+# if WSAEWOULDBLOCK != EWOULDBLOCK
+ case EWOULDBLOCK:
+# endif
+# else
+ case EWOULDBLOCK:
+# endif
+# endif
+
+# if defined(ENOTCONN)
+ case ENOTCONN:
+# endif
+
+# ifdef EINTR
+ case EINTR:
+# endif
+
+# ifdef EAGAIN
+# if EWOULDBLOCK != EAGAIN
+ case EAGAIN:
+# endif
+# endif
+
+# ifdef EPROTO
+ case EPROTO:
+# endif
+
+# ifdef EINPROGRESS
+ case EINPROGRESS:
+# endif
+
+# ifdef EALREADY
+ case EALREADY:
+# endif
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+}
+#endif
diff --git a/contrib/libs/openssl/crypto/bio/bss_file.c b/contrib/libs/openssl/crypto/bio/bss_file.c
index 1af8222f9a..1a70ce7994 100644
--- a/contrib/libs/openssl/crypto/bio/bss_file.c
+++ b/contrib/libs/openssl/crypto/bio/bss_file.c
@@ -1,422 +1,422 @@
-/*
- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
+/*
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
#if defined(__linux) || defined(__sun) || defined(__hpux)
-/*
- * Following definition aliases fopen to fopen64 on above mentioned
- * platforms. This makes it possible to open and sequentially access files
- * larger than 2GB from 32-bit application. It does not allow to traverse
- * them beyond 2GB with fseek/ftell, but on the other hand *no* 32-bit
- * platform permits that, not with fseek/ftell. Not to mention that breaking
- * 2GB limit for seeking would require surgery to *our* API. But sequential
- * access suffices for practical cases when you can run into large files,
- * such as fingerprinting, so we can let API alone. For reference, the list
- * of 32-bit platforms which allow for sequential access of large files
- * without extra "magic" comprise *BSD, Darwin, IRIX...
- */
+/*
+ * Following definition aliases fopen to fopen64 on above mentioned
+ * platforms. This makes it possible to open and sequentially access files
+ * larger than 2GB from 32-bit application. It does not allow to traverse
+ * them beyond 2GB with fseek/ftell, but on the other hand *no* 32-bit
+ * platform permits that, not with fseek/ftell. Not to mention that breaking
+ * 2GB limit for seeking would require surgery to *our* API. But sequential
+ * access suffices for practical cases when you can run into large files,
+ * such as fingerprinting, so we can let API alone. For reference, the list
+ * of 32-bit platforms which allow for sequential access of large files
+ * without extra "magic" comprise *BSD, Darwin, IRIX...
+ */
# ifndef _FILE_OFFSET_BITS
# define _FILE_OFFSET_BITS 64
-# endif
+# endif
#endif
-
+
#include <stdio.h>
#include <errno.h>
#include "bio_local.h"
#include <openssl/err.h>
-
+
#if !defined(OPENSSL_NO_STDIO)
-
-static int file_write(BIO *h, const char *buf, int num);
-static int file_read(BIO *h, char *buf, int size);
-static int file_puts(BIO *h, const char *str);
-static int file_gets(BIO *h, char *str, int size);
-static long file_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-static int file_new(BIO *h);
-static int file_free(BIO *data);
-static const BIO_METHOD methods_filep = {
- BIO_TYPE_FILE,
- "FILE pointer",
- /* TODO: Convert to new style write function */
- bwrite_conv,
- file_write,
- /* TODO: Convert to new style read function */
- bread_conv,
- file_read,
- file_puts,
- file_gets,
- file_ctrl,
- file_new,
- file_free,
- NULL, /* file_callback_ctrl */
-};
-
-BIO *BIO_new_file(const char *filename, const char *mode)
-{
- BIO *ret;
- FILE *file = openssl_fopen(filename, mode);
- int fp_flags = BIO_CLOSE;
-
- if (strchr(mode, 'b') == NULL)
- fp_flags |= BIO_FP_TEXT;
-
- if (file == NULL) {
- SYSerr(SYS_F_FOPEN, get_last_sys_error());
- ERR_add_error_data(5, "fopen('", filename, "','", mode, "')");
- if (errno == ENOENT
+
+static int file_write(BIO *h, const char *buf, int num);
+static int file_read(BIO *h, char *buf, int size);
+static int file_puts(BIO *h, const char *str);
+static int file_gets(BIO *h, char *str, int size);
+static long file_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int file_new(BIO *h);
+static int file_free(BIO *data);
+static const BIO_METHOD methods_filep = {
+ BIO_TYPE_FILE,
+ "FILE pointer",
+ /* TODO: Convert to new style write function */
+ bwrite_conv,
+ file_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
+ file_read,
+ file_puts,
+ file_gets,
+ file_ctrl,
+ file_new,
+ file_free,
+ NULL, /* file_callback_ctrl */
+};
+
+BIO *BIO_new_file(const char *filename, const char *mode)
+{
+ BIO *ret;
+ FILE *file = openssl_fopen(filename, mode);
+ int fp_flags = BIO_CLOSE;
+
+ if (strchr(mode, 'b') == NULL)
+ fp_flags |= BIO_FP_TEXT;
+
+ if (file == NULL) {
+ SYSerr(SYS_F_FOPEN, get_last_sys_error());
+ ERR_add_error_data(5, "fopen('", filename, "','", mode, "')");
+ if (errno == ENOENT
#ifdef ENXIO
- || errno == ENXIO
+ || errno == ENXIO
#endif
- )
- BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE);
- else
- BIOerr(BIO_F_BIO_NEW_FILE, ERR_R_SYS_LIB);
- return NULL;
- }
- if ((ret = BIO_new(BIO_s_file())) == NULL) {
- fclose(file);
- return NULL;
- }
-
- BIO_clear_flags(ret, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage
- * UPLINK */
- BIO_set_fp(ret, file, fp_flags);
- return ret;
-}
-
-BIO *BIO_new_fp(FILE *stream, int close_flag)
-{
- BIO *ret;
-
- if ((ret = BIO_new(BIO_s_file())) == NULL)
- return NULL;
-
- /* redundant flag, left for documentation purposes */
- BIO_set_flags(ret, BIO_FLAGS_UPLINK);
- BIO_set_fp(ret, stream, close_flag);
- return ret;
-}
-
-const BIO_METHOD *BIO_s_file(void)
-{
- return &methods_filep;
-}
-
-static int file_new(BIO *bi)
-{
- bi->init = 0;
- bi->num = 0;
- bi->ptr = NULL;
- bi->flags = BIO_FLAGS_UPLINK; /* default to UPLINK */
- return 1;
-}
-
-static int file_free(BIO *a)
-{
- if (a == NULL)
- return 0;
- if (a->shutdown) {
- if ((a->init) && (a->ptr != NULL)) {
- if (a->flags & BIO_FLAGS_UPLINK)
- UP_fclose(a->ptr);
- else
- fclose(a->ptr);
- a->ptr = NULL;
- a->flags = BIO_FLAGS_UPLINK;
- }
- a->init = 0;
- }
- return 1;
-}
-
-static int file_read(BIO *b, char *out, int outl)
-{
- int ret = 0;
-
- if (b->init && (out != NULL)) {
- if (b->flags & BIO_FLAGS_UPLINK)
- ret = UP_fread(out, 1, (int)outl, b->ptr);
- else
- ret = fread(out, 1, (int)outl, (FILE *)b->ptr);
- if (ret == 0
- && (b->flags & BIO_FLAGS_UPLINK) ? UP_ferror((FILE *)b->ptr) :
- ferror((FILE *)b->ptr)) {
- SYSerr(SYS_F_FREAD, get_last_sys_error());
- BIOerr(BIO_F_FILE_READ, ERR_R_SYS_LIB);
- ret = -1;
- }
- }
- return ret;
-}
-
-static int file_write(BIO *b, const char *in, int inl)
-{
- int ret = 0;
-
- if (b->init && (in != NULL)) {
- if (b->flags & BIO_FLAGS_UPLINK)
- ret = UP_fwrite(in, (int)inl, 1, b->ptr);
- else
- ret = fwrite(in, (int)inl, 1, (FILE *)b->ptr);
- if (ret)
- ret = inl;
- /* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */
- /*
- * according to Tim Hudson <tjh@openssl.org>, the commented out
- * version above can cause 'inl' write calls under some stupid stdio
- * implementations (VMS)
- */
- }
- return ret;
-}
-
-static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
-{
- long ret = 1;
- FILE *fp = (FILE *)b->ptr;
- FILE **fpp;
- char p[4];
- int st;
-
- switch (cmd) {
- case BIO_C_FILE_SEEK:
- case BIO_CTRL_RESET:
- if (b->flags & BIO_FLAGS_UPLINK)
- ret = (long)UP_fseek(b->ptr, num, 0);
- else
- ret = (long)fseek(fp, num, 0);
- break;
- case BIO_CTRL_EOF:
- if (b->flags & BIO_FLAGS_UPLINK)
- ret = (long)UP_feof(fp);
- else
- ret = (long)feof(fp);
- break;
- case BIO_C_FILE_TELL:
- case BIO_CTRL_INFO:
- if (b->flags & BIO_FLAGS_UPLINK)
- ret = UP_ftell(b->ptr);
- else
- ret = ftell(fp);
- break;
- case BIO_C_SET_FILE_PTR:
- file_free(b);
- b->shutdown = (int)num & BIO_CLOSE;
- b->ptr = ptr;
- b->init = 1;
+ )
+ BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE);
+ else
+ BIOerr(BIO_F_BIO_NEW_FILE, ERR_R_SYS_LIB);
+ return NULL;
+ }
+ if ((ret = BIO_new(BIO_s_file())) == NULL) {
+ fclose(file);
+ return NULL;
+ }
+
+ BIO_clear_flags(ret, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage
+ * UPLINK */
+ BIO_set_fp(ret, file, fp_flags);
+ return ret;
+}
+
+BIO *BIO_new_fp(FILE *stream, int close_flag)
+{
+ BIO *ret;
+
+ if ((ret = BIO_new(BIO_s_file())) == NULL)
+ return NULL;
+
+ /* redundant flag, left for documentation purposes */
+ BIO_set_flags(ret, BIO_FLAGS_UPLINK);
+ BIO_set_fp(ret, stream, close_flag);
+ return ret;
+}
+
+const BIO_METHOD *BIO_s_file(void)
+{
+ return &methods_filep;
+}
+
+static int file_new(BIO *bi)
+{
+ bi->init = 0;
+ bi->num = 0;
+ bi->ptr = NULL;
+ bi->flags = BIO_FLAGS_UPLINK; /* default to UPLINK */
+ return 1;
+}
+
+static int file_free(BIO *a)
+{
+ if (a == NULL)
+ return 0;
+ if (a->shutdown) {
+ if ((a->init) && (a->ptr != NULL)) {
+ if (a->flags & BIO_FLAGS_UPLINK)
+ UP_fclose(a->ptr);
+ else
+ fclose(a->ptr);
+ a->ptr = NULL;
+ a->flags = BIO_FLAGS_UPLINK;
+ }
+ a->init = 0;
+ }
+ return 1;
+}
+
+static int file_read(BIO *b, char *out, int outl)
+{
+ int ret = 0;
+
+ if (b->init && (out != NULL)) {
+ if (b->flags & BIO_FLAGS_UPLINK)
+ ret = UP_fread(out, 1, (int)outl, b->ptr);
+ else
+ ret = fread(out, 1, (int)outl, (FILE *)b->ptr);
+ if (ret == 0
+ && (b->flags & BIO_FLAGS_UPLINK) ? UP_ferror((FILE *)b->ptr) :
+ ferror((FILE *)b->ptr)) {
+ SYSerr(SYS_F_FREAD, get_last_sys_error());
+ BIOerr(BIO_F_FILE_READ, ERR_R_SYS_LIB);
+ ret = -1;
+ }
+ }
+ return ret;
+}
+
+static int file_write(BIO *b, const char *in, int inl)
+{
+ int ret = 0;
+
+ if (b->init && (in != NULL)) {
+ if (b->flags & BIO_FLAGS_UPLINK)
+ ret = UP_fwrite(in, (int)inl, 1, b->ptr);
+ else
+ ret = fwrite(in, (int)inl, 1, (FILE *)b->ptr);
+ if (ret)
+ ret = inl;
+ /* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */
+ /*
+ * according to Tim Hudson <tjh@openssl.org>, the commented out
+ * version above can cause 'inl' write calls under some stupid stdio
+ * implementations (VMS)
+ */
+ }
+ return ret;
+}
+
+static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ long ret = 1;
+ FILE *fp = (FILE *)b->ptr;
+ FILE **fpp;
+ char p[4];
+ int st;
+
+ switch (cmd) {
+ case BIO_C_FILE_SEEK:
+ case BIO_CTRL_RESET:
+ if (b->flags & BIO_FLAGS_UPLINK)
+ ret = (long)UP_fseek(b->ptr, num, 0);
+ else
+ ret = (long)fseek(fp, num, 0);
+ break;
+ case BIO_CTRL_EOF:
+ if (b->flags & BIO_FLAGS_UPLINK)
+ ret = (long)UP_feof(fp);
+ else
+ ret = (long)feof(fp);
+ break;
+ case BIO_C_FILE_TELL:
+ case BIO_CTRL_INFO:
+ if (b->flags & BIO_FLAGS_UPLINK)
+ ret = UP_ftell(b->ptr);
+ else
+ ret = ftell(fp);
+ break;
+ case BIO_C_SET_FILE_PTR:
+ file_free(b);
+ b->shutdown = (int)num & BIO_CLOSE;
+ b->ptr = ptr;
+ b->init = 1;
# if BIO_FLAGS_UPLINK!=0
# if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES)
# define _IOB_ENTRIES 20
# endif
- /* Safety net to catch purely internal BIO_set_fp calls */
+ /* Safety net to catch purely internal BIO_set_fp calls */
# if defined(_MSC_VER) && _MSC_VER>=1900
- if (ptr == stdin || ptr == stdout || ptr == stderr)
- BIO_clear_flags(b, BIO_FLAGS_UPLINK);
+ if (ptr == stdin || ptr == stdout || ptr == stderr)
+ BIO_clear_flags(b, BIO_FLAGS_UPLINK);
# elif defined(_IOB_ENTRIES)
- if ((size_t)ptr >= (size_t)stdin &&
- (size_t)ptr < (size_t)(stdin + _IOB_ENTRIES))
- BIO_clear_flags(b, BIO_FLAGS_UPLINK);
-# endif
+ if ((size_t)ptr >= (size_t)stdin &&
+ (size_t)ptr < (size_t)(stdin + _IOB_ENTRIES))
+ BIO_clear_flags(b, BIO_FLAGS_UPLINK);
+# endif
# endif
# ifdef UP_fsetmod
- if (b->flags & BIO_FLAGS_UPLINK)
- UP_fsetmod(b->ptr, (char)((num & BIO_FP_TEXT) ? 't' : 'b'));
- else
+ if (b->flags & BIO_FLAGS_UPLINK)
+ UP_fsetmod(b->ptr, (char)((num & BIO_FP_TEXT) ? 't' : 'b'));
+ else
# endif
- {
+ {
# if defined(OPENSSL_SYS_WINDOWS)
- int fd = _fileno((FILE *)ptr);
- if (num & BIO_FP_TEXT)
- _setmode(fd, _O_TEXT);
- else
- _setmode(fd, _O_BINARY);
+ int fd = _fileno((FILE *)ptr);
+ if (num & BIO_FP_TEXT)
+ _setmode(fd, _O_TEXT);
+ else
+ _setmode(fd, _O_BINARY);
# elif defined(OPENSSL_SYS_MSDOS)
- int fd = fileno((FILE *)ptr);
- /* Set correct text/binary mode */
- if (num & BIO_FP_TEXT)
- _setmode(fd, _O_TEXT);
- /* Dangerous to set stdin/stdout to raw (unless redirected) */
- else {
- if (fd == STDIN_FILENO || fd == STDOUT_FILENO) {
- if (isatty(fd) <= 0)
- _setmode(fd, _O_BINARY);
- } else
- _setmode(fd, _O_BINARY);
- }
+ int fd = fileno((FILE *)ptr);
+ /* Set correct text/binary mode */
+ if (num & BIO_FP_TEXT)
+ _setmode(fd, _O_TEXT);
+ /* Dangerous to set stdin/stdout to raw (unless redirected) */
+ else {
+ if (fd == STDIN_FILENO || fd == STDOUT_FILENO) {
+ if (isatty(fd) <= 0)
+ _setmode(fd, _O_BINARY);
+ } else
+ _setmode(fd, _O_BINARY);
+ }
# elif defined(OPENSSL_SYS_WIN32_CYGWIN)
- int fd = fileno((FILE *)ptr);
- if (!(num & BIO_FP_TEXT))
- setmode(fd, O_BINARY);
+ int fd = fileno((FILE *)ptr);
+ if (!(num & BIO_FP_TEXT))
+ setmode(fd, O_BINARY);
# endif
- }
- break;
- case BIO_C_SET_FILENAME:
- file_free(b);
- b->shutdown = (int)num & BIO_CLOSE;
- if (num & BIO_FP_APPEND) {
- if (num & BIO_FP_READ)
- OPENSSL_strlcpy(p, "a+", sizeof(p));
- else
- OPENSSL_strlcpy(p, "a", sizeof(p));
- } else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE))
- OPENSSL_strlcpy(p, "r+", sizeof(p));
- else if (num & BIO_FP_WRITE)
- OPENSSL_strlcpy(p, "w", sizeof(p));
- else if (num & BIO_FP_READ)
- OPENSSL_strlcpy(p, "r", sizeof(p));
- else {
- BIOerr(BIO_F_FILE_CTRL, BIO_R_BAD_FOPEN_MODE);
- ret = 0;
- break;
- }
+ }
+ break;
+ case BIO_C_SET_FILENAME:
+ file_free(b);
+ b->shutdown = (int)num & BIO_CLOSE;
+ if (num & BIO_FP_APPEND) {
+ if (num & BIO_FP_READ)
+ OPENSSL_strlcpy(p, "a+", sizeof(p));
+ else
+ OPENSSL_strlcpy(p, "a", sizeof(p));
+ } else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE))
+ OPENSSL_strlcpy(p, "r+", sizeof(p));
+ else if (num & BIO_FP_WRITE)
+ OPENSSL_strlcpy(p, "w", sizeof(p));
+ else if (num & BIO_FP_READ)
+ OPENSSL_strlcpy(p, "r", sizeof(p));
+ else {
+ BIOerr(BIO_F_FILE_CTRL, BIO_R_BAD_FOPEN_MODE);
+ ret = 0;
+ break;
+ }
# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS)
- if (!(num & BIO_FP_TEXT))
- OPENSSL_strlcat(p, "b", sizeof(p));
- else
- OPENSSL_strlcat(p, "t", sizeof(p));
+ if (!(num & BIO_FP_TEXT))
+ OPENSSL_strlcat(p, "b", sizeof(p));
+ else
+ OPENSSL_strlcat(p, "t", sizeof(p));
# elif defined(OPENSSL_SYS_WIN32_CYGWIN)
- if (!(num & BIO_FP_TEXT))
- OPENSSL_strlcat(p, "b", sizeof(p));
+ if (!(num & BIO_FP_TEXT))
+ OPENSSL_strlcat(p, "b", sizeof(p));
# endif
- fp = openssl_fopen(ptr, p);
- if (fp == NULL) {
- SYSerr(SYS_F_FOPEN, get_last_sys_error());
- ERR_add_error_data(5, "fopen('", ptr, "','", p, "')");
- BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB);
- ret = 0;
- break;
- }
- b->ptr = fp;
- b->init = 1;
- BIO_clear_flags(b, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage
- * UPLINK */
- break;
- case BIO_C_GET_FILE_PTR:
- /* the ptr parameter is actually a FILE ** in this case. */
- if (ptr != NULL) {
- fpp = (FILE **)ptr;
- *fpp = (FILE *)b->ptr;
- }
- break;
- case BIO_CTRL_GET_CLOSE:
- ret = (long)b->shutdown;
- break;
- case BIO_CTRL_SET_CLOSE:
- b->shutdown = (int)num;
- break;
- case BIO_CTRL_FLUSH:
- st = b->flags & BIO_FLAGS_UPLINK
- ? UP_fflush(b->ptr) : fflush((FILE *)b->ptr);
- if (st == EOF) {
- SYSerr(SYS_F_FFLUSH, get_last_sys_error());
- ERR_add_error_data(1, "fflush()");
- BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB);
- ret = 0;
- }
- break;
- case BIO_CTRL_DUP:
- ret = 1;
- break;
-
- case BIO_CTRL_WPENDING:
- case BIO_CTRL_PENDING:
- case BIO_CTRL_PUSH:
- case BIO_CTRL_POP:
- default:
- ret = 0;
- break;
- }
- return ret;
-}
-
-static int file_gets(BIO *bp, char *buf, int size)
-{
- int ret = 0;
-
- buf[0] = '\0';
- if (bp->flags & BIO_FLAGS_UPLINK) {
- if (!UP_fgets(buf, size, bp->ptr))
- goto err;
- } else {
- if (!fgets(buf, size, (FILE *)bp->ptr))
- goto err;
- }
- if (buf[0] != '\0')
- ret = strlen(buf);
- err:
- return ret;
-}
-
-static int file_puts(BIO *bp, const char *str)
-{
- int n, ret;
-
- n = strlen(str);
- ret = file_write(bp, str, n);
- return ret;
-}
-
-#else
-
-static int file_write(BIO *b, const char *in, int inl)
-{
- return -1;
-}
-static int file_read(BIO *b, char *out, int outl)
-{
- return -1;
-}
-static int file_puts(BIO *bp, const char *str)
-{
- return -1;
-}
-static int file_gets(BIO *bp, char *buf, int size)
-{
- return 0;
-}
-static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
-{
- return 0;
-}
-static int file_new(BIO *bi)
-{
- return 0;
-}
-static int file_free(BIO *a)
-{
- return 0;
-}
-
-static const BIO_METHOD methods_filep = {
- BIO_TYPE_FILE,
- "FILE pointer",
- /* TODO: Convert to new style write function */
- bwrite_conv,
- file_write,
- /* TODO: Convert to new style read function */
- bread_conv,
- file_read,
- file_puts,
- file_gets,
- file_ctrl,
- file_new,
- file_free,
- NULL, /* file_callback_ctrl */
-};
-
-const BIO_METHOD *BIO_s_file(void)
-{
- return &methods_filep;
-}
-
-BIO *BIO_new_file(const char *filename, const char *mode)
-{
- return NULL;
-}
-
+ fp = openssl_fopen(ptr, p);
+ if (fp == NULL) {
+ SYSerr(SYS_F_FOPEN, get_last_sys_error());
+ ERR_add_error_data(5, "fopen('", ptr, "','", p, "')");
+ BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB);
+ ret = 0;
+ break;
+ }
+ b->ptr = fp;
+ b->init = 1;
+ BIO_clear_flags(b, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage
+ * UPLINK */
+ break;
+ case BIO_C_GET_FILE_PTR:
+ /* the ptr parameter is actually a FILE ** in this case. */
+ if (ptr != NULL) {
+ fpp = (FILE **)ptr;
+ *fpp = (FILE *)b->ptr;
+ }
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret = (long)b->shutdown;
+ break;
+ case BIO_CTRL_SET_CLOSE:
+ b->shutdown = (int)num;
+ break;
+ case BIO_CTRL_FLUSH:
+ st = b->flags & BIO_FLAGS_UPLINK
+ ? UP_fflush(b->ptr) : fflush((FILE *)b->ptr);
+ if (st == EOF) {
+ SYSerr(SYS_F_FFLUSH, get_last_sys_error());
+ ERR_add_error_data(1, "fflush()");
+ BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB);
+ ret = 0;
+ }
+ break;
+ case BIO_CTRL_DUP:
+ ret = 1;
+ break;
+
+ case BIO_CTRL_WPENDING:
+ case BIO_CTRL_PENDING:
+ case BIO_CTRL_PUSH:
+ case BIO_CTRL_POP:
+ default:
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+static int file_gets(BIO *bp, char *buf, int size)
+{
+ int ret = 0;
+
+ buf[0] = '\0';
+ if (bp->flags & BIO_FLAGS_UPLINK) {
+ if (!UP_fgets(buf, size, bp->ptr))
+ goto err;
+ } else {
+ if (!fgets(buf, size, (FILE *)bp->ptr))
+ goto err;
+ }
+ if (buf[0] != '\0')
+ ret = strlen(buf);
+ err:
+ return ret;
+}
+
+static int file_puts(BIO *bp, const char *str)
+{
+ int n, ret;
+
+ n = strlen(str);
+ ret = file_write(bp, str, n);
+ return ret;
+}
+
+#else
+
+static int file_write(BIO *b, const char *in, int inl)
+{
+ return -1;
+}
+static int file_read(BIO *b, char *out, int outl)
+{
+ return -1;
+}
+static int file_puts(BIO *bp, const char *str)
+{
+ return -1;
+}
+static int file_gets(BIO *bp, char *buf, int size)
+{
+ return 0;
+}
+static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ return 0;
+}
+static int file_new(BIO *bi)
+{
+ return 0;
+}
+static int file_free(BIO *a)
+{
+ return 0;
+}
+
+static const BIO_METHOD methods_filep = {
+ BIO_TYPE_FILE,
+ "FILE pointer",
+ /* TODO: Convert to new style write function */
+ bwrite_conv,
+ file_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
+ file_read,
+ file_puts,
+ file_gets,
+ file_ctrl,
+ file_new,
+ file_free,
+ NULL, /* file_callback_ctrl */
+};
+
+const BIO_METHOD *BIO_s_file(void)
+{
+ return &methods_filep;
+}
+
+BIO *BIO_new_file(const char *filename, const char *mode)
+{
+ return NULL;
+}
+
#endif /* OPENSSL_NO_STDIO */
diff --git a/contrib/libs/openssl/crypto/bio/bss_log.c b/contrib/libs/openssl/crypto/bio/bss_log.c
index 879745a00c..b9579faaa2 100644
--- a/contrib/libs/openssl/crypto/bio/bss_log.c
+++ b/contrib/libs/openssl/crypto/bio/bss_log.c
@@ -1,416 +1,416 @@
-/*
- * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-/*
- * Why BIO_s_log?
- *
- * BIO_s_log is useful for system daemons (or services under NT). It is
- * one-way BIO, it sends all stuff to syslogd (on system that commonly use
- * that), or event log (on NT), or OPCOM (on OpenVMS).
- *
- */
-
-#include <stdio.h>
-#include <errno.h>
-
+/*
+ * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * Why BIO_s_log?
+ *
+ * BIO_s_log is useful for system daemons (or services under NT). It is
+ * one-way BIO, it sends all stuff to syslogd (on system that commonly use
+ * that), or event log (on NT), or OPCOM (on OpenVMS).
+ *
+ */
+
+#include <stdio.h>
+#include <errno.h>
+
#include "bio_local.h"
-#include "internal/cryptlib.h"
-
-#if defined(OPENSSL_SYS_WINCE)
-#elif defined(OPENSSL_SYS_WIN32)
-#elif defined(OPENSSL_SYS_VMS)
-# include <opcdef.h>
-# include <descrip.h>
-# include <lib$routines.h>
-# include <starlet.h>
-/* Some compiler options may mask the declaration of "_malloc32". */
-# if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE
-# if __INITIAL_POINTER_SIZE == 64
-# pragma pointer_size save
-# pragma pointer_size 32
-void *_malloc32(__size_t);
-# pragma pointer_size restore
-# endif /* __INITIAL_POINTER_SIZE == 64 */
-# endif /* __INITIAL_POINTER_SIZE && defined
- * _ANSI_C_SOURCE */
-#elif defined(__DJGPP__) && defined(OPENSSL_NO_SOCK)
-# define NO_SYSLOG
-#elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG)
-# include <syslog.h>
-#endif
-
-#include <openssl/buffer.h>
-#include <openssl/err.h>
-
-#ifndef NO_SYSLOG
-
-# if defined(OPENSSL_SYS_WIN32)
-# define LOG_EMERG 0
-# define LOG_ALERT 1
-# define LOG_CRIT 2
-# define LOG_ERR 3
-# define LOG_WARNING 4
-# define LOG_NOTICE 5
-# define LOG_INFO 6
-# define LOG_DEBUG 7
-
-# define LOG_DAEMON (3<<3)
-# elif defined(OPENSSL_SYS_VMS)
-/* On VMS, we don't really care about these, but we need them to compile */
-# define LOG_EMERG 0
-# define LOG_ALERT 1
-# define LOG_CRIT 2
-# define LOG_ERR 3
-# define LOG_WARNING 4
-# define LOG_NOTICE 5
-# define LOG_INFO 6
-# define LOG_DEBUG 7
-
-# define LOG_DAEMON OPC$M_NM_NTWORK
-# endif
-
-static int slg_write(BIO *h, const char *buf, int num);
-static int slg_puts(BIO *h, const char *str);
-static long slg_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-static int slg_new(BIO *h);
-static int slg_free(BIO *data);
-static void xopenlog(BIO *bp, char *name, int level);
-static void xsyslog(BIO *bp, int priority, const char *string);
-static void xcloselog(BIO *bp);
-
-static const BIO_METHOD methods_slg = {
- BIO_TYPE_MEM,
- "syslog",
- /* TODO: Convert to new style write function */
- bwrite_conv,
- slg_write,
- NULL, /* slg_write_old, */
- NULL, /* slg_read, */
- slg_puts,
- NULL,
- slg_ctrl,
- slg_new,
- slg_free,
- NULL, /* slg_callback_ctrl */
-};
-
-const BIO_METHOD *BIO_s_log(void)
-{
- return &methods_slg;
-}
-
-static int slg_new(BIO *bi)
-{
- bi->init = 1;
- bi->num = 0;
- bi->ptr = NULL;
- xopenlog(bi, "application", LOG_DAEMON);
- return 1;
-}
-
-static int slg_free(BIO *a)
-{
- if (a == NULL)
- return 0;
- xcloselog(a);
- return 1;
-}
-
-static int slg_write(BIO *b, const char *in, int inl)
-{
- int ret = inl;
- char *buf;
- char *pp;
- int priority, i;
- static const struct {
- int strl;
- char str[10];
- int log_level;
- } mapping[] = {
- {
- 6, "PANIC ", LOG_EMERG
- },
- {
- 6, "EMERG ", LOG_EMERG
- },
- {
- 4, "EMR ", LOG_EMERG
- },
- {
- 6, "ALERT ", LOG_ALERT
- },
- {
- 4, "ALR ", LOG_ALERT
- },
- {
- 5, "CRIT ", LOG_CRIT
- },
- {
- 4, "CRI ", LOG_CRIT
- },
- {
- 6, "ERROR ", LOG_ERR
- },
- {
- 4, "ERR ", LOG_ERR
- },
- {
- 8, "WARNING ", LOG_WARNING
- },
- {
- 5, "WARN ", LOG_WARNING
- },
- {
- 4, "WAR ", LOG_WARNING
- },
- {
- 7, "NOTICE ", LOG_NOTICE
- },
- {
- 5, "NOTE ", LOG_NOTICE
- },
- {
- 4, "NOT ", LOG_NOTICE
- },
- {
- 5, "INFO ", LOG_INFO
- },
- {
- 4, "INF ", LOG_INFO
- },
- {
- 6, "DEBUG ", LOG_DEBUG
- },
- {
- 4, "DBG ", LOG_DEBUG
- },
- {
- 0, "", LOG_ERR
- }
- /* The default */
- };
-
- if ((buf = OPENSSL_malloc(inl + 1)) == NULL) {
- BIOerr(BIO_F_SLG_WRITE, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- memcpy(buf, in, inl);
- buf[inl] = '\0';
-
- i = 0;
- while (strncmp(buf, mapping[i].str, mapping[i].strl) != 0)
- i++;
- priority = mapping[i].log_level;
- pp = buf + mapping[i].strl;
-
- xsyslog(b, priority, pp);
-
- OPENSSL_free(buf);
- return ret;
-}
-
-static long slg_ctrl(BIO *b, int cmd, long num, void *ptr)
-{
- switch (cmd) {
- case BIO_CTRL_SET:
- xcloselog(b);
- xopenlog(b, ptr, num);
- break;
- default:
- break;
- }
- return 0;
-}
-
-static int slg_puts(BIO *bp, const char *str)
-{
- int n, ret;
-
- n = strlen(str);
- ret = slg_write(bp, str, n);
- return ret;
-}
-
-# if defined(OPENSSL_SYS_WIN32)
-
-static void xopenlog(BIO *bp, char *name, int level)
-{
- if (check_winnt())
- bp->ptr = RegisterEventSourceA(NULL, name);
- else
- bp->ptr = NULL;
-}
-
-static void xsyslog(BIO *bp, int priority, const char *string)
-{
- LPCSTR lpszStrings[2];
- WORD evtype = EVENTLOG_ERROR_TYPE;
- char pidbuf[DECIMAL_SIZE(DWORD) + 4];
-
- if (bp->ptr == NULL)
- return;
-
- switch (priority) {
- case LOG_EMERG:
- case LOG_ALERT:
- case LOG_CRIT:
- case LOG_ERR:
- evtype = EVENTLOG_ERROR_TYPE;
- break;
- case LOG_WARNING:
- evtype = EVENTLOG_WARNING_TYPE;
- break;
- case LOG_NOTICE:
- case LOG_INFO:
- case LOG_DEBUG:
- evtype = EVENTLOG_INFORMATION_TYPE;
- break;
- default:
- /*
- * Should never happen, but set it
- * as error anyway.
- */
- evtype = EVENTLOG_ERROR_TYPE;
- break;
- }
-
- sprintf(pidbuf, "[%lu] ", GetCurrentProcessId());
- lpszStrings[0] = pidbuf;
- lpszStrings[1] = string;
-
- ReportEventA(bp->ptr, evtype, 0, 1024, NULL, 2, 0, lpszStrings, NULL);
-}
-
-static void xcloselog(BIO *bp)
-{
- if (bp->ptr)
- DeregisterEventSource((HANDLE) (bp->ptr));
- bp->ptr = NULL;
-}
-
-# elif defined(OPENSSL_SYS_VMS)
-
-static int VMS_OPC_target = LOG_DAEMON;
-
-static void xopenlog(BIO *bp, char *name, int level)
-{
- VMS_OPC_target = level;
-}
-
-static void xsyslog(BIO *bp, int priority, const char *string)
-{
- struct dsc$descriptor_s opc_dsc;
-
-/* Arrange 32-bit pointer to opcdef buffer and malloc(), if needed. */
-# if __INITIAL_POINTER_SIZE == 64
-# pragma pointer_size save
-# pragma pointer_size 32
-# define OPCDEF_TYPE __char_ptr32
-# define OPCDEF_MALLOC _malloc32
-# else /* __INITIAL_POINTER_SIZE == 64 */
-# define OPCDEF_TYPE char *
-# define OPCDEF_MALLOC OPENSSL_malloc
-# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
-
- struct opcdef *opcdef_p;
-
-# if __INITIAL_POINTER_SIZE == 64
-# pragma pointer_size restore
-# endif /* __INITIAL_POINTER_SIZE == 64 */
-
- char buf[10240];
- unsigned int len;
- struct dsc$descriptor_s buf_dsc;
- $DESCRIPTOR(fao_cmd, "!AZ: !AZ");
- char *priority_tag;
-
- switch (priority) {
- case LOG_EMERG:
- priority_tag = "Emergency";
- break;
- case LOG_ALERT:
- priority_tag = "Alert";
- break;
- case LOG_CRIT:
- priority_tag = "Critical";
- break;
- case LOG_ERR:
- priority_tag = "Error";
- break;
- case LOG_WARNING:
- priority_tag = "Warning";
- break;
- case LOG_NOTICE:
- priority_tag = "Notice";
- break;
- case LOG_INFO:
- priority_tag = "Info";
- break;
- case LOG_DEBUG:
- priority_tag = "DEBUG";
- break;
- }
-
- buf_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
- buf_dsc.dsc$b_class = DSC$K_CLASS_S;
- buf_dsc.dsc$a_pointer = buf;
- buf_dsc.dsc$w_length = sizeof(buf) - 1;
-
- lib$sys_fao(&fao_cmd, &len, &buf_dsc, priority_tag, string);
-
- /* We know there's an 8-byte header. That's documented. */
- opcdef_p = OPCDEF_MALLOC(8 + len);
- opcdef_p->opc$b_ms_type = OPC$_RQ_RQST;
- memcpy(opcdef_p->opc$z_ms_target_classes, &VMS_OPC_target, 3);
- opcdef_p->opc$l_ms_rqstid = 0;
- memcpy(&opcdef_p->opc$l_ms_text, buf, len);
-
- opc_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
- opc_dsc.dsc$b_class = DSC$K_CLASS_S;
- opc_dsc.dsc$a_pointer = (OPCDEF_TYPE) opcdef_p;
- opc_dsc.dsc$w_length = len + 8;
-
- sys$sndopr(opc_dsc, 0);
-
- OPENSSL_free(opcdef_p);
-}
-
-static void xcloselog(BIO *bp)
-{
-}
-
-# else /* Unix/Watt32 */
-
-static void xopenlog(BIO *bp, char *name, int level)
-{
-# ifdef WATT32 /* djgpp/DOS */
- openlog(name, LOG_PID | LOG_CONS | LOG_NDELAY, level);
-# else
- openlog(name, LOG_PID | LOG_CONS, level);
-# endif
-}
-
-static void xsyslog(BIO *bp, int priority, const char *string)
-{
- syslog(priority, "%s", string);
-}
-
-static void xcloselog(BIO *bp)
-{
- closelog();
-}
-
-# endif /* Unix */
-
-#else /* NO_SYSLOG */
-const BIO_METHOD *BIO_s_log(void)
-{
- return NULL;
-}
-#endif /* NO_SYSLOG */
+#include "internal/cryptlib.h"
+
+#if defined(OPENSSL_SYS_WINCE)
+#elif defined(OPENSSL_SYS_WIN32)
+#elif defined(OPENSSL_SYS_VMS)
+# include <opcdef.h>
+# include <descrip.h>
+# include <lib$routines.h>
+# include <starlet.h>
+/* Some compiler options may mask the declaration of "_malloc32". */
+# if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE
+# if __INITIAL_POINTER_SIZE == 64
+# pragma pointer_size save
+# pragma pointer_size 32
+void *_malloc32(__size_t);
+# pragma pointer_size restore
+# endif /* __INITIAL_POINTER_SIZE == 64 */
+# endif /* __INITIAL_POINTER_SIZE && defined
+ * _ANSI_C_SOURCE */
+#elif defined(__DJGPP__) && defined(OPENSSL_NO_SOCK)
+# define NO_SYSLOG
+#elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG)
+# include <syslog.h>
+#endif
+
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+
+#ifndef NO_SYSLOG
+
+# if defined(OPENSSL_SYS_WIN32)
+# define LOG_EMERG 0
+# define LOG_ALERT 1
+# define LOG_CRIT 2
+# define LOG_ERR 3
+# define LOG_WARNING 4
+# define LOG_NOTICE 5
+# define LOG_INFO 6
+# define LOG_DEBUG 7
+
+# define LOG_DAEMON (3<<3)
+# elif defined(OPENSSL_SYS_VMS)
+/* On VMS, we don't really care about these, but we need them to compile */
+# define LOG_EMERG 0
+# define LOG_ALERT 1
+# define LOG_CRIT 2
+# define LOG_ERR 3
+# define LOG_WARNING 4
+# define LOG_NOTICE 5
+# define LOG_INFO 6
+# define LOG_DEBUG 7
+
+# define LOG_DAEMON OPC$M_NM_NTWORK
+# endif
+
+static int slg_write(BIO *h, const char *buf, int num);
+static int slg_puts(BIO *h, const char *str);
+static long slg_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int slg_new(BIO *h);
+static int slg_free(BIO *data);
+static void xopenlog(BIO *bp, char *name, int level);
+static void xsyslog(BIO *bp, int priority, const char *string);
+static void xcloselog(BIO *bp);
+
+static const BIO_METHOD methods_slg = {
+ BIO_TYPE_MEM,
+ "syslog",
+ /* TODO: Convert to new style write function */
+ bwrite_conv,
+ slg_write,
+ NULL, /* slg_write_old, */
+ NULL, /* slg_read, */
+ slg_puts,
+ NULL,
+ slg_ctrl,
+ slg_new,
+ slg_free,
+ NULL, /* slg_callback_ctrl */
+};
+
+const BIO_METHOD *BIO_s_log(void)
+{
+ return &methods_slg;
+}
+
+static int slg_new(BIO *bi)
+{
+ bi->init = 1;
+ bi->num = 0;
+ bi->ptr = NULL;
+ xopenlog(bi, "application", LOG_DAEMON);
+ return 1;
+}
+
+static int slg_free(BIO *a)
+{
+ if (a == NULL)
+ return 0;
+ xcloselog(a);
+ return 1;
+}
+
+static int slg_write(BIO *b, const char *in, int inl)
+{
+ int ret = inl;
+ char *buf;
+ char *pp;
+ int priority, i;
+ static const struct {
+ int strl;
+ char str[10];
+ int log_level;
+ } mapping[] = {
+ {
+ 6, "PANIC ", LOG_EMERG
+ },
+ {
+ 6, "EMERG ", LOG_EMERG
+ },
+ {
+ 4, "EMR ", LOG_EMERG
+ },
+ {
+ 6, "ALERT ", LOG_ALERT
+ },
+ {
+ 4, "ALR ", LOG_ALERT
+ },
+ {
+ 5, "CRIT ", LOG_CRIT
+ },
+ {
+ 4, "CRI ", LOG_CRIT
+ },
+ {
+ 6, "ERROR ", LOG_ERR
+ },
+ {
+ 4, "ERR ", LOG_ERR
+ },
+ {
+ 8, "WARNING ", LOG_WARNING
+ },
+ {
+ 5, "WARN ", LOG_WARNING
+ },
+ {
+ 4, "WAR ", LOG_WARNING
+ },
+ {
+ 7, "NOTICE ", LOG_NOTICE
+ },
+ {
+ 5, "NOTE ", LOG_NOTICE
+ },
+ {
+ 4, "NOT ", LOG_NOTICE
+ },
+ {
+ 5, "INFO ", LOG_INFO
+ },
+ {
+ 4, "INF ", LOG_INFO
+ },
+ {
+ 6, "DEBUG ", LOG_DEBUG
+ },
+ {
+ 4, "DBG ", LOG_DEBUG
+ },
+ {
+ 0, "", LOG_ERR
+ }
+ /* The default */
+ };
+
+ if ((buf = OPENSSL_malloc(inl + 1)) == NULL) {
+ BIOerr(BIO_F_SLG_WRITE, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ memcpy(buf, in, inl);
+ buf[inl] = '\0';
+
+ i = 0;
+ while (strncmp(buf, mapping[i].str, mapping[i].strl) != 0)
+ i++;
+ priority = mapping[i].log_level;
+ pp = buf + mapping[i].strl;
+
+ xsyslog(b, priority, pp);
+
+ OPENSSL_free(buf);
+ return ret;
+}
+
+static long slg_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ switch (cmd) {
+ case BIO_CTRL_SET:
+ xcloselog(b);
+ xopenlog(b, ptr, num);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static int slg_puts(BIO *bp, const char *str)
+{
+ int n, ret;
+
+ n = strlen(str);
+ ret = slg_write(bp, str, n);
+ return ret;
+}
+
+# if defined(OPENSSL_SYS_WIN32)
+
+static void xopenlog(BIO *bp, char *name, int level)
+{
+ if (check_winnt())
+ bp->ptr = RegisterEventSourceA(NULL, name);
+ else
+ bp->ptr = NULL;
+}
+
+static void xsyslog(BIO *bp, int priority, const char *string)
+{
+ LPCSTR lpszStrings[2];
+ WORD evtype = EVENTLOG_ERROR_TYPE;
+ char pidbuf[DECIMAL_SIZE(DWORD) + 4];
+
+ if (bp->ptr == NULL)
+ return;
+
+ switch (priority) {
+ case LOG_EMERG:
+ case LOG_ALERT:
+ case LOG_CRIT:
+ case LOG_ERR:
+ evtype = EVENTLOG_ERROR_TYPE;
+ break;
+ case LOG_WARNING:
+ evtype = EVENTLOG_WARNING_TYPE;
+ break;
+ case LOG_NOTICE:
+ case LOG_INFO:
+ case LOG_DEBUG:
+ evtype = EVENTLOG_INFORMATION_TYPE;
+ break;
+ default:
+ /*
+ * Should never happen, but set it
+ * as error anyway.
+ */
+ evtype = EVENTLOG_ERROR_TYPE;
+ break;
+ }
+
+ sprintf(pidbuf, "[%lu] ", GetCurrentProcessId());
+ lpszStrings[0] = pidbuf;
+ lpszStrings[1] = string;
+
+ ReportEventA(bp->ptr, evtype, 0, 1024, NULL, 2, 0, lpszStrings, NULL);
+}
+
+static void xcloselog(BIO *bp)
+{
+ if (bp->ptr)
+ DeregisterEventSource((HANDLE) (bp->ptr));
+ bp->ptr = NULL;
+}
+
+# elif defined(OPENSSL_SYS_VMS)
+
+static int VMS_OPC_target = LOG_DAEMON;
+
+static void xopenlog(BIO *bp, char *name, int level)
+{
+ VMS_OPC_target = level;
+}
+
+static void xsyslog(BIO *bp, int priority, const char *string)
+{
+ struct dsc$descriptor_s opc_dsc;
+
+/* Arrange 32-bit pointer to opcdef buffer and malloc(), if needed. */
+# if __INITIAL_POINTER_SIZE == 64
+# pragma pointer_size save
+# pragma pointer_size 32
+# define OPCDEF_TYPE __char_ptr32
+# define OPCDEF_MALLOC _malloc32
+# else /* __INITIAL_POINTER_SIZE == 64 */
+# define OPCDEF_TYPE char *
+# define OPCDEF_MALLOC OPENSSL_malloc
+# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+ struct opcdef *opcdef_p;
+
+# if __INITIAL_POINTER_SIZE == 64
+# pragma pointer_size restore
+# endif /* __INITIAL_POINTER_SIZE == 64 */
+
+ char buf[10240];
+ unsigned int len;
+ struct dsc$descriptor_s buf_dsc;
+ $DESCRIPTOR(fao_cmd, "!AZ: !AZ");
+ char *priority_tag;
+
+ switch (priority) {
+ case LOG_EMERG:
+ priority_tag = "Emergency";
+ break;
+ case LOG_ALERT:
+ priority_tag = "Alert";
+ break;
+ case LOG_CRIT:
+ priority_tag = "Critical";
+ break;
+ case LOG_ERR:
+ priority_tag = "Error";
+ break;
+ case LOG_WARNING:
+ priority_tag = "Warning";
+ break;
+ case LOG_NOTICE:
+ priority_tag = "Notice";
+ break;
+ case LOG_INFO:
+ priority_tag = "Info";
+ break;
+ case LOG_DEBUG:
+ priority_tag = "DEBUG";
+ break;
+ }
+
+ buf_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ buf_dsc.dsc$b_class = DSC$K_CLASS_S;
+ buf_dsc.dsc$a_pointer = buf;
+ buf_dsc.dsc$w_length = sizeof(buf) - 1;
+
+ lib$sys_fao(&fao_cmd, &len, &buf_dsc, priority_tag, string);
+
+ /* We know there's an 8-byte header. That's documented. */
+ opcdef_p = OPCDEF_MALLOC(8 + len);
+ opcdef_p->opc$b_ms_type = OPC$_RQ_RQST;
+ memcpy(opcdef_p->opc$z_ms_target_classes, &VMS_OPC_target, 3);
+ opcdef_p->opc$l_ms_rqstid = 0;
+ memcpy(&opcdef_p->opc$l_ms_text, buf, len);
+
+ opc_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ opc_dsc.dsc$b_class = DSC$K_CLASS_S;
+ opc_dsc.dsc$a_pointer = (OPCDEF_TYPE) opcdef_p;
+ opc_dsc.dsc$w_length = len + 8;
+
+ sys$sndopr(opc_dsc, 0);
+
+ OPENSSL_free(opcdef_p);
+}
+
+static void xcloselog(BIO *bp)
+{
+}
+
+# else /* Unix/Watt32 */
+
+static void xopenlog(BIO *bp, char *name, int level)
+{
+# ifdef WATT32 /* djgpp/DOS */
+ openlog(name, LOG_PID | LOG_CONS | LOG_NDELAY, level);
+# else
+ openlog(name, LOG_PID | LOG_CONS, level);
+# endif
+}
+
+static void xsyslog(BIO *bp, int priority, const char *string)
+{
+ syslog(priority, "%s", string);
+}
+
+static void xcloselog(BIO *bp)
+{
+ closelog();
+}
+
+# endif /* Unix */
+
+#else /* NO_SYSLOG */
+const BIO_METHOD *BIO_s_log(void)
+{
+ return NULL;
+}
+#endif /* NO_SYSLOG */
diff --git a/contrib/libs/openssl/crypto/bio/bss_mem.c b/contrib/libs/openssl/crypto/bio/bss_mem.c
index 16bec42fd1..7cb4a57813 100644
--- a/contrib/libs/openssl/crypto/bio/bss_mem.c
+++ b/contrib/libs/openssl/crypto/bio/bss_mem.c
@@ -1,372 +1,372 @@
-/*
- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include <errno.h>
+/*
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <errno.h>
#include "bio_local.h"
-#include "internal/cryptlib.h"
-
-static int mem_write(BIO *h, const char *buf, int num);
-static int mem_read(BIO *h, char *buf, int size);
-static int mem_puts(BIO *h, const char *str);
-static int mem_gets(BIO *h, char *str, int size);
-static long mem_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-static int mem_new(BIO *h);
-static int secmem_new(BIO *h);
-static int mem_free(BIO *data);
-static int mem_buf_free(BIO *data);
-static int mem_buf_sync(BIO *h);
-
-static const BIO_METHOD mem_method = {
- BIO_TYPE_MEM,
- "memory buffer",
- /* TODO: Convert to new style write function */
- bwrite_conv,
- mem_write,
- /* TODO: Convert to new style read function */
- bread_conv,
- mem_read,
- mem_puts,
- mem_gets,
- mem_ctrl,
- mem_new,
- mem_free,
- NULL, /* mem_callback_ctrl */
-};
-
-static const BIO_METHOD secmem_method = {
- BIO_TYPE_MEM,
- "secure memory buffer",
- /* TODO: Convert to new style write function */
- bwrite_conv,
- mem_write,
- /* TODO: Convert to new style read function */
- bread_conv,
- mem_read,
- mem_puts,
- mem_gets,
- mem_ctrl,
- secmem_new,
- mem_free,
- NULL, /* mem_callback_ctrl */
-};
-
+#include "internal/cryptlib.h"
+
+static int mem_write(BIO *h, const char *buf, int num);
+static int mem_read(BIO *h, char *buf, int size);
+static int mem_puts(BIO *h, const char *str);
+static int mem_gets(BIO *h, char *str, int size);
+static long mem_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int mem_new(BIO *h);
+static int secmem_new(BIO *h);
+static int mem_free(BIO *data);
+static int mem_buf_free(BIO *data);
+static int mem_buf_sync(BIO *h);
+
+static const BIO_METHOD mem_method = {
+ BIO_TYPE_MEM,
+ "memory buffer",
+ /* TODO: Convert to new style write function */
+ bwrite_conv,
+ mem_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
+ mem_read,
+ mem_puts,
+ mem_gets,
+ mem_ctrl,
+ mem_new,
+ mem_free,
+ NULL, /* mem_callback_ctrl */
+};
+
+static const BIO_METHOD secmem_method = {
+ BIO_TYPE_MEM,
+ "secure memory buffer",
+ /* TODO: Convert to new style write function */
+ bwrite_conv,
+ mem_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
+ mem_read,
+ mem_puts,
+ mem_gets,
+ mem_ctrl,
+ secmem_new,
+ mem_free,
+ NULL, /* mem_callback_ctrl */
+};
+
/*
* BIO memory stores buffer and read pointer
* however the roles are different for read only BIOs.
* In that case the readp just stores the original state
* to be used for reset.
*/
-typedef struct bio_buf_mem_st {
- struct buf_mem_st *buf; /* allocated buffer */
- struct buf_mem_st *readp; /* read pointer */
-} BIO_BUF_MEM;
-
-/*
- * bio->num is used to hold the value to return on 'empty', if it is 0,
- * should_retry is not set
- */
-
-const BIO_METHOD *BIO_s_mem(void)
-{
- return &mem_method;
-}
-
-const BIO_METHOD *BIO_s_secmem(void)
-{
- return(&secmem_method);
-}
-
-BIO *BIO_new_mem_buf(const void *buf, int len)
-{
- BIO *ret;
- BUF_MEM *b;
- BIO_BUF_MEM *bb;
- size_t sz;
-
- if (buf == NULL) {
- BIOerr(BIO_F_BIO_NEW_MEM_BUF, BIO_R_NULL_PARAMETER);
- return NULL;
- }
- sz = (len < 0) ? strlen(buf) : (size_t)len;
- if ((ret = BIO_new(BIO_s_mem())) == NULL)
- return NULL;
- bb = (BIO_BUF_MEM *)ret->ptr;
- b = bb->buf;
- /* Cast away const and trust in the MEM_RDONLY flag. */
- b->data = (void *)buf;
- b->length = sz;
- b->max = sz;
- *bb->readp = *bb->buf;
- ret->flags |= BIO_FLAGS_MEM_RDONLY;
- /* Since this is static data retrying won't help */
- ret->num = 0;
- return ret;
-}
-
-static int mem_init(BIO *bi, unsigned long flags)
-{
- BIO_BUF_MEM *bb = OPENSSL_zalloc(sizeof(*bb));
-
- if (bb == NULL)
- return 0;
- if ((bb->buf = BUF_MEM_new_ex(flags)) == NULL) {
- OPENSSL_free(bb);
- return 0;
- }
- if ((bb->readp = OPENSSL_zalloc(sizeof(*bb->readp))) == NULL) {
- BUF_MEM_free(bb->buf);
- OPENSSL_free(bb);
- return 0;
- }
- *bb->readp = *bb->buf;
- bi->shutdown = 1;
- bi->init = 1;
- bi->num = -1;
- bi->ptr = (char *)bb;
- return 1;
-}
-
-static int mem_new(BIO *bi)
-{
- return mem_init(bi, 0L);
-}
-
-static int secmem_new(BIO *bi)
-{
- return mem_init(bi, BUF_MEM_FLAG_SECURE);
-}
-
-static int mem_free(BIO *a)
-{
- BIO_BUF_MEM *bb;
-
- if (a == NULL)
- return 0;
-
- bb = (BIO_BUF_MEM *)a->ptr;
- if (!mem_buf_free(a))
- return 0;
- OPENSSL_free(bb->readp);
- OPENSSL_free(bb);
- return 1;
-}
-
-static int mem_buf_free(BIO *a)
-{
- if (a == NULL)
- return 0;
-
- if (a->shutdown && a->init && a->ptr != NULL) {
- BIO_BUF_MEM *bb = (BIO_BUF_MEM *)a->ptr;
- BUF_MEM *b = bb->buf;
-
- if (a->flags & BIO_FLAGS_MEM_RDONLY)
- b->data = NULL;
- BUF_MEM_free(b);
- }
- return 1;
-}
-
-/*
- * Reallocate memory buffer if read pointer differs
- */
-static int mem_buf_sync(BIO *b)
-{
- if (b != NULL && b->init != 0 && b->ptr != NULL) {
- BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
-
- if (bbm->readp->data != bbm->buf->data) {
- memmove(bbm->buf->data, bbm->readp->data, bbm->readp->length);
- bbm->buf->length = bbm->readp->length;
- bbm->readp->data = bbm->buf->data;
- }
- }
- return 0;
-}
-
-static int mem_read(BIO *b, char *out, int outl)
-{
- int ret = -1;
- BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
- BUF_MEM *bm = bbm->readp;
-
+typedef struct bio_buf_mem_st {
+ struct buf_mem_st *buf; /* allocated buffer */
+ struct buf_mem_st *readp; /* read pointer */
+} BIO_BUF_MEM;
+
+/*
+ * bio->num is used to hold the value to return on 'empty', if it is 0,
+ * should_retry is not set
+ */
+
+const BIO_METHOD *BIO_s_mem(void)
+{
+ return &mem_method;
+}
+
+const BIO_METHOD *BIO_s_secmem(void)
+{
+ return(&secmem_method);
+}
+
+BIO *BIO_new_mem_buf(const void *buf, int len)
+{
+ BIO *ret;
+ BUF_MEM *b;
+ BIO_BUF_MEM *bb;
+ size_t sz;
+
+ if (buf == NULL) {
+ BIOerr(BIO_F_BIO_NEW_MEM_BUF, BIO_R_NULL_PARAMETER);
+ return NULL;
+ }
+ sz = (len < 0) ? strlen(buf) : (size_t)len;
+ if ((ret = BIO_new(BIO_s_mem())) == NULL)
+ return NULL;
+ bb = (BIO_BUF_MEM *)ret->ptr;
+ b = bb->buf;
+ /* Cast away const and trust in the MEM_RDONLY flag. */
+ b->data = (void *)buf;
+ b->length = sz;
+ b->max = sz;
+ *bb->readp = *bb->buf;
+ ret->flags |= BIO_FLAGS_MEM_RDONLY;
+ /* Since this is static data retrying won't help */
+ ret->num = 0;
+ return ret;
+}
+
+static int mem_init(BIO *bi, unsigned long flags)
+{
+ BIO_BUF_MEM *bb = OPENSSL_zalloc(sizeof(*bb));
+
+ if (bb == NULL)
+ return 0;
+ if ((bb->buf = BUF_MEM_new_ex(flags)) == NULL) {
+ OPENSSL_free(bb);
+ return 0;
+ }
+ if ((bb->readp = OPENSSL_zalloc(sizeof(*bb->readp))) == NULL) {
+ BUF_MEM_free(bb->buf);
+ OPENSSL_free(bb);
+ return 0;
+ }
+ *bb->readp = *bb->buf;
+ bi->shutdown = 1;
+ bi->init = 1;
+ bi->num = -1;
+ bi->ptr = (char *)bb;
+ return 1;
+}
+
+static int mem_new(BIO *bi)
+{
+ return mem_init(bi, 0L);
+}
+
+static int secmem_new(BIO *bi)
+{
+ return mem_init(bi, BUF_MEM_FLAG_SECURE);
+}
+
+static int mem_free(BIO *a)
+{
+ BIO_BUF_MEM *bb;
+
+ if (a == NULL)
+ return 0;
+
+ bb = (BIO_BUF_MEM *)a->ptr;
+ if (!mem_buf_free(a))
+ return 0;
+ OPENSSL_free(bb->readp);
+ OPENSSL_free(bb);
+ return 1;
+}
+
+static int mem_buf_free(BIO *a)
+{
+ if (a == NULL)
+ return 0;
+
+ if (a->shutdown && a->init && a->ptr != NULL) {
+ BIO_BUF_MEM *bb = (BIO_BUF_MEM *)a->ptr;
+ BUF_MEM *b = bb->buf;
+
+ if (a->flags & BIO_FLAGS_MEM_RDONLY)
+ b->data = NULL;
+ BUF_MEM_free(b);
+ }
+ return 1;
+}
+
+/*
+ * Reallocate memory buffer if read pointer differs
+ */
+static int mem_buf_sync(BIO *b)
+{
+ if (b != NULL && b->init != 0 && b->ptr != NULL) {
+ BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
+
+ if (bbm->readp->data != bbm->buf->data) {
+ memmove(bbm->buf->data, bbm->readp->data, bbm->readp->length);
+ bbm->buf->length = bbm->readp->length;
+ bbm->readp->data = bbm->buf->data;
+ }
+ }
+ return 0;
+}
+
+static int mem_read(BIO *b, char *out, int outl)
+{
+ int ret = -1;
+ BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
+ BUF_MEM *bm = bbm->readp;
+
if (b->flags & BIO_FLAGS_MEM_RDONLY)
bm = bbm->buf;
- BIO_clear_retry_flags(b);
- ret = (outl >= 0 && (size_t)outl > bm->length) ? (int)bm->length : outl;
- if ((out != NULL) && (ret > 0)) {
- memcpy(out, bm->data, ret);
- bm->length -= ret;
+ BIO_clear_retry_flags(b);
+ ret = (outl >= 0 && (size_t)outl > bm->length) ? (int)bm->length : outl;
+ if ((out != NULL) && (ret > 0)) {
+ memcpy(out, bm->data, ret);
+ bm->length -= ret;
bm->max -= ret;
- bm->data += ret;
- } else if (bm->length == 0) {
- ret = b->num;
- if (ret != 0)
- BIO_set_retry_read(b);
- }
- return ret;
-}
-
-static int mem_write(BIO *b, const char *in, int inl)
-{
- int ret = -1;
- int blen;
- BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
-
- if (in == NULL) {
- BIOerr(BIO_F_MEM_WRITE, BIO_R_NULL_PARAMETER);
- goto end;
- }
- if (b->flags & BIO_FLAGS_MEM_RDONLY) {
- BIOerr(BIO_F_MEM_WRITE, BIO_R_WRITE_TO_READ_ONLY_BIO);
- goto end;
- }
- BIO_clear_retry_flags(b);
- if (inl == 0)
- return 0;
- blen = bbm->readp->length;
- mem_buf_sync(b);
- if (BUF_MEM_grow_clean(bbm->buf, blen + inl) == 0)
- goto end;
- memcpy(bbm->buf->data + blen, in, inl);
- *bbm->readp = *bbm->buf;
- ret = inl;
- end:
- return ret;
-}
-
-static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
-{
- long ret = 1;
- char **pptr;
- BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
- BUF_MEM *bm;
-
+ bm->data += ret;
+ } else if (bm->length == 0) {
+ ret = b->num;
+ if (ret != 0)
+ BIO_set_retry_read(b);
+ }
+ return ret;
+}
+
+static int mem_write(BIO *b, const char *in, int inl)
+{
+ int ret = -1;
+ int blen;
+ BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
+
+ if (in == NULL) {
+ BIOerr(BIO_F_MEM_WRITE, BIO_R_NULL_PARAMETER);
+ goto end;
+ }
+ if (b->flags & BIO_FLAGS_MEM_RDONLY) {
+ BIOerr(BIO_F_MEM_WRITE, BIO_R_WRITE_TO_READ_ONLY_BIO);
+ goto end;
+ }
+ BIO_clear_retry_flags(b);
+ if (inl == 0)
+ return 0;
+ blen = bbm->readp->length;
+ mem_buf_sync(b);
+ if (BUF_MEM_grow_clean(bbm->buf, blen + inl) == 0)
+ goto end;
+ memcpy(bbm->buf->data + blen, in, inl);
+ *bbm->readp = *bbm->buf;
+ ret = inl;
+ end:
+ return ret;
+}
+
+static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ long ret = 1;
+ char **pptr;
+ BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
+ BUF_MEM *bm;
+
if (b->flags & BIO_FLAGS_MEM_RDONLY)
bm = bbm->buf;
else
bm = bbm->readp;
- switch (cmd) {
- case BIO_CTRL_RESET:
- bm = bbm->buf;
- if (bm->data != NULL) {
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ bm = bbm->buf;
+ if (bm->data != NULL) {
if (!(b->flags & BIO_FLAGS_MEM_RDONLY)) {
if (!(b->flags & BIO_FLAGS_NONCLEAR_RST)) {
memset(bm->data, 0, bm->max);
bm->length = 0;
}
*bbm->readp = *bbm->buf;
- } else {
+ } else {
/* For read only case just reset to the start again */
*bbm->buf = *bbm->readp;
- }
- }
- break;
- case BIO_CTRL_EOF:
- ret = (long)(bm->length == 0);
- break;
- case BIO_C_SET_BUF_MEM_EOF_RETURN:
- b->num = (int)num;
- break;
- case BIO_CTRL_INFO:
- ret = (long)bm->length;
- if (ptr != NULL) {
- pptr = (char **)ptr;
- *pptr = (char *)&(bm->data[0]);
- }
- break;
- case BIO_C_SET_BUF_MEM:
- mem_buf_free(b);
- b->shutdown = (int)num;
- bbm->buf = ptr;
- *bbm->readp = *bbm->buf;
- break;
- case BIO_C_GET_BUF_MEM_PTR:
- if (ptr != NULL) {
+ }
+ }
+ break;
+ case BIO_CTRL_EOF:
+ ret = (long)(bm->length == 0);
+ break;
+ case BIO_C_SET_BUF_MEM_EOF_RETURN:
+ b->num = (int)num;
+ break;
+ case BIO_CTRL_INFO:
+ ret = (long)bm->length;
+ if (ptr != NULL) {
+ pptr = (char **)ptr;
+ *pptr = (char *)&(bm->data[0]);
+ }
+ break;
+ case BIO_C_SET_BUF_MEM:
+ mem_buf_free(b);
+ b->shutdown = (int)num;
+ bbm->buf = ptr;
+ *bbm->readp = *bbm->buf;
+ break;
+ case BIO_C_GET_BUF_MEM_PTR:
+ if (ptr != NULL) {
if (!(b->flags & BIO_FLAGS_MEM_RDONLY))
mem_buf_sync(b);
bm = bbm->buf;
- pptr = (char **)ptr;
- *pptr = (char *)bm;
- }
- break;
- case BIO_CTRL_GET_CLOSE:
- ret = (long)b->shutdown;
- break;
- case BIO_CTRL_SET_CLOSE:
- b->shutdown = (int)num;
- break;
- case BIO_CTRL_WPENDING:
- ret = 0L;
- break;
- case BIO_CTRL_PENDING:
- ret = (long)bm->length;
- break;
- case BIO_CTRL_DUP:
- case BIO_CTRL_FLUSH:
- ret = 1;
- break;
- case BIO_CTRL_PUSH:
- case BIO_CTRL_POP:
- default:
- ret = 0;
- break;
- }
- return ret;
-}
-
-static int mem_gets(BIO *bp, char *buf, int size)
-{
- int i, j;
- int ret = -1;
- char *p;
- BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)bp->ptr;
- BUF_MEM *bm = bbm->readp;
-
+ pptr = (char **)ptr;
+ *pptr = (char *)bm;
+ }
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret = (long)b->shutdown;
+ break;
+ case BIO_CTRL_SET_CLOSE:
+ b->shutdown = (int)num;
+ break;
+ case BIO_CTRL_WPENDING:
+ ret = 0L;
+ break;
+ case BIO_CTRL_PENDING:
+ ret = (long)bm->length;
+ break;
+ case BIO_CTRL_DUP:
+ case BIO_CTRL_FLUSH:
+ ret = 1;
+ break;
+ case BIO_CTRL_PUSH:
+ case BIO_CTRL_POP:
+ default:
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+static int mem_gets(BIO *bp, char *buf, int size)
+{
+ int i, j;
+ int ret = -1;
+ char *p;
+ BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)bp->ptr;
+ BUF_MEM *bm = bbm->readp;
+
if (bp->flags & BIO_FLAGS_MEM_RDONLY)
bm = bbm->buf;
- BIO_clear_retry_flags(bp);
- j = bm->length;
- if ((size - 1) < j)
- j = size - 1;
- if (j <= 0) {
- *buf = '\0';
- return 0;
- }
- p = bm->data;
- for (i = 0; i < j; i++) {
- if (p[i] == '\n') {
- i++;
- break;
- }
- }
-
- /*
- * i is now the max num of bytes to copy, either j or up to
- * and including the first newline
- */
-
- i = mem_read(bp, buf, i);
- if (i > 0)
- buf[i] = '\0';
- ret = i;
- return ret;
-}
-
-static int mem_puts(BIO *bp, const char *str)
-{
- int n, ret;
-
- n = strlen(str);
- ret = mem_write(bp, str, n);
- /* memory semantics is that it will always work */
- return ret;
-}
+ BIO_clear_retry_flags(bp);
+ j = bm->length;
+ if ((size - 1) < j)
+ j = size - 1;
+ if (j <= 0) {
+ *buf = '\0';
+ return 0;
+ }
+ p = bm->data;
+ for (i = 0; i < j; i++) {
+ if (p[i] == '\n') {
+ i++;
+ break;
+ }
+ }
+
+ /*
+ * i is now the max num of bytes to copy, either j or up to
+ * and including the first newline
+ */
+
+ i = mem_read(bp, buf, i);
+ if (i > 0)
+ buf[i] = '\0';
+ ret = i;
+ return ret;
+}
+
+static int mem_puts(BIO *bp, const char *str)
+{
+ int n, ret;
+
+ n = strlen(str);
+ ret = mem_write(bp, str, n);
+ /* memory semantics is that it will always work */
+ return ret;
+}
diff --git a/contrib/libs/openssl/crypto/bio/bss_null.c b/contrib/libs/openssl/crypto/bio/bss_null.c
index 4ebff60e20..e73ce7841d 100644
--- a/contrib/libs/openssl/crypto/bio/bss_null.c
+++ b/contrib/libs/openssl/crypto/bio/bss_null.c
@@ -1,87 +1,87 @@
-/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include <errno.h>
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <errno.h>
#include "bio_local.h"
-#include "internal/cryptlib.h"
-
-static int null_write(BIO *h, const char *buf, int num);
-static int null_read(BIO *h, char *buf, int size);
-static int null_puts(BIO *h, const char *str);
-static int null_gets(BIO *h, char *str, int size);
-static long null_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-static const BIO_METHOD null_method = {
- BIO_TYPE_NULL,
- "NULL",
- /* TODO: Convert to new style write function */
- bwrite_conv,
- null_write,
- /* TODO: Convert to new style read function */
- bread_conv,
- null_read,
- null_puts,
- null_gets,
- null_ctrl,
- NULL,
- NULL,
- NULL, /* null_callback_ctrl */
-};
-
-const BIO_METHOD *BIO_s_null(void)
-{
- return &null_method;
-}
-
-static int null_read(BIO *b, char *out, int outl)
-{
- return 0;
-}
-
-static int null_write(BIO *b, const char *in, int inl)
-{
- return inl;
-}
-
-static long null_ctrl(BIO *b, int cmd, long num, void *ptr)
-{
- long ret = 1;
-
- switch (cmd) {
- case BIO_CTRL_RESET:
- case BIO_CTRL_EOF:
- case BIO_CTRL_SET:
- case BIO_CTRL_SET_CLOSE:
- case BIO_CTRL_FLUSH:
- case BIO_CTRL_DUP:
- ret = 1;
- break;
- case BIO_CTRL_GET_CLOSE:
- case BIO_CTRL_INFO:
- case BIO_CTRL_GET:
- case BIO_CTRL_PENDING:
- case BIO_CTRL_WPENDING:
- default:
- ret = 0;
- break;
- }
- return ret;
-}
-
-static int null_gets(BIO *bp, char *buf, int size)
-{
- return 0;
-}
-
-static int null_puts(BIO *bp, const char *str)
-{
- if (str == NULL)
- return 0;
- return strlen(str);
-}
+#include "internal/cryptlib.h"
+
+static int null_write(BIO *h, const char *buf, int num);
+static int null_read(BIO *h, char *buf, int size);
+static int null_puts(BIO *h, const char *str);
+static int null_gets(BIO *h, char *str, int size);
+static long null_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static const BIO_METHOD null_method = {
+ BIO_TYPE_NULL,
+ "NULL",
+ /* TODO: Convert to new style write function */
+ bwrite_conv,
+ null_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
+ null_read,
+ null_puts,
+ null_gets,
+ null_ctrl,
+ NULL,
+ NULL,
+ NULL, /* null_callback_ctrl */
+};
+
+const BIO_METHOD *BIO_s_null(void)
+{
+ return &null_method;
+}
+
+static int null_read(BIO *b, char *out, int outl)
+{
+ return 0;
+}
+
+static int null_write(BIO *b, const char *in, int inl)
+{
+ return inl;
+}
+
+static long null_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ long ret = 1;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ case BIO_CTRL_EOF:
+ case BIO_CTRL_SET:
+ case BIO_CTRL_SET_CLOSE:
+ case BIO_CTRL_FLUSH:
+ case BIO_CTRL_DUP:
+ ret = 1;
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ case BIO_CTRL_INFO:
+ case BIO_CTRL_GET:
+ case BIO_CTRL_PENDING:
+ case BIO_CTRL_WPENDING:
+ default:
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+static int null_gets(BIO *bp, char *buf, int size)
+{
+ return 0;
+}
+
+static int null_puts(BIO *bp, const char *str)
+{
+ if (str == NULL)
+ return 0;
+ return strlen(str);
+}
diff --git a/contrib/libs/openssl/crypto/bio/bss_sock.c b/contrib/libs/openssl/crypto/bio/bss_sock.c
index 63ede6bbf7..6251f3d46a 100644
--- a/contrib/libs/openssl/crypto/bio/bss_sock.c
+++ b/contrib/libs/openssl/crypto/bio/bss_sock.c
@@ -1,238 +1,238 @@
-/*
+/*
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include <errno.h>
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <errno.h>
#include "bio_local.h"
-#include "internal/cryptlib.h"
-
-#ifndef OPENSSL_NO_SOCK
-
-# include <openssl/bio.h>
-
-# ifdef WATT32
-/* Watt-32 uses same names */
-# undef sock_write
-# undef sock_read
-# undef sock_puts
-# define sock_write SockWrite
-# define sock_read SockRead
-# define sock_puts SockPuts
-# endif
-
-static int sock_write(BIO *h, const char *buf, int num);
-static int sock_read(BIO *h, char *buf, int size);
-static int sock_puts(BIO *h, const char *str);
-static long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-static int sock_new(BIO *h);
-static int sock_free(BIO *data);
-int BIO_sock_should_retry(int s);
-
-static const BIO_METHOD methods_sockp = {
- BIO_TYPE_SOCKET,
- "socket",
- /* TODO: Convert to new style write function */
- bwrite_conv,
- sock_write,
- /* TODO: Convert to new style read function */
- bread_conv,
- sock_read,
- sock_puts,
- NULL, /* sock_gets, */
- sock_ctrl,
- sock_new,
- sock_free,
- NULL, /* sock_callback_ctrl */
-};
-
-const BIO_METHOD *BIO_s_socket(void)
-{
- return &methods_sockp;
-}
-
-BIO *BIO_new_socket(int fd, int close_flag)
-{
- BIO *ret;
-
- ret = BIO_new(BIO_s_socket());
- if (ret == NULL)
- return NULL;
- BIO_set_fd(ret, fd, close_flag);
- return ret;
-}
-
-static int sock_new(BIO *bi)
-{
- bi->init = 0;
- bi->num = 0;
- bi->ptr = NULL;
- bi->flags = 0;
- return 1;
-}
-
-static int sock_free(BIO *a)
-{
- if (a == NULL)
- return 0;
- if (a->shutdown) {
- if (a->init) {
- BIO_closesocket(a->num);
- }
- a->init = 0;
- a->flags = 0;
- }
- return 1;
-}
-
-static int sock_read(BIO *b, char *out, int outl)
-{
- int ret = 0;
-
- if (out != NULL) {
- clear_socket_error();
- ret = readsocket(b->num, out, outl);
- BIO_clear_retry_flags(b);
- if (ret <= 0) {
- if (BIO_sock_should_retry(ret))
- BIO_set_retry_read(b);
+#include "internal/cryptlib.h"
+
+#ifndef OPENSSL_NO_SOCK
+
+# include <openssl/bio.h>
+
+# ifdef WATT32
+/* Watt-32 uses same names */
+# undef sock_write
+# undef sock_read
+# undef sock_puts
+# define sock_write SockWrite
+# define sock_read SockRead
+# define sock_puts SockPuts
+# endif
+
+static int sock_write(BIO *h, const char *buf, int num);
+static int sock_read(BIO *h, char *buf, int size);
+static int sock_puts(BIO *h, const char *str);
+static long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int sock_new(BIO *h);
+static int sock_free(BIO *data);
+int BIO_sock_should_retry(int s);
+
+static const BIO_METHOD methods_sockp = {
+ BIO_TYPE_SOCKET,
+ "socket",
+ /* TODO: Convert to new style write function */
+ bwrite_conv,
+ sock_write,
+ /* TODO: Convert to new style read function */
+ bread_conv,
+ sock_read,
+ sock_puts,
+ NULL, /* sock_gets, */
+ sock_ctrl,
+ sock_new,
+ sock_free,
+ NULL, /* sock_callback_ctrl */
+};
+
+const BIO_METHOD *BIO_s_socket(void)
+{
+ return &methods_sockp;
+}
+
+BIO *BIO_new_socket(int fd, int close_flag)
+{
+ BIO *ret;
+
+ ret = BIO_new(BIO_s_socket());
+ if (ret == NULL)
+ return NULL;
+ BIO_set_fd(ret, fd, close_flag);
+ return ret;
+}
+
+static int sock_new(BIO *bi)
+{
+ bi->init = 0;
+ bi->num = 0;
+ bi->ptr = NULL;
+ bi->flags = 0;
+ return 1;
+}
+
+static int sock_free(BIO *a)
+{
+ if (a == NULL)
+ return 0;
+ if (a->shutdown) {
+ if (a->init) {
+ BIO_closesocket(a->num);
+ }
+ a->init = 0;
+ a->flags = 0;
+ }
+ return 1;
+}
+
+static int sock_read(BIO *b, char *out, int outl)
+{
+ int ret = 0;
+
+ if (out != NULL) {
+ clear_socket_error();
+ ret = readsocket(b->num, out, outl);
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_sock_should_retry(ret))
+ BIO_set_retry_read(b);
else if (ret == 0)
b->flags |= BIO_FLAGS_IN_EOF;
- }
- }
- return ret;
-}
-
-static int sock_write(BIO *b, const char *in, int inl)
-{
- int ret;
-
- clear_socket_error();
- ret = writesocket(b->num, in, inl);
- BIO_clear_retry_flags(b);
- if (ret <= 0) {
- if (BIO_sock_should_retry(ret))
- BIO_set_retry_write(b);
- }
- return ret;
-}
-
-static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
-{
- long ret = 1;
- int *ip;
-
- switch (cmd) {
- case BIO_C_SET_FD:
- sock_free(b);
- b->num = *((int *)ptr);
- b->shutdown = (int)num;
- b->init = 1;
- break;
- case BIO_C_GET_FD:
- if (b->init) {
- ip = (int *)ptr;
- if (ip != NULL)
- *ip = b->num;
- ret = b->num;
- } else
- ret = -1;
- break;
- case BIO_CTRL_GET_CLOSE:
- ret = b->shutdown;
- break;
- case BIO_CTRL_SET_CLOSE:
- b->shutdown = (int)num;
- break;
- case BIO_CTRL_DUP:
- case BIO_CTRL_FLUSH:
- ret = 1;
- break;
+ }
+ }
+ return ret;
+}
+
+static int sock_write(BIO *b, const char *in, int inl)
+{
+ int ret;
+
+ clear_socket_error();
+ ret = writesocket(b->num, in, inl);
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_sock_should_retry(ret))
+ BIO_set_retry_write(b);
+ }
+ return ret;
+}
+
+static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ long ret = 1;
+ int *ip;
+
+ switch (cmd) {
+ case BIO_C_SET_FD:
+ sock_free(b);
+ b->num = *((int *)ptr);
+ b->shutdown = (int)num;
+ b->init = 1;
+ break;
+ case BIO_C_GET_FD:
+ if (b->init) {
+ ip = (int *)ptr;
+ if (ip != NULL)
+ *ip = b->num;
+ ret = b->num;
+ } else
+ ret = -1;
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret = b->shutdown;
+ break;
+ case BIO_CTRL_SET_CLOSE:
+ b->shutdown = (int)num;
+ break;
+ case BIO_CTRL_DUP:
+ case BIO_CTRL_FLUSH:
+ ret = 1;
+ break;
case BIO_CTRL_EOF:
ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0;
break;
- default:
- ret = 0;
- break;
- }
- return ret;
-}
-
-static int sock_puts(BIO *bp, const char *str)
-{
- int n, ret;
-
- n = strlen(str);
- ret = sock_write(bp, str, n);
- return ret;
-}
-
-int BIO_sock_should_retry(int i)
-{
- int err;
-
- if ((i == 0) || (i == -1)) {
- err = get_last_socket_error();
-
- return BIO_sock_non_fatal_error(err);
- }
- return 0;
-}
-
-int BIO_sock_non_fatal_error(int err)
-{
- switch (err) {
-# if defined(OPENSSL_SYS_WINDOWS)
-# if defined(WSAEWOULDBLOCK)
- case WSAEWOULDBLOCK:
-# endif
-# endif
-
-# ifdef EWOULDBLOCK
-# ifdef WSAEWOULDBLOCK
-# if WSAEWOULDBLOCK != EWOULDBLOCK
- case EWOULDBLOCK:
-# endif
-# else
- case EWOULDBLOCK:
-# endif
-# endif
-
-# if defined(ENOTCONN)
- case ENOTCONN:
-# endif
-
-# ifdef EINTR
- case EINTR:
-# endif
-
-# ifdef EAGAIN
-# if EWOULDBLOCK != EAGAIN
- case EAGAIN:
-# endif
-# endif
-
-# ifdef EPROTO
- case EPROTO:
-# endif
-
-# ifdef EINPROGRESS
- case EINPROGRESS:
-# endif
-
-# ifdef EALREADY
- case EALREADY:
-# endif
- return 1;
- default:
- break;
- }
- return 0;
-}
-
-#endif /* #ifndef OPENSSL_NO_SOCK */
+ default:
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+static int sock_puts(BIO *bp, const char *str)
+{
+ int n, ret;
+
+ n = strlen(str);
+ ret = sock_write(bp, str, n);
+ return ret;
+}
+
+int BIO_sock_should_retry(int i)
+{
+ int err;
+
+ if ((i == 0) || (i == -1)) {
+ err = get_last_socket_error();
+
+ return BIO_sock_non_fatal_error(err);
+ }
+ return 0;
+}
+
+int BIO_sock_non_fatal_error(int err)
+{
+ switch (err) {
+# if defined(OPENSSL_SYS_WINDOWS)
+# if defined(WSAEWOULDBLOCK)
+ case WSAEWOULDBLOCK:
+# endif
+# endif
+
+# ifdef EWOULDBLOCK
+# ifdef WSAEWOULDBLOCK
+# if WSAEWOULDBLOCK != EWOULDBLOCK
+ case EWOULDBLOCK:
+# endif
+# else
+ case EWOULDBLOCK:
+# endif
+# endif
+
+# if defined(ENOTCONN)
+ case ENOTCONN:
+# endif
+
+# ifdef EINTR
+ case EINTR:
+# endif
+
+# ifdef EAGAIN
+# if EWOULDBLOCK != EAGAIN
+ case EAGAIN:
+# endif
+# endif
+
+# ifdef EPROTO
+ case EPROTO:
+# endif
+
+# ifdef EINPROGRESS
+ case EINPROGRESS:
+# endif
+
+# ifdef EALREADY
+ case EALREADY:
+# endif
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+}
+
+#endif /* #ifndef OPENSSL_NO_SOCK */