/*
 * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (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 <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);
static int dgram_sctp_wait_for_dry(BIO *b);
static int dgram_sctp_msg_waiting(BIO *b);
#  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",
    bwrite_conv,
    dgram_write,
    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",
    bwrite_conv,
    dgram_sctp_write,
    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;
    BIO_dgram_sctp_notification_handler_fn handle_notifications;
    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);
        ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB,
                       "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);
        ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB,
                       "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);
        ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB,
                       "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) {
        ERR_raise(ERR_LIB_BIO, 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;
    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) {
                union sctp_notification snp;

                memcpy(&snp, out, sizeof(snp));
                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(&snp, 0, sizeof(snp));
                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) {
                ERR_raise(ERR_LIB_BIO, 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) {
                ERR_raise(ERR_LIB_BIO, 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;
    case BIO_CTRL_DGRAM_SCTP_WAIT_FOR_DRY:
        return dgram_sctp_wait_for_dry(b);
    case BIO_CTRL_DGRAM_SCTP_MSG_WAITING:
        return dgram_sctp_msg_waiting(b);

    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,
                BIO_dgram_sctp_notification_handler_fn handle_notifications,
                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)
{
    return (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SCTP_WAIT_FOR_DRY, 0, NULL);
}

static int 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)
{
    return (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SCTP_MSG_WAITING, 0, NULL);
}

static int 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
